From 4dc55afc975557a9bc9da3da51d9bd0bf98599cf Mon Sep 17 00:00:00 2001 From: Yuri Neves Date: Fri, 23 Oct 2026 13:45:48 -0300 Subject: [PATCH 01/11] Init Brazilian Portuguese translation --- ...okbook_configuring-webservers_apache.md.po | 96 ++ ...kbook_configuring-webservers_general.md.po | 100 ++ .../cookbook_configuring-webservers_iis.md.po | 66 + ...book_configuring-webservers_lighttpd.md.po | 42 + ...ok_configuring-webservers_nginx-unit.md.po | 103 ++ ...ookbook_configuring-webservers_nginx.md.po | 96 ++ .../pt-BR/cookbook_configuring-xdebug.md.po | 540 +++++++ ...ookbook_custom-hydrator-type-casters.md.po | 773 +++++++++ .../cookbook_custom-migration-template.md.po | 238 +++ ...okbook_deployment_angie-docker-proxy.md.po | 432 +++++ .../cookbook_deployment_autoscaling.md.po | 336 ++++ ...okbook_deployment_docker-swarm-caddy.md.po | 1102 +++++++++++++ ...book_deployment_docker-swarm-traefik.md.po | 1100 +++++++++++++ .../cookbook_deployment_docker-swarm.md.po | 32 + ...deployment_rolling-update-migrations.md.po | 490 ++++++ .../cookbook_disabling-csrf-protection.md.po | 310 ++++ _translations/po/pt-BR/cookbook_index.md.po | 147 ++ .../pt-BR/cookbook_making-http-requests.md.po | 295 ++++ .../cookbook_opening-files-in-phpstorm.md.po | 210 +++ .../cookbook_organizing-code_domain.md.po | 192 +++ .../cookbook_organizing-code_service.md.po | 196 +++ ...ing-by-use-case-with-vertical-slices.md.po | 119 ++ _translations/po/pt-BR/cookbook_preface.md.po | 80 + .../pt-BR/cookbook_sentry-integration.md.po | 250 +++ ...kbook_third-party-integrations_index.md.po | 52 + ..._symfony-messenger-integration-guide.md.po | 471 ++++++ ..._symfony-scheduler-integration-guide.md.po | 401 +++++ ...kbook_using-htmx-for-partial-reloads.md.po | 541 +++++++ ...okbook_using-yii-in-third-party-apps.md.po | 289 ++++ .../pt-BR/cookbook_working-on-windows.md.po | 160 ++ .../po/pt-BR/guide_caching_data.md.po | 335 ++++ .../po/pt-BR/guide_caching_overview.md.po | 57 + .../po/pt-BR/guide_concept_aliases.md.po | 274 ++++ .../po/pt-BR/guide_concept_autoloading.md.po | 76 + .../pt-BR/guide_concept_configuration.md.po | 681 ++++++++ .../po/pt-BR/guide_concept_di-container.md.po | 535 +++++++ .../po/pt-BR/guide_concept_events.md.po | 316 ++++ .../po/pt-BR/guide_concept_immutability.md.po | 224 +++ .../pt-BR/guide_databases_db-migrations.md.po | 918 +++++++++++ _translations/po/pt-BR/guide_glossary.md.po | 547 +++++++ _translations/po/pt-BR/guide_index.md.po | 630 ++++++++ .../pt-BR/guide_intro_upgrade-from-v1.md.po | 1189 ++++++++++++++ .../pt-BR/guide_intro_upgrade-from-v2.md.po | 1410 +++++++++++++++++ .../po/pt-BR/guide_intro_what-is-yii.md.po | 153 ++ .../po/pt-BR/guide_rest_quick-start.md.po | 500 ++++++ .../po/pt-BR/guide_runtime_cookies.md.po | 311 ++++ .../pt-BR/guide_runtime_handling-errors.md.po | 472 ++++++ .../po/pt-BR/guide_runtime_logging.md.po | 743 +++++++++ .../po/pt-BR/guide_runtime_request.md.po | 554 +++++++ .../po/pt-BR/guide_runtime_response.md.po | 236 +++ .../po/pt-BR/guide_runtime_routing.md.po | 861 ++++++++++ .../po/pt-BR/guide_runtime_sessions.md.po | 251 +++ .../pt-BR/guide_security_authentication.md.po | 391 +++++ .../pt-BR/guide_security_authorization.md.po | 854 ++++++++++ .../pt-BR/guide_security_best-practices.md.po | 496 ++++++ .../pt-BR/guide_security_cryptography.md.po | 232 +++ .../po/pt-BR/guide_security_overview.md.po | 67 + .../po/pt-BR/guide_security_passwords.md.po | 77 + .../guide_security_trusted-request.md.po | 76 + .../pt-BR/guide_start_creating-project.md.po | 154 ++ .../po/pt-BR/guide_start_databases.md.po | 1219 ++++++++++++++ .../po/pt-BR/guide_start_demo-apps.md.po | 60 + .../po/pt-BR/guide_start_forms.md.po | 799 ++++++++++ _translations/po/pt-BR/guide_start_gii.md.po | 32 + .../po/pt-BR/guide_start_hello.md.po | 362 +++++ .../po/pt-BR/guide_start_looking-ahead.md.po | 27 + .../po/pt-BR/guide_start_prerequisites.md.po | 97 ++ .../po/pt-BR/guide_start_workflow.md.po | 286 ++++ .../po/pt-BR/guide_structure_action.md.po | 188 +++ .../pt-BR/guide_structure_application.md.po | 47 + .../guide_structure_designing-packages.md.po | 789 +++++++++ .../pt-BR/guide_structure_entry-script.md.po | 202 +++ .../po/pt-BR/guide_structure_middleware.md.po | 315 ++++ .../po/pt-BR/guide_structure_module.md.po | 448 ++++++ .../po/pt-BR/guide_structure_overview.md.po | 160 ++ .../po/pt-BR/guide_structure_package.md.po | 239 +++ .../po/pt-BR/guide_testing_end-to-end.md.po | 246 +++ .../guide_testing_environment-setup.md.po | 365 +++++ .../po/pt-BR/guide_testing_functional.md.po | 201 +++ .../po/pt-BR/guide_testing_overview.md.po | 229 +++ .../pt-BR/guide_testing_quality-tools.md.po | 215 +++ .../po/pt-BR/guide_testing_unit.md.po | 304 ++++ .../guide_tutorial_console-applications.md.po | 155 ++ .../po/pt-BR/guide_tutorial_docker.md.po | 709 +++++++++ .../po/pt-BR/guide_tutorial_i18n.md.po | 697 ++++++++ .../po/pt-BR/guide_tutorial_mailing.md.po | 606 +++++++ .../guide_tutorial_performance-tuning.md.po | 344 ++++ ...guide_tutorial_using-with-event-loop.md.po | 141 ++ ...e_tutorial_using-yii-with-frankenphp.md.po | 370 +++++ ...guide_tutorial_using-yii-with-rapira.md.po | 256 +++ ...e_tutorial_using-yii-with-roadrunner.md.po | 304 ++++ ...guide_tutorial_using-yii-with-swoole.md.po | 262 +++ .../po/pt-BR/guide_views_asset.md.po | 997 ++++++++++++ .../pt-BR/guide_views_script-style-meta.md.po | 783 +++++++++ .../pt-BR/guide_views_template-engines.md.po | 363 +++++ .../pt-BR/guide_views_view-injections.md.po | 179 +++ _translations/po/pt-BR/guide_views_view.md.po | 490 ++++++ .../po/pt-BR/guide_views_widget.md.po | 1032 ++++++++++++ _translations/po/pt-BR/index.md.po | 97 ++ .../po/pt-BR/internals_000-packages.md.po | 236 +++ .../po/pt-BR/internals_001-yii-values.md.po | 242 +++ .../pt-BR/internals_002-issue-workflow.md.po | 95 ++ .../po/pt-BR/internals_003-roadmap.md.po | 598 +++++++ .../po/pt-BR/internals_004-namespaces.md.po | 81 + .../internals_005-development-tool.md.po | 83 + .../internals_006-git-commit-messages.md.po | 75 + .../po/pt-BR/internals_007-exceptions.md.po | 69 + .../po/pt-BR/internals_008-interfaces.md.po | 49 + .../internals_009-design-decisions.md.po | 195 +++ .../po/pt-BR/internals_010-code-style.md.po | 473 ++++++ .../internals_011-error-correction.md.po | 27 + .../po/pt-BR/internals_012-tests.md.po | 72 + .../po/pt-BR/internals_013-code-review.md.po | 119 ++ .../po/pt-BR/internals_014-docs.md.po | 390 +++++ .../po/pt-BR/internals_015-phpstorm.md.po | 134 ++ .../internals_016-security-workflow.md.po | 159 ++ .../po/pt-BR/internals_017-tags.md.po | 126 ++ .../po/pt-BR/internals_018-widgets.md.po | 116 ++ .../pt-BR/internals_019-view-code-style.md.po | 101 ++ .../pt-BR/internals_020-package-release.md.po | 157 ++ .../internals_021-changelog-upgrade.md.po | 130 ++ .../pt-BR/internals_022-config-groups.md.po | 244 +++ .../pt-BR/internals_023-github-actions.md.po | 80 + _translations/po/pt-BR/internals_index.md.po | 153 ++ _translations/po4a-base.conf | 2 +- _translations/po4a.conf | 2 +- src/.vitepress/config.js | 285 ++++ .../cookbook/configuring-webservers/apache.md | 60 + .../configuring-webservers/general.md | 43 + .../cookbook/configuring-webservers/iis.md | 36 + .../configuring-webservers/lighttpd.md | 10 + .../configuring-webservers/nginx-unit.md | 70 + .../cookbook/configuring-webservers/nginx.md | 66 + src/pt-BR/cookbook/configuring-xdebug.md | 278 ++++ .../cookbook/custom-hydrator-type-casters.md | 564 +++++++ .../cookbook/custom-migration-template.md | 136 ++ .../cookbook/deployment/angie-docker-proxy.md | 234 +++ src/pt-BR/cookbook/deployment/autoscaling.md | 168 ++ .../cookbook/deployment/docker-swarm-caddy.md | 591 +++++++ .../deployment/docker-swarm-traefik.md | 601 +++++++ src/pt-BR/cookbook/deployment/docker-swarm.md | 4 + .../deployment/rolling-update-migrations.md | 190 +++ .../cookbook/disabling-csrf-protection.md | 153 ++ src/pt-BR/cookbook/index.md | 44 + src/pt-BR/cookbook/making-http-requests.md | 208 +++ .../cookbook/opening-files-in-phpstorm.md | 128 ++ src/pt-BR/cookbook/organizing-code/domain.md | 91 ++ src/pt-BR/cookbook/organizing-code/service.md | 119 ++ ...turing-by-use-case-with-vertical-slices.md | 81 + src/pt-BR/cookbook/preface.md | 37 + src/pt-BR/cookbook/sentry-integration.md | 125 ++ .../third-party-integrations/index.md | 18 + .../symfony-messenger-integration-guide.md | 352 ++++ .../symfony-scheduler-integration-guide.md | 292 ++++ .../using-htmx-for-partial-reloads.md | 390 +++++ .../cookbook/using-yii-in-third-party-apps.md | 171 ++ src/pt-BR/cookbook/working-on-windows.md | 84 + src/pt-BR/guide/caching/data.md | 216 +++ src/pt-BR/guide/caching/overview.md | 21 + src/pt-BR/guide/concept/aliases.md | 149 ++ src/pt-BR/guide/concept/autoloading.md | 37 + src/pt-BR/guide/concept/configuration.md | 455 ++++++ src/pt-BR/guide/concept/di-container.md | 346 ++++ src/pt-BR/guide/concept/events.md | 197 +++ src/pt-BR/guide/concept/immutability.md | 160 ++ src/pt-BR/guide/databases/db-migrations.md | 450 ++++++ src/pt-BR/guide/glossary.md | 254 +++ src/pt-BR/guide/index.md | 162 ++ src/pt-BR/guide/intro/upgrade-from-v1.md | 752 +++++++++ src/pt-BR/guide/intro/upgrade-from-v2.md | 863 ++++++++++ src/pt-BR/guide/intro/what-is-yii.md | 72 + src/pt-BR/guide/rest/quick-start.md | 357 +++++ src/pt-BR/guide/runtime/cookies.md | 211 +++ src/pt-BR/guide/runtime/handling-errors.md | 318 ++++ src/pt-BR/guide/runtime/logging.md | 496 ++++++ src/pt-BR/guide/runtime/request.md | 336 ++++ src/pt-BR/guide/runtime/response.md | 134 ++ src/pt-BR/guide/runtime/routing.md | 582 +++++++ src/pt-BR/guide/runtime/sessions.md | 161 ++ src/pt-BR/guide/security/authentication.md | 258 +++ src/pt-BR/guide/security/authorization.md | 608 +++++++ src/pt-BR/guide/security/best-practices.md | 282 ++++ src/pt-BR/guide/security/cryptography.md | 123 ++ src/pt-BR/guide/security/overview.md | 19 + src/pt-BR/guide/security/passwords.md | 45 + src/pt-BR/guide/security/trusted-request.md | 43 + src/pt-BR/guide/start/creating-project.md | 67 + src/pt-BR/guide/start/databases.md | 905 +++++++++++ src/pt-BR/guide/start/demo-apps.md | 24 + src/pt-BR/guide/start/forms.md | 429 +++++ src/pt-BR/guide/start/gii.md | 4 + src/pt-BR/guide/start/hello.md | 192 +++ src/pt-BR/guide/start/looking-ahead.md | 9 + src/pt-BR/guide/start/prerequisites.md | 45 + src/pt-BR/guide/start/workflow.md | 149 ++ src/pt-BR/guide/structure/action.md | 128 ++ src/pt-BR/guide/structure/application.md | 18 + .../guide/structure/designing-packages.md | 536 +++++++ src/pt-BR/guide/structure/entry-script.md | 116 ++ src/pt-BR/guide/structure/middleware.md | 195 +++ src/pt-BR/guide/structure/module.md | 280 ++++ src/pt-BR/guide/structure/overview.md | 65 + src/pt-BR/guide/structure/package.md | 118 ++ src/pt-BR/guide/testing/end-to-end.md | 131 ++ src/pt-BR/guide/testing/environment-setup.md | 195 +++ src/pt-BR/guide/testing/functional.md | 129 ++ src/pt-BR/guide/testing/overview.md | 99 ++ src/pt-BR/guide/testing/quality-tools.md | 110 ++ src/pt-BR/guide/testing/unit.md | 213 +++ .../guide/tutorial/console-applications.md | 93 ++ src/pt-BR/guide/tutorial/docker.md | 456 ++++++ src/pt-BR/guide/tutorial/i18n.md | 449 ++++++ src/pt-BR/guide/tutorial/mailing.md | 329 ++++ .../guide/tutorial/performance-tuning.md | 219 +++ .../guide/tutorial/using-with-event-loop.md | 67 + .../tutorial/using-yii-with-frankenphp.md | 263 +++ .../guide/tutorial/using-yii-with-rapira.md | 143 ++ .../tutorial/using-yii-with-roadrunner.md | 180 +++ .../guide/tutorial/using-yii-with-swoole.md | 172 ++ src/pt-BR/guide/views/asset.md | 666 ++++++++ src/pt-BR/guide/views/script-style-meta.md | 505 ++++++ src/pt-BR/guide/views/template-engines.md | 207 +++ src/pt-BR/guide/views/view-injections.md | 116 ++ src/pt-BR/guide/views/view.md | 316 ++++ src/pt-BR/guide/views/widget.md | 767 +++++++++ src/pt-BR/index.md | 39 + src/pt-BR/internals/000-packages.md | 84 + src/pt-BR/internals/001-yii-values.md | 82 + src/pt-BR/internals/002-issue-workflow.md | 27 + src/pt-BR/internals/003-roadmap.md | 207 +++ src/pt-BR/internals/004-namespaces.md | 23 + src/pt-BR/internals/005-development-tool.md | 51 + .../internals/006-git-commit-messages.md | 18 + src/pt-BR/internals/007-exceptions.md | 16 + src/pt-BR/internals/008-interfaces.md | 10 + src/pt-BR/internals/009-design-decisions.md | 89 ++ src/pt-BR/internals/010-code-style.md | 210 +++ src/pt-BR/internals/011-error-correction.md | 5 + src/pt-BR/internals/012-tests.md | 18 + src/pt-BR/internals/013-code-review.md | 33 + src/pt-BR/internals/014-docs.md | 223 +++ src/pt-BR/internals/015-phpstorm.md | 70 + src/pt-BR/internals/016-security-workflow.md | 68 + src/pt-BR/internals/017-tags.md | 43 + src/pt-BR/internals/018-widgets.md | 36 + src/pt-BR/internals/019-view-code-style.md | 46 + src/pt-BR/internals/020-package-release.md | 56 + src/pt-BR/internals/021-changelog-upgrade.md | 67 + src/pt-BR/internals/022-config-groups.md | 73 + src/pt-BR/internals/023-github-actions.md | 34 + src/pt-BR/internals/index.md | 48 + 251 files changed, 66217 insertions(+), 2 deletions(-) create mode 100644 _translations/po/pt-BR/cookbook_configuring-webservers_apache.md.po create mode 100644 _translations/po/pt-BR/cookbook_configuring-webservers_general.md.po create mode 100644 _translations/po/pt-BR/cookbook_configuring-webservers_iis.md.po create mode 100644 _translations/po/pt-BR/cookbook_configuring-webservers_lighttpd.md.po create mode 100644 _translations/po/pt-BR/cookbook_configuring-webservers_nginx-unit.md.po create mode 100644 _translations/po/pt-BR/cookbook_configuring-webservers_nginx.md.po create mode 100644 _translations/po/pt-BR/cookbook_configuring-xdebug.md.po create mode 100644 _translations/po/pt-BR/cookbook_custom-hydrator-type-casters.md.po create mode 100644 _translations/po/pt-BR/cookbook_custom-migration-template.md.po create mode 100644 _translations/po/pt-BR/cookbook_deployment_angie-docker-proxy.md.po create mode 100644 _translations/po/pt-BR/cookbook_deployment_autoscaling.md.po create mode 100644 _translations/po/pt-BR/cookbook_deployment_docker-swarm-caddy.md.po create mode 100644 _translations/po/pt-BR/cookbook_deployment_docker-swarm-traefik.md.po create mode 100644 _translations/po/pt-BR/cookbook_deployment_docker-swarm.md.po create mode 100644 _translations/po/pt-BR/cookbook_deployment_rolling-update-migrations.md.po create mode 100644 _translations/po/pt-BR/cookbook_disabling-csrf-protection.md.po create mode 100644 _translations/po/pt-BR/cookbook_index.md.po create mode 100644 _translations/po/pt-BR/cookbook_making-http-requests.md.po create mode 100644 _translations/po/pt-BR/cookbook_opening-files-in-phpstorm.md.po create mode 100644 _translations/po/pt-BR/cookbook_organizing-code_domain.md.po create mode 100644 _translations/po/pt-BR/cookbook_organizing-code_service.md.po create mode 100644 _translations/po/pt-BR/cookbook_organizing-code_structuring-by-use-case-with-vertical-slices.md.po create mode 100644 _translations/po/pt-BR/cookbook_preface.md.po create mode 100644 _translations/po/pt-BR/cookbook_sentry-integration.md.po create mode 100644 _translations/po/pt-BR/cookbook_third-party-integrations_index.md.po create mode 100644 _translations/po/pt-BR/cookbook_third-party-integrations_symfony-messenger-integration-guide.md.po create mode 100644 _translations/po/pt-BR/cookbook_third-party-integrations_symfony-scheduler-integration-guide.md.po create mode 100644 _translations/po/pt-BR/cookbook_using-htmx-for-partial-reloads.md.po create mode 100644 _translations/po/pt-BR/cookbook_using-yii-in-third-party-apps.md.po create mode 100644 _translations/po/pt-BR/cookbook_working-on-windows.md.po create mode 100644 _translations/po/pt-BR/guide_caching_data.md.po create mode 100644 _translations/po/pt-BR/guide_caching_overview.md.po create mode 100644 _translations/po/pt-BR/guide_concept_aliases.md.po create mode 100644 _translations/po/pt-BR/guide_concept_autoloading.md.po create mode 100644 _translations/po/pt-BR/guide_concept_configuration.md.po create mode 100644 _translations/po/pt-BR/guide_concept_di-container.md.po create mode 100644 _translations/po/pt-BR/guide_concept_events.md.po create mode 100644 _translations/po/pt-BR/guide_concept_immutability.md.po create mode 100644 _translations/po/pt-BR/guide_databases_db-migrations.md.po create mode 100644 _translations/po/pt-BR/guide_glossary.md.po create mode 100644 _translations/po/pt-BR/guide_index.md.po create mode 100644 _translations/po/pt-BR/guide_intro_upgrade-from-v1.md.po create mode 100644 _translations/po/pt-BR/guide_intro_upgrade-from-v2.md.po create mode 100644 _translations/po/pt-BR/guide_intro_what-is-yii.md.po create mode 100644 _translations/po/pt-BR/guide_rest_quick-start.md.po create mode 100644 _translations/po/pt-BR/guide_runtime_cookies.md.po create mode 100644 _translations/po/pt-BR/guide_runtime_handling-errors.md.po create mode 100644 _translations/po/pt-BR/guide_runtime_logging.md.po create mode 100644 _translations/po/pt-BR/guide_runtime_request.md.po create mode 100644 _translations/po/pt-BR/guide_runtime_response.md.po create mode 100644 _translations/po/pt-BR/guide_runtime_routing.md.po create mode 100644 _translations/po/pt-BR/guide_runtime_sessions.md.po create mode 100644 _translations/po/pt-BR/guide_security_authentication.md.po create mode 100644 _translations/po/pt-BR/guide_security_authorization.md.po create mode 100644 _translations/po/pt-BR/guide_security_best-practices.md.po create mode 100644 _translations/po/pt-BR/guide_security_cryptography.md.po create mode 100644 _translations/po/pt-BR/guide_security_overview.md.po create mode 100644 _translations/po/pt-BR/guide_security_passwords.md.po create mode 100644 _translations/po/pt-BR/guide_security_trusted-request.md.po create mode 100644 _translations/po/pt-BR/guide_start_creating-project.md.po create mode 100644 _translations/po/pt-BR/guide_start_databases.md.po create mode 100644 _translations/po/pt-BR/guide_start_demo-apps.md.po create mode 100644 _translations/po/pt-BR/guide_start_forms.md.po create mode 100644 _translations/po/pt-BR/guide_start_gii.md.po create mode 100644 _translations/po/pt-BR/guide_start_hello.md.po create mode 100644 _translations/po/pt-BR/guide_start_looking-ahead.md.po create mode 100644 _translations/po/pt-BR/guide_start_prerequisites.md.po create mode 100644 _translations/po/pt-BR/guide_start_workflow.md.po create mode 100644 _translations/po/pt-BR/guide_structure_action.md.po create mode 100644 _translations/po/pt-BR/guide_structure_application.md.po create mode 100644 _translations/po/pt-BR/guide_structure_designing-packages.md.po create mode 100644 _translations/po/pt-BR/guide_structure_entry-script.md.po create mode 100644 _translations/po/pt-BR/guide_structure_middleware.md.po create mode 100644 _translations/po/pt-BR/guide_structure_module.md.po create mode 100644 _translations/po/pt-BR/guide_structure_overview.md.po create mode 100644 _translations/po/pt-BR/guide_structure_package.md.po create mode 100644 _translations/po/pt-BR/guide_testing_end-to-end.md.po create mode 100644 _translations/po/pt-BR/guide_testing_environment-setup.md.po create mode 100644 _translations/po/pt-BR/guide_testing_functional.md.po create mode 100644 _translations/po/pt-BR/guide_testing_overview.md.po create mode 100644 _translations/po/pt-BR/guide_testing_quality-tools.md.po create mode 100644 _translations/po/pt-BR/guide_testing_unit.md.po create mode 100644 _translations/po/pt-BR/guide_tutorial_console-applications.md.po create mode 100644 _translations/po/pt-BR/guide_tutorial_docker.md.po create mode 100644 _translations/po/pt-BR/guide_tutorial_i18n.md.po create mode 100644 _translations/po/pt-BR/guide_tutorial_mailing.md.po create mode 100644 _translations/po/pt-BR/guide_tutorial_performance-tuning.md.po create mode 100644 _translations/po/pt-BR/guide_tutorial_using-with-event-loop.md.po create mode 100644 _translations/po/pt-BR/guide_tutorial_using-yii-with-frankenphp.md.po create mode 100644 _translations/po/pt-BR/guide_tutorial_using-yii-with-rapira.md.po create mode 100644 _translations/po/pt-BR/guide_tutorial_using-yii-with-roadrunner.md.po create mode 100644 _translations/po/pt-BR/guide_tutorial_using-yii-with-swoole.md.po create mode 100644 _translations/po/pt-BR/guide_views_asset.md.po create mode 100644 _translations/po/pt-BR/guide_views_script-style-meta.md.po create mode 100644 _translations/po/pt-BR/guide_views_template-engines.md.po create mode 100644 _translations/po/pt-BR/guide_views_view-injections.md.po create mode 100644 _translations/po/pt-BR/guide_views_view.md.po create mode 100644 _translations/po/pt-BR/guide_views_widget.md.po create mode 100644 _translations/po/pt-BR/index.md.po create mode 100644 _translations/po/pt-BR/internals_000-packages.md.po create mode 100644 _translations/po/pt-BR/internals_001-yii-values.md.po create mode 100644 _translations/po/pt-BR/internals_002-issue-workflow.md.po create mode 100644 _translations/po/pt-BR/internals_003-roadmap.md.po create mode 100644 _translations/po/pt-BR/internals_004-namespaces.md.po create mode 100644 _translations/po/pt-BR/internals_005-development-tool.md.po create mode 100644 _translations/po/pt-BR/internals_006-git-commit-messages.md.po create mode 100644 _translations/po/pt-BR/internals_007-exceptions.md.po create mode 100644 _translations/po/pt-BR/internals_008-interfaces.md.po create mode 100644 _translations/po/pt-BR/internals_009-design-decisions.md.po create mode 100644 _translations/po/pt-BR/internals_010-code-style.md.po create mode 100644 _translations/po/pt-BR/internals_011-error-correction.md.po create mode 100644 _translations/po/pt-BR/internals_012-tests.md.po create mode 100644 _translations/po/pt-BR/internals_013-code-review.md.po create mode 100644 _translations/po/pt-BR/internals_014-docs.md.po create mode 100644 _translations/po/pt-BR/internals_015-phpstorm.md.po create mode 100644 _translations/po/pt-BR/internals_016-security-workflow.md.po create mode 100644 _translations/po/pt-BR/internals_017-tags.md.po create mode 100644 _translations/po/pt-BR/internals_018-widgets.md.po create mode 100644 _translations/po/pt-BR/internals_019-view-code-style.md.po create mode 100644 _translations/po/pt-BR/internals_020-package-release.md.po create mode 100644 _translations/po/pt-BR/internals_021-changelog-upgrade.md.po create mode 100644 _translations/po/pt-BR/internals_022-config-groups.md.po create mode 100644 _translations/po/pt-BR/internals_023-github-actions.md.po create mode 100644 _translations/po/pt-BR/internals_index.md.po create mode 100644 src/pt-BR/cookbook/configuring-webservers/apache.md create mode 100644 src/pt-BR/cookbook/configuring-webservers/general.md create mode 100644 src/pt-BR/cookbook/configuring-webservers/iis.md create mode 100644 src/pt-BR/cookbook/configuring-webservers/lighttpd.md create mode 100644 src/pt-BR/cookbook/configuring-webservers/nginx-unit.md create mode 100644 src/pt-BR/cookbook/configuring-webservers/nginx.md create mode 100644 src/pt-BR/cookbook/configuring-xdebug.md create mode 100644 src/pt-BR/cookbook/custom-hydrator-type-casters.md create mode 100644 src/pt-BR/cookbook/custom-migration-template.md create mode 100644 src/pt-BR/cookbook/deployment/angie-docker-proxy.md create mode 100644 src/pt-BR/cookbook/deployment/autoscaling.md create mode 100644 src/pt-BR/cookbook/deployment/docker-swarm-caddy.md create mode 100644 src/pt-BR/cookbook/deployment/docker-swarm-traefik.md create mode 100644 src/pt-BR/cookbook/deployment/docker-swarm.md create mode 100644 src/pt-BR/cookbook/deployment/rolling-update-migrations.md create mode 100644 src/pt-BR/cookbook/disabling-csrf-protection.md create mode 100644 src/pt-BR/cookbook/index.md create mode 100644 src/pt-BR/cookbook/making-http-requests.md create mode 100644 src/pt-BR/cookbook/opening-files-in-phpstorm.md create mode 100644 src/pt-BR/cookbook/organizing-code/domain.md create mode 100644 src/pt-BR/cookbook/organizing-code/service.md create mode 100644 src/pt-BR/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md create mode 100644 src/pt-BR/cookbook/preface.md create mode 100644 src/pt-BR/cookbook/sentry-integration.md create mode 100644 src/pt-BR/cookbook/third-party-integrations/index.md create mode 100644 src/pt-BR/cookbook/third-party-integrations/symfony-messenger-integration-guide.md create mode 100644 src/pt-BR/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md create mode 100644 src/pt-BR/cookbook/using-htmx-for-partial-reloads.md create mode 100644 src/pt-BR/cookbook/using-yii-in-third-party-apps.md create mode 100644 src/pt-BR/cookbook/working-on-windows.md create mode 100644 src/pt-BR/guide/caching/data.md create mode 100644 src/pt-BR/guide/caching/overview.md create mode 100644 src/pt-BR/guide/concept/aliases.md create mode 100644 src/pt-BR/guide/concept/autoloading.md create mode 100644 src/pt-BR/guide/concept/configuration.md create mode 100644 src/pt-BR/guide/concept/di-container.md create mode 100644 src/pt-BR/guide/concept/events.md create mode 100644 src/pt-BR/guide/concept/immutability.md create mode 100644 src/pt-BR/guide/databases/db-migrations.md create mode 100644 src/pt-BR/guide/glossary.md create mode 100644 src/pt-BR/guide/index.md create mode 100644 src/pt-BR/guide/intro/upgrade-from-v1.md create mode 100644 src/pt-BR/guide/intro/upgrade-from-v2.md create mode 100644 src/pt-BR/guide/intro/what-is-yii.md create mode 100644 src/pt-BR/guide/rest/quick-start.md create mode 100644 src/pt-BR/guide/runtime/cookies.md create mode 100644 src/pt-BR/guide/runtime/handling-errors.md create mode 100644 src/pt-BR/guide/runtime/logging.md create mode 100644 src/pt-BR/guide/runtime/request.md create mode 100644 src/pt-BR/guide/runtime/response.md create mode 100644 src/pt-BR/guide/runtime/routing.md create mode 100644 src/pt-BR/guide/runtime/sessions.md create mode 100644 src/pt-BR/guide/security/authentication.md create mode 100644 src/pt-BR/guide/security/authorization.md create mode 100644 src/pt-BR/guide/security/best-practices.md create mode 100644 src/pt-BR/guide/security/cryptography.md create mode 100644 src/pt-BR/guide/security/overview.md create mode 100644 src/pt-BR/guide/security/passwords.md create mode 100644 src/pt-BR/guide/security/trusted-request.md create mode 100644 src/pt-BR/guide/start/creating-project.md create mode 100644 src/pt-BR/guide/start/databases.md create mode 100644 src/pt-BR/guide/start/demo-apps.md create mode 100644 src/pt-BR/guide/start/forms.md create mode 100644 src/pt-BR/guide/start/gii.md create mode 100644 src/pt-BR/guide/start/hello.md create mode 100644 src/pt-BR/guide/start/looking-ahead.md create mode 100644 src/pt-BR/guide/start/prerequisites.md create mode 100644 src/pt-BR/guide/start/workflow.md create mode 100644 src/pt-BR/guide/structure/action.md create mode 100644 src/pt-BR/guide/structure/application.md create mode 100644 src/pt-BR/guide/structure/designing-packages.md create mode 100644 src/pt-BR/guide/structure/entry-script.md create mode 100644 src/pt-BR/guide/structure/middleware.md create mode 100644 src/pt-BR/guide/structure/module.md create mode 100644 src/pt-BR/guide/structure/overview.md create mode 100644 src/pt-BR/guide/structure/package.md create mode 100644 src/pt-BR/guide/testing/end-to-end.md create mode 100644 src/pt-BR/guide/testing/environment-setup.md create mode 100644 src/pt-BR/guide/testing/functional.md create mode 100644 src/pt-BR/guide/testing/overview.md create mode 100644 src/pt-BR/guide/testing/quality-tools.md create mode 100644 src/pt-BR/guide/testing/unit.md create mode 100644 src/pt-BR/guide/tutorial/console-applications.md create mode 100644 src/pt-BR/guide/tutorial/docker.md create mode 100644 src/pt-BR/guide/tutorial/i18n.md create mode 100644 src/pt-BR/guide/tutorial/mailing.md create mode 100644 src/pt-BR/guide/tutorial/performance-tuning.md create mode 100644 src/pt-BR/guide/tutorial/using-with-event-loop.md create mode 100644 src/pt-BR/guide/tutorial/using-yii-with-frankenphp.md create mode 100644 src/pt-BR/guide/tutorial/using-yii-with-rapira.md create mode 100644 src/pt-BR/guide/tutorial/using-yii-with-roadrunner.md create mode 100644 src/pt-BR/guide/tutorial/using-yii-with-swoole.md create mode 100644 src/pt-BR/guide/views/asset.md create mode 100644 src/pt-BR/guide/views/script-style-meta.md create mode 100644 src/pt-BR/guide/views/template-engines.md create mode 100644 src/pt-BR/guide/views/view-injections.md create mode 100644 src/pt-BR/guide/views/view.md create mode 100644 src/pt-BR/guide/views/widget.md create mode 100644 src/pt-BR/index.md create mode 100644 src/pt-BR/internals/000-packages.md create mode 100644 src/pt-BR/internals/001-yii-values.md create mode 100644 src/pt-BR/internals/002-issue-workflow.md create mode 100644 src/pt-BR/internals/003-roadmap.md create mode 100644 src/pt-BR/internals/004-namespaces.md create mode 100644 src/pt-BR/internals/005-development-tool.md create mode 100644 src/pt-BR/internals/006-git-commit-messages.md create mode 100644 src/pt-BR/internals/007-exceptions.md create mode 100644 src/pt-BR/internals/008-interfaces.md create mode 100644 src/pt-BR/internals/009-design-decisions.md create mode 100644 src/pt-BR/internals/010-code-style.md create mode 100644 src/pt-BR/internals/011-error-correction.md create mode 100644 src/pt-BR/internals/012-tests.md create mode 100644 src/pt-BR/internals/013-code-review.md create mode 100644 src/pt-BR/internals/014-docs.md create mode 100644 src/pt-BR/internals/015-phpstorm.md create mode 100644 src/pt-BR/internals/016-security-workflow.md create mode 100644 src/pt-BR/internals/017-tags.md create mode 100644 src/pt-BR/internals/018-widgets.md create mode 100644 src/pt-BR/internals/019-view-code-style.md create mode 100644 src/pt-BR/internals/020-package-release.md create mode 100644 src/pt-BR/internals/021-changelog-upgrade.md create mode 100644 src/pt-BR/internals/022-config-groups.md create mode 100644 src/pt-BR/internals/023-github-actions.md create mode 100644 src/pt-BR/internals/index.md diff --git a/_translations/po/pt-BR/cookbook_configuring-webservers_apache.md.po b/_translations/po/pt-BR/cookbook_configuring-webservers_apache.md.po new file mode 100644 index 00000000..05ba666e --- /dev/null +++ b/_translations/po/pt-BR/cookbook_configuring-webservers_apache.md.po @@ -0,0 +1,96 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-10-15 10:10+0000\n" +"PO-Revision-Date: 2026-10-15 10:10+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/cookbook/configuring-webservers/apache.md +#, no-wrap +msgid "Configuring web servers: Apache" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-webservers/apache.md +msgid "Use the following configuration in Apache's `httpd.conf` file or within a virtual host configuration. Note that you should replace `path/to/app/public` with the actual path for `app/public`." +msgstr "" + +#. type: Fenced code block (apache) +#: ../src/cookbook/configuring-webservers/apache.md +#, no-wrap +msgid "" +"# Set document root to be \"app/public\"\n" +"DocumentRoot \"path/to/app/public\"\n" +"\n" +"\n" +" # use mod_rewrite for pretty URL support\n" +" RewriteEngine on\n" +" \n" +" # Do not allow access to URLs with a script name\n" +" RewriteCond %{THE_REQUEST} index.php [NC]\n" +" RewriteRule . - [R=404,L]\n" +" \n" +" # If a directory or a file exists, use the request directly\n" +" RewriteCond %{REQUEST_FILENAME} !-f\n" +" RewriteCond %{REQUEST_FILENAME} !-d\n" +" \n" +" # Otherwise forward the request to index.php\n" +" RewriteRule . index.php\n" +" \n" +" SetEnv APP_ENV dev\n" +"\n" +" # ...other settings...\n" +"\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-webservers/apache.md +msgid "In case you have `AllowOverride All` you can add `.htaccess` file with the following configuration instead of using `httpd.conf`:" +msgstr "" + +#. type: Fenced code block (apache) +#: ../src/cookbook/configuring-webservers/apache.md +#, no-wrap +msgid "" +"# use mod_rewrite for pretty URL support\n" +"RewriteEngine on\n" +"\n" +"# Do not allow access to URLs with a script name\n" +"RewriteCond %{THE_REQUEST} index.php [NC]\n" +"RewriteRule . - [R=404,L]\n" +"\n" +"# If a directory or a file exists, use the request directly\n" +"RewriteCond %{REQUEST_FILENAME} !-f\n" +"RewriteCond %{REQUEST_FILENAME} !-d\n" +"\n" +"# Otherwise forward the request to index.php\n" +"RewriteRule . index.php\n" +"\n" +"SetEnv APP_ENV dev\n" +"\n" +"# ...other settings...\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-webservers/apache.md +msgid "In the above, note the usage of `SetEnv`. Since Yii3 application templates use environment variables, this is a possible place to set them. In production environment remember to set `APP_ENV` to `prod`." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-webservers/apache.md +#: ../src/cookbook/configuring-webservers/iis.md +#: ../src/cookbook/configuring-webservers/lighttpd.md +#: ../src/cookbook/configuring-webservers/nginx-unit.md +msgid "See [application logs](general.md#application-logs) for logging configuration." +msgstr "" diff --git a/_translations/po/pt-BR/cookbook_configuring-webservers_general.md.po b/_translations/po/pt-BR/cookbook_configuring-webservers_general.md.po new file mode 100644 index 00000000..62ba593b --- /dev/null +++ b/_translations/po/pt-BR/cookbook_configuring-webservers_general.md.po @@ -0,0 +1,100 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-10-15 10:10+0000\n" +"PO-Revision-Date: 2026-10-15 10:10+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/cookbook/configuring-webservers/general.md +#, no-wrap +msgid "Configuring web servers: General" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-webservers/general.md +msgid "On a production server, if you don't use Docker, configure your web server to serve only the application's public files. Point the document root of your web server to the `app/public` folder." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-webservers/general.md +#, no-wrap +msgid "" +"> [!IMPORTANT]\n" +"> If you're running your Yii application behind a reverse proxy, you might need to configure\n" +"> [Trusted proxies and headers](../../guide/security/trusted-request.md).\n" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/configuring-webservers/general.md +#, no-wrap +msgid "Application logs" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-webservers/general.md +msgid "Yii3 application templates write application logs to standard output (`stdout`, or `php://stdout`) by default. They don't create application log files. Standard error (`stderr`) requires explicit log target configuration. Docker collects container output, but on a server without containers you must configure where that output goes or [configure a file target](../../guide/runtime/logging.md#logging-to-files). Web server access and error log settings don't configure Yii's log targets." +msgstr "" + +#. type: Title ### +#: ../src/cookbook/configuring-webservers/general.md +#, no-wrap +msgid "PHP-FPM" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-webservers/general.md +msgid "If your web server uses PHP-FPM, enable worker output capture in the application's PHP-FPM pool configuration:" +msgstr "" + +#. type: Fenced code block (ini) +#: ../src/cookbook/configuring-webservers/general.md +#, no-wrap +msgid "catch_workers_output = yes\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-webservers/general.md +msgid "Reload PHP-FPM after changing its configuration. PHP-FPM sends worker standard output and standard error to its main error log. The `error_log` directive in `php-fpm.conf` sets the destination. Without this setting, PHP-FPM redirects both streams to `/dev/null` by default. See the [PHP-FPM configuration reference](https://www.php.net/manual/en/install.fpm.configuration.php)." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/configuring-webservers/general.md +#, no-wrap +msgid "Specific server configurations" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/configuring-webservers/general.md +msgid "[Nginx](nginx.md)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/configuring-webservers/general.md +msgid "[Apache](apache.md)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/configuring-webservers/general.md +msgid "[Lighttpd](lighttpd.md)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/configuring-webservers/general.md +msgid "[Nginx Unit](nginx-unit.md)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/configuring-webservers/general.md +msgid "[IIS](iis.md)" +msgstr "" diff --git a/_translations/po/pt-BR/cookbook_configuring-webservers_iis.md.po b/_translations/po/pt-BR/cookbook_configuring-webservers_iis.md.po new file mode 100644 index 00000000..2b9e5617 --- /dev/null +++ b/_translations/po/pt-BR/cookbook_configuring-webservers_iis.md.po @@ -0,0 +1,66 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-10-15 10:10+0000\n" +"PO-Revision-Date: 2026-10-15 10:10+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Plain text +#: ../src/cookbook/configuring-webservers/apache.md +#: ../src/cookbook/configuring-webservers/iis.md +#: ../src/cookbook/configuring-webservers/lighttpd.md +#: ../src/cookbook/configuring-webservers/nginx-unit.md +msgid "See [application logs](general.md#application-logs) for logging configuration." +msgstr "" + +#. type: Title # +#: ../src/cookbook/configuring-webservers/iis.md +#, no-wrap +msgid "Configuring web servers: IIS" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-webservers/iis.md +msgid "When you use [IIS](https://www.iis.net/), host the application in a virtual host (Website) where the document root points to the `path/to/app/public` folder and configure the website to run PHP. In that `public` folder, place a file named `web.config` at `path/to/app/public/web.config`. Use the following content:" +msgstr "" + +#. type: Fenced code block (xml) +#: ../src/cookbook/configuring-webservers/iis.md +#, no-wrap +msgid "" +"\n" +"\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-webservers/iis.md +msgid "Also, [IIS documentation](https://learn.microsoft.com/en-us/iis/) could be useful to configure PHP on IIS." +msgstr "" diff --git a/_translations/po/pt-BR/cookbook_configuring-webservers_lighttpd.md.po b/_translations/po/pt-BR/cookbook_configuring-webservers_lighttpd.md.po new file mode 100644 index 00000000..a6e025df --- /dev/null +++ b/_translations/po/pt-BR/cookbook_configuring-webservers_lighttpd.md.po @@ -0,0 +1,42 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-10-15 10:10+0000\n" +"PO-Revision-Date: 2026-10-15 10:10+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Plain text +#: ../src/cookbook/configuring-webservers/apache.md +#: ../src/cookbook/configuring-webservers/iis.md +#: ../src/cookbook/configuring-webservers/lighttpd.md +#: ../src/cookbook/configuring-webservers/nginx-unit.md +msgid "See [application logs](general.md#application-logs) for logging configuration." +msgstr "" + +#. type: Title # +#: ../src/cookbook/configuring-webservers/lighttpd.md +#, no-wrap +msgid "Configuring web servers: lighttpd" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-webservers/lighttpd.md +#, no-wrap +msgid "To use [lighttpd](https://www.lighttpd.net/) >= 1.4.24, put `index.php` in the web root and add the following to the configuration:\n" +msgstr "" + +#. type: Fenced code block +#: ../src/cookbook/configuring-webservers/lighttpd.md +#, no-wrap +msgid "url.rewrite-if-not-file = (\"(.*)\" => \"/index.php/$0\")\n" +msgstr "" diff --git a/_translations/po/pt-BR/cookbook_configuring-webservers_nginx-unit.md.po b/_translations/po/pt-BR/cookbook_configuring-webservers_nginx-unit.md.po new file mode 100644 index 00000000..ca9d0a9f --- /dev/null +++ b/_translations/po/pt-BR/cookbook_configuring-webservers_nginx-unit.md.po @@ -0,0 +1,103 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-10-15 10:10+0000\n" +"PO-Revision-Date: 2026-10-15 10:10+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Plain text +#: ../src/cookbook/configuring-webservers/apache.md +#: ../src/cookbook/configuring-webservers/iis.md +#: ../src/cookbook/configuring-webservers/lighttpd.md +#: ../src/cookbook/configuring-webservers/nginx-unit.md +msgid "See [application logs](general.md#application-logs) for logging configuration." +msgstr "" + +#. type: Title # +#: ../src/cookbook/configuring-webservers/nginx-unit.md +#, no-wrap +msgid "Configuring web servers: NGINX Unit and FreeUnit" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-webservers/nginx-unit.md +msgid "Run Yii-based apps using [NGINX Unit](https://unit.nginx.org/) with a PHP language module. The same configuration format is used by [FreeUnit](https://github.com/freeunitorg/freeunit), a community LTS fork of Unit. With FreeUnit Docker images, such as `ghcr.io/freeunitorg/freeunit:latest-php8.5`, put the configuration in `/var/lib/unit/config.json`." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-webservers/nginx-unit.md +msgid "Here is a sample configuration." +msgstr "" + +#. type: Fenced code block (json) +#: ../src/cookbook/configuring-webservers/nginx-unit.md +#, no-wrap +msgid "" +"{\n" +" \"listeners\": {\n" +" \"*:80\": {\n" +" \"pass\": \"routes\"\n" +" }\n" +" },\n" +"\n" +" \"routes\": [\n" +" {\n" +" \"match\": {\n" +" \"uri\": [\n" +" \"!/assets/*\",\n" +" \"*.php\",\n" +" \"*.php/*\"\n" +" ]\n" +" },\n" +"\n" +" \"action\": {\n" +" \"pass\": \"applications/yii/direct\"\n" +" }\n" +" },\n" +" {\n" +" \"action\": {\n" +" \"share\": \"/path/to/app/public$uri\",\n" +" \"fallback\": {\n" +" \"pass\": \"applications/yii/index\"\n" +" }\n" +" }\n" +" }\n" +" ],\n" +"\n" +" \"applications\": {\n" +" \"yii\": {\n" +" \"type\": \"php\",\n" +" \"targets\": {\n" +" \"direct\": {\n" +" \"root\": \"/path/to/app/public/\"\n" +" },\n" +"\n" +" \"index\": {\n" +" \"root\": \"/path/to/app/public/\",\n" +" \"script\": \"index.php\"\n" +" }\n" +" }\n" +" }\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-webservers/nginx-unit.md +msgid "You can also [set up](https://unit.nginx.org/configuration/#php) your PHP environment or supply a custom `php.ini` in the same configuration." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-webservers/nginx-unit.md +msgid "Since Yii3 application templates use environment variables, you can set them in `applications.yii.environment`. In a production environment, remember to set `APP_ENV` to `prod`." +msgstr "" diff --git a/_translations/po/pt-BR/cookbook_configuring-webservers_nginx.md.po b/_translations/po/pt-BR/cookbook_configuring-webservers_nginx.md.po new file mode 100644 index 00000000..b42ff0a9 --- /dev/null +++ b/_translations/po/pt-BR/cookbook_configuring-webservers_nginx.md.po @@ -0,0 +1,96 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-10-15 10:10+0000\n" +"PO-Revision-Date: 2026-10-15 10:10+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/cookbook/configuring-webservers/nginx.md +#, no-wrap +msgid "Configuring web servers: Nginx" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-webservers/nginx.md +msgid "To use [Nginx](https:/nginx.org/), install PHP as an [FPM SAPI](https://secure.php.net/install.fpm). Use the following Nginx configuration, replacing `path/to/app/public` with the actual path for `app/public` and `mysite.test` with the actual hostname to serve." +msgstr "" + +#. type: Fenced code block (nginx) +#: ../src/cookbook/configuring-webservers/nginx.md +#, no-wrap +msgid "" +"server {\n" +" charset utf-8;\n" +" client_max_body_size 128M;\n" +"\n" +" listen 80; ## listen for ipv4\n" +" #listen [::]:80 default_server ipv6only=on; ## listen for ipv6\n" +"\n" +" server_name mysite.test;\n" +" root /path/to/app/public;\n" +" index index.php;\n" +"\n" +" access_log /path/to/basic/log/access.log;\n" +" error_log /path/to/basic/log/error.log;\n" +"\n" +" location / {\n" +" # Redirect everything that isn't a real file to index.php\n" +" try_files $uri $uri/ /index.php$is_args$args;\n" +" }\n" +"\n" +" # uncomment to avoid processing of calls to non-existing static files by Yii\n" +" #location ~ \\.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {\n" +" # try_files $uri =404;\n" +" #}\n" +" #error_page 404 /404.html;\n" +"\n" +" # deny accessing php files for the /assets directory\n" +" location ~ ^/assets/.*\\.php$ {\n" +" deny all;\n" +" }\n" +"\n" +" location ~ \\.php$ {\n" +" include fastcgi_params;\n" +" fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;\n" +" fastcgi_pass 127.0.0.1:9000;\n" +" #fastcgi_pass unix:/var/run/php8-fpm.sock;\n" +" try_files $uri =404;\n" +" fastcgi_param APP_ENV \"dev\";\n" +" }\n" +"\n" +" location ~* /\\. {\n" +" deny all;\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-webservers/nginx.md +msgid "When you use this configuration, also set `cgi.fix_pathinfo=0` in the `php.ini` file to avoid many unnecessary system `stat()` calls." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-webservers/nginx.md +msgid "Also, note that when running an HTTPS server, you need to add `fastcgi_param HTTPS on;` so that Yii can detect if a connection is secure." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-webservers/nginx.md +msgid "In the above, note the usage of `fastcgi_param APP_ENV`. Since Yii3 application templates use environment variables, this is a possible place to set them. In production environment remember to set `APP_ENV` to `prod`." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-webservers/nginx.md +msgid "The Nginx `access_log` and `error_log` directives above don't capture PHP-FPM worker output. See [application logs](general.md#application-logs) for logging configuration." +msgstr "" diff --git a/_translations/po/pt-BR/cookbook_configuring-xdebug.md.po b/_translations/po/pt-BR/cookbook_configuring-xdebug.md.po new file mode 100644 index 00000000..a270cba1 --- /dev/null +++ b/_translations/po/pt-BR/cookbook_configuring-xdebug.md.po @@ -0,0 +1,540 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-05-07 14:37+0000\n" +"PO-Revision-Date: 2026-05-07 14:37+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/cookbook/configuring-xdebug.md +#, no-wrap +msgid "Configuring Xdebug" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md +msgid "Xdebug lets an IDE stop PHP code on breakpoints while the application handles a web request, console command, or test. The IDE listens for debug connections. PHP starts the request and Xdebug connects back to the IDE." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md +msgid "Yii works with the regular Xdebug setup. Configure Xdebug for the PHP runtime that executes the code and make sure the IDE can map runtime paths to project files." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/configuring-xdebug.md +#, no-wrap +msgid "Check Xdebug" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md +msgid "Use Xdebug 3. The default debug port is `9003`." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md +msgid "Without Docker, install Xdebug for the PHP executable that runs the application, then check it:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/cookbook/configuring-xdebug.md +#, no-wrap +msgid "" +"php --version\n" +"php --ri xdebug\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md +msgid "In `php.ini` or an Xdebug-specific ini file, enable step debugging:" +msgstr "" + +#. type: Fenced code block (ini) +#: ../src/cookbook/configuring-xdebug.md +#, no-wrap +msgid "" +"xdebug.mode=develop,debug\n" +"xdebug.start_with_request=trigger\n" +"xdebug.client_host=127.0.0.1\n" +"xdebug.client_port=9003\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md +msgid "`trigger` starts a debug session only when a browser extension, query parameter, cookie, or `XDEBUG_SESSION` environment variable asks for it." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md +msgid "With Docker, the Yii application template installs Xdebug in the development image. Enable step debugging in `docker/dev/override.env`:" +msgstr "" + +#. type: Fenced code block (dotenv) +#: ../src/cookbook/configuring-xdebug.md +#, no-wrap +msgid "" +"XDEBUG_MODE=develop,debug\n" +"XDEBUG_CONFIG=\"client_host=host.docker.internal idekey=phpstorm\"\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md +msgid "Keep the default `SERVER_NAME=:80` from `docker/dev/.env` unless the application needs a different Caddy address. Set the browser port with `DEV_PORT` in `docker/.env`:" +msgstr "" + +#. type: Fenced code block (dotenv) +#: ../src/cookbook/configuring-xdebug.md +#, no-wrap +msgid "DEV_PORT=80\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md +msgid "On Linux, Docker must resolve `host.docker.internal` to the host gateway. The current Yii application template already has this in `docker/compose.yml`:" +msgstr "" + +#. type: Fenced code block (yaml) +#: ../src/cookbook/configuring-xdebug.md +#, no-wrap +msgid "" +"services:\n" +" app:\n" +" extra_hosts:\n" +" - \"host.docker.internal:host-gateway\"\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md +msgid "Rebuild the development image if Xdebug was added after the image had already been built:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/cookbook/configuring-xdebug.md +#, no-wrap +msgid "make build\n" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/configuring-xdebug.md +#, no-wrap +msgid "PhpStorm" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md +#, no-wrap +msgid "" +"In **Settings** > **PHP** > **Debug**, check that Xdebug listens on port `9003`. Start listening with\n" +"**Run** > **Start Listening for PHP Debug Connections**.\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md +#, no-wrap +msgid "" +"For browser debugging, install a browser extension from **Settings** > **PHP** > **Debug**. In the extension options,\n" +"use `phpstorm` as the IDE key.\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md +#, no-wrap +msgid "When PHP runs in Docker, configure a server in **Settings** > **PHP** > **Servers**:\n" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/configuring-xdebug.md +msgid "Name: `localhost`." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/configuring-xdebug.md +msgid "Host: `localhost`." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/configuring-xdebug.md +msgid "Port: `80`, or the host port configured by `DEV_PORT`." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/configuring-xdebug.md +msgid "Debugger: `Xdebug`." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/configuring-xdebug.md +msgid "Path mapping: map the project root on the host to `/app` in the container." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md +msgid "Use the project root for the mapping. Mapping only `public/` leaves files under `src/`, `config/`, and `vendor/` unmapped. The path in the container must match the path used by PHP. In the default template, the project is mounted into `/app`." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md +msgid "For local PHP, PhpStorm usually uses the same filesystem paths as PHP, so path mappings are usually unnecessary." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/configuring-xdebug.md +#, no-wrap +msgid "VS Code" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md +msgid "Install the [PHP Debug](https://marketplace.visualstudio.com/items?itemName=xdebug.php-debug) extension." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md +msgid "For PHP that runs on the same filesystem as VS Code, create `.vscode/launch.json`:" +msgstr "" + +#. type: Fenced code block (json) +#: ../src/cookbook/configuring-xdebug.md +#, no-wrap +msgid "" +"{\n" +" \"version\": \"0.2.0\",\n" +" \"configurations\": [\n" +" {\n" +" \"name\": \"Listen for Xdebug\",\n" +" \"type\": \"php\",\n" +" \"request\": \"launch\",\n" +" \"port\": 9003\n" +" }\n" +" ]\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md +msgid "For Docker, add path mappings:" +msgstr "" + +#. type: Fenced code block (json) +#: ../src/cookbook/configuring-xdebug.md +#, no-wrap +msgid "" +"{\n" +" \"version\": \"0.2.0\",\n" +" \"configurations\": [\n" +" {\n" +" \"name\": \"Listen for Xdebug\",\n" +" \"type\": \"php\",\n" +" \"request\": \"launch\",\n" +" \"port\": 9003,\n" +" \"pathMappings\": {\n" +" \"/app\": \"${workspaceFolder}\"\n" +" }\n" +" }\n" +" ]\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md +msgid "Start this configuration before running the web request, command, or test." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/configuring-xdebug.md +#, no-wrap +msgid "Zed" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md +msgid "Install or enable the PHP extension in Zed. It provides the `Xdebug` debug adapter." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md +msgid "Create `.zed/debug.json`:" +msgstr "" + +#. type: Fenced code block (json) +#: ../src/cookbook/configuring-xdebug.md +#, no-wrap +msgid "" +"[\n" +" {\n" +" \"label\": \"PHP: Listen to Xdebug\",\n" +" \"adapter\": \"Xdebug\",\n" +" \"request\": \"launch\",\n" +" \"port\": 9003\n" +" }\n" +"]\n" +msgstr "" + +#. type: Fenced code block (json) +#: ../src/cookbook/configuring-xdebug.md +#, no-wrap +msgid "" +"[\n" +" {\n" +" \"label\": \"PHP: Listen to Xdebug\",\n" +" \"adapter\": \"Xdebug\",\n" +" \"request\": \"launch\",\n" +" \"port\": 9003,\n" +" \"pathMappings\": {\n" +" \"/app\": \"$ZED_WORKTREE_ROOT\"\n" +" }\n" +" }\n" +"]\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md +msgid "Start the configuration with **debugger: start** before running the web request, command, or test. Zed can also load debug configurations from `.vscode/launch.json` when `.zed/debug.json` is absent." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/configuring-xdebug.md +#, no-wrap +msgid "Debug a web request" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md +msgid "Without Docker:" +msgstr "" + +#. type: Bullet: '3. ' +#: ../src/cookbook/configuring-xdebug.md +msgid "Start listening in the IDE." +msgstr "" + +#. type: Bullet: '4. ' +#: ../src/cookbook/configuring-xdebug.md +msgid "Put a breakpoint in an action or middleware." +msgstr "" + +#. type: Bullet: '3. ' +#: ../src/cookbook/configuring-xdebug.md +msgid "Start the built-in server with an Xdebug trigger:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/cookbook/configuring-xdebug.md +#, no-wrap +msgid " ./yii serve --xdebug\n" +msgstr "" + +#. type: Bullet: '4. ' +#: ../src/cookbook/configuring-xdebug.md +msgid "Open or reload the page in the browser." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md +msgid "The `--xdebug` option passes `XDEBUG_MODE=debug XDEBUG_TRIGGER=yes` to the built-in PHP server. If you use another web server, enable debugging with the browser extension and reload the page." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md +msgid "With Docker:" +msgstr "" + +#. type: Bullet: '1. ' +#: ../src/cookbook/configuring-xdebug.md +msgid "Add the Docker Xdebug variables to `docker/dev/override.env`." +msgstr "" + +#. type: Bullet: '2. ' +#: ../src/cookbook/configuring-xdebug.md +msgid "Start or restart the development containers:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/cookbook/configuring-xdebug.md +#, no-wrap +msgid " make up\n" +msgstr "" + +#. type: Bullet: '5. ' +#: ../src/cookbook/configuring-xdebug.md +msgid "Enable debugging in the browser extension and reload the page." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md +msgid "If the IDE accepts a connection and the breakpoint stays inactive, check path mappings first." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/configuring-xdebug.md +#, no-wrap +msgid "Debug a console command" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md +msgid "Without Docker, start the command with an Xdebug trigger:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/cookbook/configuring-xdebug.md +#, no-wrap +msgid "XDEBUG_MODE=debug XDEBUG_SESSION=phpstorm ./yii hello\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md +msgid "With Docker, pass the trigger to the container:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/cookbook/configuring-xdebug.md +#, no-wrap +msgid "" +"docker compose -f docker/compose.yml -f docker/dev/compose.yml run --rm \\\n" +" -e XDEBUG_MODE=debug \\\n" +" -e XDEBUG_SESSION=phpstorm \\\n" +" -e PHP_IDE_CONFIG=serverName=localhost \\\n" +" app ./yii hello\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md +msgid "Use the command name and arguments you need instead of `hello`." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/configuring-xdebug.md +#, no-wrap +msgid "Debug tests" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md +msgid "Without Docker, start the test runner with an Xdebug trigger:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/cookbook/configuring-xdebug.md +#, no-wrap +msgid "XDEBUG_MODE=debug XDEBUG_SESSION=phpstorm vendor/bin/codecept run\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md +msgid "With Docker, configure `docker/test/override.env`:" +msgstr "" + +#. type: Fenced code block (dotenv) +#: ../src/cookbook/configuring-xdebug.md +#, no-wrap +msgid "" +"XDEBUG_MODE=debug,coverage\n" +"XDEBUG_CONFIG=\"client_host=host.docker.internal idekey=phpstorm\"\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md +msgid "Then run the test container with a trigger:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/cookbook/configuring-xdebug.md +#, no-wrap +msgid "" +"docker compose -f docker/compose.yml -f docker/test/compose.yml run --rm \\\n" +" -e XDEBUG_SESSION=phpstorm \\\n" +" -e PHP_IDE_CONFIG=serverName=localhost \\\n" +" app ./vendor/bin/codecept run\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md +msgid "Use `make test` for regular test runs. Use the explicit `docker compose` command when you need to pass debug-only environment variables to one run." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/configuring-xdebug.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/guide/views/asset.md +#, no-wrap +msgid "Troubleshooting" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/configuring-xdebug.md +msgid "The IDE must listen before PHP starts the request." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/configuring-xdebug.md +msgid "Xdebug connects from PHP to the IDE. Allow incoming connections to port `9003` in the host firewall." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/configuring-xdebug.md +msgid "In Docker, `client_host` must be reachable from the container. The Yii template uses `host.docker.internal`." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/configuring-xdebug.md +msgid "For CLI and tests, set `XDEBUG_SESSION=phpstorm` or another trigger accepted by your Xdebug configuration." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/configuring-xdebug.md +msgid "For Docker path mappings, map the host project root to `/app`." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/configuring-xdebug.md +msgid "To inspect connection attempts, temporarily add `log=/app/runtime/xdebug.log` to `XDEBUG_CONFIG`." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/configuring-xdebug.md +#, no-wrap +msgid "See also" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/configuring-xdebug.md +msgid "[Xdebug step debugging](https://xdebug.org/docs/step_debug)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/configuring-xdebug.md +msgid "[PhpStorm Xdebug documentation](https://www.jetbrains.com/help/phpstorm/configuring-xdebug.html)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/configuring-xdebug.md +msgid "[PhpStorm servers and path mappings](https://www.jetbrains.com/help/phpstorm/servers.html)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/configuring-xdebug.md +msgid "[VS Code PHP Debug](https://github.com/xdebug/vscode-php-debug)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/configuring-xdebug.md +msgid "[Zed PHP documentation](https://zed.dev/docs/languages/php#debugging)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/configuring-xdebug.md +msgid "[Docker in application templates](../guide/tutorial/docker.md)" +msgstr "" diff --git a/_translations/po/pt-BR/cookbook_custom-hydrator-type-casters.md.po b/_translations/po/pt-BR/cookbook_custom-hydrator-type-casters.md.po new file mode 100644 index 00000000..35a830db --- /dev/null +++ b/_translations/po/pt-BR/cookbook_custom-hydrator-type-casters.md.po @@ -0,0 +1,773 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-10-15 11:09+0000\n" +"PO-Revision-Date: 2026-10-15 11:09+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/cookbook/custom-hydrator-type-casters.md +#, no-wrap +msgid "Custom hydrator type casters" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "[Yii Hydrator](https://github.com/yiisoft/hydrator) creates objects and fills them with data from arrays. It's used directly and by packages built on top of it:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "[Yii Input HTTP](https://github.com/yiisoft/input-http) fills request input objects from query parameters, request body, and, with the help of [Yii Router](https://github.com/yiisoft/router), route arguments." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "[Yii Form Model](https://github.com/yiisoft/form-model) provides `FormHydrator` that fills form models from submitted data." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "The incoming data is usually \"raw\": HTTP requests, database rows, and queue messages contain strings, numbers, and arrays. Before assigning a value to a property or passing it to a constructor parameter, the hydrator converts it to the declared type. A *type caster* performs this conversion. By writing your own type caster, you teach the hydrator to create your types, such as value objects, from raw data." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/custom-hydrator-type-casters.md +#, no-wrap +msgid "Why custom type casters" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "Out of the box, the hydrator uses a composite type caster with two casters:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "`PhpNativeTypeCaster` casts values to built-in PHP types, such as `int`, `string`, `bool`, and `array`." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "`HydratorTypeCaster` creates nested objects from arrays using the hydrator itself." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "That's enough for DTOs with scalar properties, but not for a rich domain model. Consider a property typed as `UserId`, `Email`, or `Money`. The incoming value is a string, and neither of the default casters knows how to turn it into such an object. So you end up declaring the property as `string` and converting it by hand wherever it's used:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/custom-hydrator-type-casters.md +#, no-wrap +msgid "" +"final class CreatePostForm extends FormModel\n" +"{\n" +" public string $authorId = '';\n" +"}\n" +"\n" +"// In every action that uses the form:\n" +"try {\n" +" $authorId = new UserId($form->authorId);\n" +"} catch (InvalidArgumentException) {\n" +" // Report the error somehow.\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "With a type caster for `UserId`, you can declare the property with its real type. The conversion happens during hydration:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/custom-hydrator-type-casters.md +#, no-wrap +msgid "" +"final class CreatePostForm extends FormModel\n" +"{\n" +" public ?UserId $authorId = null;\n" +"}\n" +"\n" +"// $form->authorId is already an instance of UserId.\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "The conversion logic lives in a single place. Once you register the caster, the hydrator applies it to every property and constructor parameter of the matching type in every object it creates." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "Typical use cases are:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "value objects, such as entity IDs, emails, phone numbers, and money amounts." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "types from third-party libraries, such as UUIDs, dates, or currencies." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "consistent normalization of values, for example, parsing dates in a format specific to your application." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/custom-hydrator-type-casters.md +#, no-wrap +msgid "Anatomy of a type caster" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "A type caster implements `Yiisoft\\Hydrator\\TypeCaster\\TypeCasterInterface` with a single method:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/custom-hydrator-type-casters.md +#, no-wrap +msgid "public function cast(mixed $value, TypeCastContext $context): Result;\n" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "`$value` is the raw value to convert." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "`$context` is a `Yiisoft\\Hydrator\\TypeCaster\\TypeCastContext`. Its `getReflectionType()` method returns the declared type of the target property or constructor parameter. Use it to decide whether the caster supports the target type." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "The method returns a `Yiisoft\\Hydrator\\Result`: `Result::success($convertedValue)` if the conversion succeeded or `Result::fail()` if the caster can't handle the value." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "Follow these rules when writing a type caster:" +msgstr "" + +#. type: Bullet: '1. ' +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "**Check the target type first.** If the declared type isn't the one your caster is responsible for, return `Result::fail()` right away so other casters can handle the value." +msgstr "" + +#. type: Bullet: '2. ' +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "**Handle both named and union types.** PHP represents a nullable type such as `?Email` (or `Email|null`) with `ReflectionNamedType` and `Email|string` with `ReflectionUnionType`. In the latter case, look for your type among its subtypes." +msgstr "" + +#. type: Bullet: '3. ' +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "**Don't handle `null` yourself.** If the value is `null`, just return `Result::fail()`. `PhpNativeTypeCaster` returns `null` for any type that allows it, so a `null` value assigned to `?Email` stays `null`." +msgstr "" + +#. type: Bullet: '4. ' +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "**Accept already converted values.** If the value is already an instance of the target type, return it as is." +msgstr "" + +#. type: Bullet: '5. ' +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "**Fail instead of throwing.** If your caster can't convert the value, for example, a malformed string, return `Result::fail()`. An exception would break the whole hydration." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "Keep in mind what happens when no caster succeeds:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "For a property, the cast fails silently. The hydrator doesn't set the property or report an error, so the property keeps its default value. Reporting the problem to the user is the job of the validation that runs after hydration. See [Null and invalid values](#null-and-invalid-values) for an example." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "For a constructor parameter, the hydrator omits the argument. If the parameter has a default value, it's used. Otherwise, object creation fails with `WrongConstructorArgumentsCountException`, even for a nullable parameter without a default value." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/custom-hydrator-type-casters.md +#, no-wrap +msgid "Registering a type caster" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "Combine type casters with `CompositeTypeCaster`. It tries the casters one by one and uses the result of the first one that succeeds. To add your caster, redefine `TypeCasterInterface` in the DI container configuration, for example, in `config/common/di/hydrator.php`. The `HydratorInterface` implementation from the container uses this chain, as do packages that rely on it, such as Yii Input HTTP:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/custom-hydrator-type-casters.md +#, no-wrap +msgid "" +" static fn() => new CompositeTypeCaster(\n" +" new UuidValueTypeCaster(),\n" +" new PhpNativeTypeCaster(),\n" +" new HydratorTypeCaster(),\n" +" ),\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "Since the first successful result wins, the order matters:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "Put custom casters before `PhpNativeTypeCaster`. Otherwise, for a property declared as `UserId|string`, `PhpNativeTypeCaster` accepts a string as is, and your caster never runs." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "Keep the default casters in the list. `PhpNativeTypeCaster` casts scalar values to built-in types, and `HydratorTypeCaster` creates nested objects from arrays." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "If a caster has dependencies, take it from the container:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/custom-hydrator-type-casters.md +#, no-wrap +msgid "" +" static fn(ContainerInterface $container) => new CompositeTypeCaster(\n" +" $container->get(MoneyTypeCaster::class),\n" +" new PhpNativeTypeCaster(),\n" +" new HydratorTypeCaster(),\n" +" ),\n" +"];\n" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/custom-hydrator-type-casters.md +#, no-wrap +msgid "Registering for form models" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "`FormHydrator` from Yii Form Model doesn't use `TypeCasterInterface`. Its DI configuration creates a dedicated hydrator with its own chain of type casters, so add your caster there as well:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/custom-hydrator-type-casters.md +#, no-wrap +msgid "" +" [\n" +" '__construct()' => [\n" +" 'hydrator' => DynamicReference::to([\n" +" 'class' => Hydrator::class,\n" +" '__construct()' => [\n" +" 'typeCaster' => new CompositeTypeCaster(\n" +" new NullTypeCaster(emptyString: true),\n" +" new UuidValueTypeCaster(),\n" +" new PhpNativeTypeCaster(),\n" +" new NonArrayTypeCaster(),\n" +" new HydratorTypeCaster(),\n" +" ),\n" +" ],\n" +" ]),\n" +" ],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "This definition replaces the one from the package, so keep its type casters. This example uses the list from `config/di.php` of Yii Form Model 1.1. Check it against the version you use. `NullTypeCaster` turns empty strings submitted by forms into `null` for nullable properties, so it stays first." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/custom-hydrator-type-casters.md +#, no-wrap +msgid "Example: UUID value objects" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "Entity IDs often use value objects, such as `UserId`, `PostId`, and `OrderId`, instead of plain strings. Such objects make method signatures self-documenting and prevent passing a post ID where a method expects a user ID. The following example shows how to write a type caster that creates them from UUID strings." +msgstr "" + +#. type: Title ### +#: ../src/cookbook/custom-hydrator-type-casters.md +#, no-wrap +msgid "Value objects" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "All ID value objects extend an abstract `UuidValue` class. The example uses [ramsey/uuid](https://github.com/ramsey/uuid) to validate and generate UUIDs:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/cookbook/custom-hydrator-type-casters.md +#, no-wrap +msgid "composer require ramsey/uuid\n" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/custom-hydrator-type-casters.md +#, no-wrap +msgid "" +"value = Uuid::fromString($value)->toString();\n" +" }\n" +"\n" +" public static function generate(): static\n" +" {\n" +" return new static(Uuid::uuid7()->toString());\n" +" }\n" +"\n" +" public function equals(self $other): bool\n" +" {\n" +" return $other instanceof static && $other->value === $this->value;\n" +" }\n" +"\n" +" public function __toString(): string\n" +" {\n" +" return $this->value;\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "The constructor is final, so `new static()` is safe and creates every child class from a string the same way. A concrete ID is just an empty child class:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/custom-hydrator-type-casters.md +#, no-wrap +msgid "" +"findUuidValueClass($context->getReflectionType());\n" +" if ($class === null) {\n" +" return Result::fail();\n" +" }\n" +"\n" +" if ($value instanceof $class) {\n" +" return Result::success($value);\n" +" }\n" +"\n" +" if (!is_string($value) || !Uuid::isValid($value)) {\n" +" return Result::fail();\n" +" }\n" +"\n" +" return Result::success(new $class($value));\n" +" }\n" +"\n" +" /**\n" +" * Returns the `UuidValue` child class from the declared type, or `null` if there is none or there are several\n" +" * of them, such as in `UserId|PostId`.\n" +" *\n" +" * @return class-string|null\n" +" */\n" +" private function findUuidValueClass(?ReflectionType $type): ?string\n" +" {\n" +" $types = match (true) {\n" +" $type instanceof ReflectionNamedType => [$type],\n" +" $type instanceof ReflectionUnionType => $type->getTypes(),\n" +" default => [],\n" +" };\n" +"\n" +" $classes = [];\n" +" foreach ($types as $subType) {\n" +" if (\n" +" $subType instanceof ReflectionNamedType\n" +" && !$subType->isBuiltin()\n" +" && is_subclass_of($subType->getName(), UuidValue::class)\n" +" ) {\n" +" $classes[] = $subType->getName();\n" +" }\n" +" }\n" +"\n" +" return count($classes) === 1 ? $classes[0] : null;\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "The caster follows the [rules for writing a type caster](#anatomy-of-a-type-caster). It chooses the class to create from the declared type. All IDs share the same UUID format, so a string alone can't tell whether it's a user ID or a post ID. A single caster therefore serves all `UuidValue` child classes, and adding a new ID class doesn't require changes to the caster. For the same reason, the caster fails for a type with several ID classes, such as `UserId|PostId`. There's no way to choose the right one." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "Register `UuidValueTypeCaster` as shown in the [Registering a type caster](#registering-a-type-caster) section, including the [form model configuration](#registering-for-form-models) if you use Yii Form Model." +msgstr "" + +#. type: Title ### +#: ../src/cookbook/custom-hydrator-type-casters.md +#, no-wrap +msgid "Using the value objects" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "Now any class that's populated by the hydrator can declare ID value objects directly." +msgstr "" + +#. type: Title #### +#: ../src/cookbook/custom-hydrator-type-casters.md +#, no-wrap +msgid "Hydrator" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "The same string becomes a different value object depending on the type of the property:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/custom-hydrator-type-casters.md +#, no-wrap +msgid "" +"use App\\Post\\PostId;\n" +"use App\\User\\UserId;\n" +"use Yiisoft\\Hydrator\\HydratorInterface;\n" +"\n" +"final class CommentFilter\n" +"{\n" +" public ?UserId $authorId = null;\n" +" public ?PostId $postId = null;\n" +"}\n" +"\n" +"/** @var HydratorInterface $hydrator */\n" +"$filter = $hydrator->create(CommentFilter::class, [\n" +" 'authorId' => '0192f2a4-7a4b-7c3e-9a1b-3f5c8d2e6a10',\n" +" 'postId' => '0192f2a4-7a4b-7c3e-9a1b-3f5c8d2e6a10',\n" +"]);\n" +"\n" +"// $filter->authorId is UserId, $filter->postId is PostId.\n" +"// $filter->authorId->equals($filter->postId) returns false.\n" +msgstr "" + +#. type: Title #### +#: ../src/cookbook/custom-hydrator-type-casters.md +#, no-wrap +msgid "Request input" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "The [Yii Input HTTP](https://github.com/yiisoft/input-http) package uses the hydrator to fill request input objects, so the same type caster works for query parameters, request body, and route arguments. The `RouteArgument` attribute comes from [Yii Router](https://github.com/yiisoft/router). Extend `AbstractInput` to get the input validated after hydration:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/custom-hydrator-type-casters.md +#, no-wrap +msgid "" +"getValidationResult()->isValid()) {\n" +" // Return an error response.\n" +" }\n" +"\n" +" // $input->id is PostId, $input->authorId is UserId.\n" +" // ...\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title #### +#: ../src/cookbook/custom-hydrator-type-casters.md +#, no-wrap +msgid "Form model" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "`FormHydrator` from [Yii Form Model](https://github.com/yiisoft/form-model) populates form models. Once you [register the caster for form models](#registering-for-form-models), you can declare form properties as value objects too:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/custom-hydrator-type-casters.md +#, no-wrap +msgid "" +"formHydrator->populateFromPostAndValidate($form, $request)) {\n" +" // $form->authorId is UserId.\n" +" // ...\n" +" }\n" +"\n" +" // ...\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/custom-hydrator-type-casters.md +#, no-wrap +msgid "Null and invalid values" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "Here is what happens with a property declared as `?UserId` for different input values:" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-hydrator-type-casters.md +#, no-wrap +msgid "" +"| Input value | Handled by | Property value |\n" +"|------------------------------------------|------------------------|----------------------------------|\n" +"| `'0192f2a4-7a4b-7c3e-9a1b-3f5c8d2e6a10'` | `UuidValueTypeCaster` | `UserId` instance |\n" +"| `null` | `PhpNativeTypeCaster` | `null` |\n" +"| `'not-a-uuid'` | none, all casters fail | default value, `null` in example |\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "The last row is the important one: the hydrator doesn't report the malformed value. With the `Required` rule, validation catches it with the \"cannot be blank\" error. See the [request input](#request-input) and [form model](#form-model) examples. But if the property is optional, an invalid UUID is silently turned into `null` and is indistinguishable from a missing value. If that's not acceptable, keep the raw value for validation: declare the property as `string`, validate its format, and convert it to the value object after validation." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/custom-hydrator-type-casters.md +#, no-wrap +msgid "When to use a type caster" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "A type caster fits well when the conversion:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "depends only on the value and the declared type." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "is the same everywhere in the application." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "doesn't need I/O, such as database queries or HTTP calls." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "Value objects for IDs, emails, and money amounts match all three. Keep the conversion in a dedicated mapper or a domain factory instead when it:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "needs a database lookup, for example, turning an ID into a loaded entity." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "depends on context, such as the current user." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "combines several input fields into one object." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/custom-hydrator-type-casters.md +msgid "differs between use cases." +msgstr "" diff --git a/_translations/po/pt-BR/cookbook_custom-migration-template.md.po b/_translations/po/pt-BR/cookbook_custom-migration-template.md.po new file mode 100644 index 00000000..d2bfc038 --- /dev/null +++ b/_translations/po/pt-BR/cookbook_custom-migration-template.md.po @@ -0,0 +1,238 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-06-05 22:11+0000\n" +"PO-Revision-Date: 2026-06-05 22:11+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/cookbook/custom-migration-template.md +#, no-wrap +msgid "Using a custom migration template" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-migration-template.md +msgid "The `migrate:create` command from `yiisoft/db-migration` generates migration classes from PHP view templates. Use a custom template when your project wants a standard header, strict class shape, comments, helper calls, or team-specific placeholders in every new migration." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-migration-template.md +msgid "This recipe assumes migrations are already configured as described in the [Database migrations](../guide/databases/db-migrations.md) guide." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/custom-migration-template.md +#, no-wrap +msgid "Create a template" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-migration-template.md +msgid "Create `resources/migration-templates/migration.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/custom-migration-template.md +#, no-wrap +msgid "" +"\n" +"\n" +"use Yiisoft\\Db\\Migration\\MigrationBuilder;\n" +"use Yiisoft\\Db\\Migration\\RevertibleMigrationInterface;\n" +"\n" +"final class implements RevertibleMigrationInterface\n" +"{\n" +" public function up(MigrationBuilder $b): void\n" +" {\n" +" // Add forward migration code.\n" +" }\n" +"\n" +" public function down(MigrationBuilder $b): void\n" +" {\n" +" // Add rollback migration code.\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-migration-template.md +msgid "The template is a PHP file that prints the generated migration. For the default `create` command, the most useful variables are `$className` and `$namespace`." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/custom-migration-template.md +#, no-wrap +msgid "Configure the generator" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-migration-template.md +msgid "Create `config/common/di/migration-generator.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/custom-migration-template.md +#, no-wrap +msgid "" +" [\n" +" 'setTemplate()' => [\n" +" 'create',\n" +" dirname(__DIR__, 3) . '/resources/migration-templates/migration.php',\n" +" ],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-migration-template.md +msgid "The `create` key changes the template used by:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/cookbook/custom-migration-template.md +#, no-wrap +msgid "./yii migrate:create audit_log\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-migration-template.md +msgid "The command asks for confirmation and then writes a migration using your template." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-migration-template.md +msgid "If the new DI file is not picked up, rebuild the config merge plan:" +msgstr "" + +#. type: Fenced code block (sh) +#: ../src/cookbook/custom-migration-template.md +#: ../src/cookbook/using-yii-in-third-party-apps.md +#: ../src/guide/structure/designing-packages.md +#: ../src/guide/structure/module.md ../src/guide/structure/package.md +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "composer yii-config-rebuild\n" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/custom-migration-template.md +#, no-wrap +msgid "Configure multiple templates" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-migration-template.md +msgid "`yiisoft/db-migration` supports these template keys:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/custom-migration-template.md +msgid "`create`" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/custom-migration-template.md +msgid "`table`" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/custom-migration-template.md +msgid "`dropTable`" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/custom-migration-template.md +msgid "`addColumn`" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/custom-migration-template.md +msgid "`dropColumn`" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/custom-migration-template.md +msgid "`junction`" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-migration-template.md +msgid "To replace multiple templates at once, use `setTemplates()`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/custom-migration-template.md +#, no-wrap +msgid "" +"use Yiisoft\\Db\\Migration\\Service\\Generate\\CreateService;\n" +"\n" +"return [\n" +" CreateService::class => [\n" +" 'setTemplates()' => [[\n" +" 'create' => dirname(__DIR__, 3) . '/resources/migration-templates/migration.php',\n" +" 'table' => dirname(__DIR__, 3) . '/resources/migration-templates/create-table.php',\n" +" 'dropTable' => dirname(__DIR__, 3) . '/resources/migration-templates/drop-table.php',\n" +" 'addColumn' => dirname(__DIR__, 3) . '/resources/migration-templates/add-column.php',\n" +" 'dropColumn' => dirname(__DIR__, 3) . '/resources/migration-templates/drop-column.php',\n" +" 'junction' => dirname(__DIR__, 3) . '/resources/migration-templates/create-junction.php',\n" +" ]],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-migration-template.md +msgid "For table-oriented templates, copy the corresponding file from `vendor/yiisoft/db-migration/resources/views/` and adjust it. Those templates receive additional variables such as `$table`, `$columns`, `$foreignKeys`, and `$tableComment`." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/custom-migration-template.md +#, no-wrap +msgid "Keep templates maintainable" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-migration-template.md +msgid "Keep generated migrations independent from current application services. A migration may run years later, after service APIs have changed. Put stable schema operations in the generated class and leave business logic in console commands or application services." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/custom-migration-template.md +msgid "Do not edit templates under `vendor/`. Copy them into your project and configure `CreateService` to use the copies." +msgstr "" diff --git a/_translations/po/pt-BR/cookbook_deployment_angie-docker-proxy.md.po b/_translations/po/pt-BR/cookbook_deployment_angie-docker-proxy.md.po new file mode 100644 index 00000000..421f3aa9 --- /dev/null +++ b/_translations/po/pt-BR/cookbook_deployment_angie-docker-proxy.md.po @@ -0,0 +1,432 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-09-25 14:35+0000\n" +"PO-Revision-Date: 2026-09-25 14:35+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/cookbook/deployment/angie-docker-proxy.md +#, no-wrap +msgid "Deploying Yii applications with Angie Docker Proxy" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "[Angie Docker Proxy](https://hub.docker.com/r/angiesoftware/proxy) is a small reverse proxy for Docker Compose projects. It runs in a separate container alongside the applications, reads the Docker API through the Docker socket, discovers containers using the `VIRTUAL_HOST` and `VIRTUAL_PORT` environment variables, generates the Angie configuration, and automatically obtains TLS certificates using ACME." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "This approach is useful when you need to run several web applications on one server and enable HTTPS for them without manually editing the reverse proxy configuration for each domain." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "In this example, we'll connect a containerized Yii application to Angie Docker Proxy and configure automatic HTTPS." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "This guide assumes that your Yii application is already packaged as a Docker image and accepts HTTP requests on port 80. Building and configuring the application image is outside the scope of this guide." +msgstr "" + +#. type: Fenced code block (mermaid) +#: ../src/cookbook/deployment/angie-docker-proxy.md +#, no-wrap +msgid "" +"graph LR\n" +" A[Internet] --> B[Reverse Proxy: Angie]\n" +" B --> C[Yii application]\n" +" B --> D[Another application]\n" +"\n" +" subgraph Docker Compose Project\n" +" B\n" +" C\n" +" D\n" +" end\n" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/angie-docker-proxy.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/preface.md +#, no-wrap +msgid "Prerequisites" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "A server with a fresh Linux distribution." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "A domain name pointing to your server's IP address." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "Docker and Docker Compose." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "Open TCP ports `80` and `443`." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "SSH access to your server." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "Basic knowledge of Docker and command-line tools." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/angie-docker-proxy.md +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "Project structure" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "The example requires a single Docker Compose configuration:" +msgstr "" + +#. type: Fenced code block (text) +#: ../src/cookbook/deployment/angie-docker-proxy.md +#, no-wrap +msgid "" +"yii-angie-demo/\n" +"└── docker-compose.yml\n" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/angie-docker-proxy.md +#, no-wrap +msgid "Configuring Docker Compose" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "Create `docker-compose.yml` with the following configuration. Replace:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "`admin@example.com` with your email address;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "`registry.example.com/yii-app:1.0.0` with your application image;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "`example-demo.example.com` with the domain pointing to your server." +msgstr "" + +#. type: Fenced code block (yaml) +#: ../src/cookbook/deployment/angie-docker-proxy.md +#, no-wrap +msgid "" +"services:\n" +" angie-proxy:\n" +" image: angiesoftware/proxy:latest\n" +" environment:\n" +" - ANGIE_ACME_EMAIL=admin@example.com\n" +" - ANGIE_ACME_URL=https://acme-v02.api.letsencrypt.org/directory\n" +" - ANGIE_RESOLVER=1.1.1.1 8.8.8.8\n" +" - ANGIE_RESOLVER_VALID=300s\n" +" - ANGIE_PROXY_NETWORK=proxy\n" +" ports:\n" +" - \"80:80\"\n" +" - \"443:443\"\n" +" volumes:\n" +" - /var/run/docker.sock:/tmp/docker.sock:ro\n" +" - angie_acme:/var/lib/angie/acme\n" +" networks:\n" +" - proxy\n" +"\n" +" yii-app:\n" +" image: registry.example.com/yii-app:1.0.0\n" +" environment:\n" +" - VIRTUAL_HOST=example-demo.example.com\n" +" - VIRTUAL_PORT=80\n" +" networks:\n" +" - proxy\n" +"\n" +"networks:\n" +" proxy:\n" +" name: proxy\n" +"\n" +"volumes:\n" +" angie_acme:\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "`VIRTUAL_HOST` is the application's public domain." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "`VIRTUAL_PORT` is the container's internal port to which Angie should proxy requests." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "Angie Docker Proxy automatically discovers `VIRTUAL_HOST` and `VIRTUAL_PORT` from the environment variables and issues certificates using the Angie ACME module and Let's Encrypt." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/angie-docker-proxy.md +#, no-wrap +msgid "Starting the services" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "Start the proxy and application containers:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/angie-docker-proxy.md +#, no-wrap +msgid "docker compose up -d\n" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/angie-docker-proxy.md +#, no-wrap +msgid "Adding another application" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "To expose another application, add it to `services` in `docker-compose.yml` and attach it to the `proxy` network:" +msgstr "" + +#. type: Fenced code block (yaml) +#: ../src/cookbook/deployment/angie-docker-proxy.md +#, no-wrap +msgid "" +"services:\n" +" second-app:\n" +" image: traefik/whoami\n" +" environment:\n" +" - VIRTUAL_HOST=example-demo2.example.com\n" +" - VIRTUAL_PORT=80\n" +" networks:\n" +" - proxy\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "Apply the changes:" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/angie-docker-proxy.md +#, no-wrap +msgid "How it works" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "Angie Docker Proxy monitors the Docker API and discovers containers configured with `VIRTUAL_HOST` and `VIRTUAL_PORT`. It generates the Angie configuration, obtains TLS certificates using ACME, and forwards incoming requests to the corresponding containers through the shared Docker network." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "When containers are added, removed, or updated, the proxy regenerates its configuration and performs a graceful reload. Existing connections continue to be handled while the updated configuration is applied." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "For configuration options and implementation details, see the [Angie Docker Proxy documentation](https://hub.docker.com/r/angiesoftware/proxy)." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/angie-docker-proxy.md +#, no-wrap +msgid "Verification" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "Check the containers:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/angie-docker-proxy.md +#, no-wrap +msgid "docker compose ps\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "Check the HTTP redirect:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/angie-docker-proxy.md +#, no-wrap +msgid "curl -I http://example-demo.example.com/\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "Expected result:" +msgstr "" + +#. type: Fenced code block (text) +#: ../src/cookbook/deployment/angie-docker-proxy.md +#, no-wrap +msgid "" +"HTTP/1.1 301 Moved Permanently\n" +"Location: https://example-demo.example.com/\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "Check HTTPS:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/angie-docker-proxy.md +#, no-wrap +msgid "curl -I https://example-demo.example.com/\n" +msgstr "" + +#. type: Fenced code block (text) +#: ../src/cookbook/deployment/angie-docker-proxy.md +#, no-wrap +msgid "" +"HTTP/1.1 200 OK\n" +"Server: Angie/...\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "Check the certificate:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/angie-docker-proxy.md +#, no-wrap +msgid "" +"echo | openssl s_client \\\n" +" -connect example-demo.example.com:443 \\\n" +" -servername example-demo.example.com 2>/dev/null \\\n" +" | openssl x509 -noout -issuer -subject -dates\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "Expected issuer:" +msgstr "" + +#. type: Fenced code block (text) +#: ../src/cookbook/deployment/angie-docker-proxy.md +#, no-wrap +msgid "Let's Encrypt\n" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/angie-docker-proxy.md +#, no-wrap +msgid "Logs" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "Proxy logs:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/angie-docker-proxy.md +#, no-wrap +msgid "docker compose logs -f angie-proxy\n" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/angie-docker-proxy.md +#, no-wrap +msgid "Stopping the services" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "Stop the services:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/angie-docker-proxy.md +#, no-wrap +msgid "docker compose down\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "Stop the services and remove the certificates:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/angie-docker-proxy.md +#, no-wrap +msgid "docker compose down -v\n" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/angie-docker-proxy.md +#, no-wrap +msgid "Limitations" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "This setup is intended for Docker Compose. Kubernetes doesn't expose workloads through the Docker API and requires an Ingress or Gateway API controller. Docker Swarm also uses the Docker API, but Swarm deployment isn't covered in this guide." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/angie-docker-proxy.md +#, no-wrap +msgid "For more information" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "[Angie Docker Proxy documentation](https://hub.docker.com/r/angiesoftware/proxy)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "[Yii Application Template](https://github.com/yiisoft/app)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "[Docker in Yii Application Templates](https://yiisoft.github.io/docs/guide/tutorial/docker.html)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/angie-docker-proxy.md +msgid "[Docker Compose documentation](https://docs.docker.com/compose/)" +msgstr "" diff --git a/_translations/po/pt-BR/cookbook_deployment_autoscaling.md.po b/_translations/po/pt-BR/cookbook_deployment_autoscaling.md.po new file mode 100644 index 00000000..a9fc896b --- /dev/null +++ b/_translations/po/pt-BR/cookbook_deployment_autoscaling.md.po @@ -0,0 +1,336 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-06-02 22:17+0000\n" +"PO-Revision-Date: 2026-06-02 22:17+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/cookbook/deployment/autoscaling.md +#, no-wrap +msgid "Configuring an application for autoscaling" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/autoscaling.md +msgid "Autoscaling works when any application instance can handle any request and can be added or removed without special local state. In Yii applications this mostly means keeping runtime state outside the container or VM, making health checks cheap, and running migrations and workers separately from web replicas." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/autoscaling.md +#, no-wrap +msgid "Keep web instances stateless" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/autoscaling.md +msgid "Do not store user-visible state on the local filesystem of a web instance. Local files disappear when an instance is replaced and are not visible to other replicas." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/autoscaling.md +msgid "Move these resources to shared services:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/autoscaling.md +msgid "Sessions: use a shared session handler when users can move between replicas. See [Sessions](../../guide/runtime/sessions.md) and prefer closing sessions early." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/autoscaling.md +msgid "Cache: use Redis, Memcached, database, or another shared PSR-16 cache backend for data that must be consistent across replicas. See [Data caching](../../guide/caching/data.md)." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/autoscaling.md +msgid "Uploads: store files in object storage, a shared volume, or a service dedicated to file storage. Local `runtime` or `public/uploads` directories are safe only for temporary files." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/autoscaling.md +msgid "Generated assets: build them into the image or publish them to shared storage/CDN during deployment." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/autoscaling.md +msgid "Logs: write to stdout/stderr or a central log target. Do not depend on files inside a short-lived instance." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/autoscaling.md +msgid "Sticky sessions can reduce immediate pressure, but they are not a substitute for shared state. A replacement instance or deployment rollout still breaks local session and upload storage." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/autoscaling.md +#, no-wrap +msgid "Add health endpoints" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/autoscaling.md +msgid "Use a cheap liveness endpoint for the load balancer or orchestrator:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/deployment/autoscaling.md +#, no-wrap +msgid "" +"responseFactory->createResponse(Status::NO_CONTENT);\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/autoscaling.md +msgid "Register it in `config/common/routes.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/deployment/autoscaling.md +#, no-wrap +msgid "" +"use App\\Web\\Health\\HealthCheckAction;\n" +"use Yiisoft\\Router\\Route;\n" +"\n" +"return [\n" +" // ...\n" +" Route::get('/healthz')\n" +" ->action(HealthCheckAction::class)\n" +" ->name('healthz'),\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/autoscaling.md +msgid "Keep this endpoint independent from the database and external APIs. It should answer whether the PHP process can accept requests, not whether every dependency is healthy." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/autoscaling.md +msgid "If your platform supports readiness checks, add a separate endpoint such as `/readyz` for dependencies that must be available before routing traffic to a new instance. Keep it bounded with short timeouts. A slow readiness check can make a traffic spike worse." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/autoscaling.md +#, no-wrap +msgid "Configure runtime paths" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/autoscaling.md +msgid "The `runtime` directory should contain disposable process-local files only: logs before shipping, cache files that can be rebuilt, temporary upload chunks, locks scoped to one instance, and debug artifacts." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/autoscaling.md +msgid "For autoscaled deployments:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/autoscaling.md +msgid "mount `runtime` as an instance-local writable volume or create it during image startup;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/autoscaling.md +msgid "do not store permanent uploaded files in `runtime`;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/autoscaling.md +msgid "do not use local file locks for jobs that must be unique across all replicas;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/autoscaling.md +msgid "clear or ignore local runtime cache during rollouts." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/autoscaling.md +msgid "When a command or worker must be unique globally, use a database lock, Redis lock, queue semantics, or run it as a single scheduled job outside the web autoscaling group." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/autoscaling.md +#, no-wrap +msgid "Run migrations once" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/autoscaling.md +msgid "Do not run `./yii migrate` from every web instance during startup. Multiple replicas starting at the same time can compete for locks, slow down boot, or partially deploy incompatible schema." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/autoscaling.md +msgid "Run migrations from one deployment job or a dedicated console container before or during rollout:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/cookbook/deployment/autoscaling.md +#, no-wrap +msgid "APP_ENV=prod php ./yii migrate --no-interaction\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/autoscaling.md +msgid "For zero-downtime deployments, use an expand-and-contract migration flow. See [Applying migrations during rolling updates](rolling-update-migrations.md)." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/autoscaling.md +#, no-wrap +msgid "Separate web, workers, and scheduled jobs" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/autoscaling.md +msgid "Scale web replicas for request traffic. Scale queue workers for queue depth or processing latency. Run scheduled jobs from one scheduler, not from every web replica." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/autoscaling.md +msgid "Use the same application image when practical, but different entry points:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/cookbook/deployment/autoscaling.md +#, no-wrap +msgid "" +"php ./yii queue:listen\n" +"php ./yii app:send-digests --no-interaction\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/autoscaling.md +msgid "Make workers and scheduled commands idempotent. A deployment may stop a worker after it started processing a message, and the queue may deliver it again." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/autoscaling.md +#, no-wrap +msgid "Use environment-specific configuration" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/autoscaling.md +msgid "Keep secrets and per-environment values out of the image:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/autoscaling.md +msgid "database DSN, username, and password;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/autoscaling.md +msgid "cache/session backend addresses;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/autoscaling.md +msgid "cookie validation keys and encryption keys;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/autoscaling.md +msgid "mail, queue, and object-storage credentials;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/autoscaling.md +msgid "public base URL and trusted proxy settings." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/autoscaling.md +msgid "Load them through environment variables or environment-specific Yii config files. Every replica of the same release should receive the same configuration values, except for platform-provided instance metadata." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/autoscaling.md +#, no-wrap +msgid "Capacity checklist" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/autoscaling.md +msgid "Before enabling autoscaling, verify that:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/autoscaling.md +msgid "a request can be served correctly after the previous request went to another replica;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/autoscaling.md +msgid "login and flash messages work without sticky sessions;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/autoscaling.md +msgid "uploaded files remain available after the handling instance is removed;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/autoscaling.md +msgid "cache misses on one instance do not corrupt or hide data on another instance;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/autoscaling.md +msgid "migrations are run by exactly one deployment step;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/autoscaling.md +msgid "background workers and scheduled commands are not multiplied accidentally;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/autoscaling.md +msgid "health checks are fast and do not overload the database;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/autoscaling.md +msgid "logs and metrics identify the application version and instance;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/autoscaling.md +msgid "shutdown is graceful enough for your web server and queue worker timeouts." +msgstr "" diff --git a/_translations/po/pt-BR/cookbook_deployment_docker-swarm-caddy.md.po b/_translations/po/pt-BR/cookbook_deployment_docker-swarm-caddy.md.po new file mode 100644 index 00000000..532440e6 --- /dev/null +++ b/_translations/po/pt-BR/cookbook_deployment_docker-swarm-caddy.md.po @@ -0,0 +1,1102 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-09-25 14:35+0000\n" +"PO-Revision-Date: 2026-09-25 14:35+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/cookbook/configuring-xdebug.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/guide/views/asset.md +#, no-wrap +msgid "Troubleshooting" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/angie-docker-proxy.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/preface.md +#, no-wrap +msgid "Prerequisites" +msgstr "" + +#. type: Title # +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#, no-wrap +msgid "Deploying Yii applications to Docker Swarm and Caddy" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +msgid "This guide walks you through deploying a Yii application to [Docker Swarm](https://docs.docker.com/engine/swarm/) starting from a blank server, using [Caddy](https://caddyserver.com/) as a reverse proxy and deploying from a container registry ([Forgejo](https://forgejo.org/) or [Gitea](https://about.gitea.com/))." +msgstr "" + +#. type: Fenced code block (mermaid) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#, no-wrap +msgid "" +"graph LR\n" +" A[Internet] --> B[Reverse Proxy: Caddy]\n" +" B --> C[app1.example.com]\n" +" B --> D[app2.example.com]\n" +" \n" +" subgraph Docker Swarm Cluster\n" +" B\n" +" C\n" +" D\n" +" end\n" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "A server with a fresh installation of a Linux distribution (Ubuntu 22.04 LTS or later recommended)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "A domain name pointing to your server's IP address" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "SSH access to your server" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Basic knowledge of Docker and command-line tools" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Server preparation" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Install Docker" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "For installation instructions, see the [official Docker documentation](https://docs.docker.com/engine/install/ubuntu/)." +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Initialize Docker Swarm" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Initialize your server as a Docker Swarm manager:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "docker swarm init --advertise-addr \n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Replace `` with your server's public IP address.\n" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Set up the reverse proxy network" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Create a dedicated overlay network for reverse proxy to communicate with your services:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "docker network create --driver=overlay reverse_proxy_public\n" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#, no-wrap +msgid "Setting up Caddy as reverse proxy" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +msgid "To deploy Caddy as reverse proxy create a file `caddy-stack.yml`:" +msgstr "" + +#. type: Fenced code block (yaml) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#, no-wrap +msgid "" +"services:\n" +" caddy:\n" +" image: lucaslorentz/caddy-docker-proxy:ci-alpine\n" +" ports:\n" +" - \"80:80\"\n" +" - \"443:443\"\n" +" volumes:\n" +" - /var/run/docker.sock:/var/run/docker.sock\n" +" - caddy_data:/data\n" +" networks:\n" +" - reverse_proxy_public\n" +"\n" +"volumes:\n" +" caddy_data:\n" +"\n" +"networks:\n" +" reverse_proxy_public:\n" +" external: true\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +msgid "Deploy Caddy:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#, no-wrap +msgid "docker stack deploy -c caddy-stack.yml caddy\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +msgid "Caddy automatically discovers services with Caddy labels and sets up HTTPS using Let's Encrypt. Yii3 application templates are using Caddy labels by default:" +msgstr "" + +#. type: Fenced code block (yaml) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#, no-wrap +msgid "" +"deploy:\n" +" labels:\n" +" - caddy: ${PROD_HOST:-app.example.com}\n" +" - caddy.reverse_proxy: \"{{upstreams 80}}\"\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#, no-wrap +msgid "" +"> [!IMPORTANT]\n" +"> Make sure your domain DNS records are configured and pointing to your server before deploying services with\n" +"> Caddy labels, as Let's Encrypt requires domain validation.\n" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Setting up a container registry" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "You need a container registry to store your Docker images. Choose one of the following options." +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Option 1: Using Forgejo" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "To deploy Forgejo create a file `forgejo-stack.yml`:" +msgstr "" + +#. type: Fenced code block (yaml) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#, no-wrap +msgid "" +"services:\n" +" forgejo:\n" +" image: codeberg.org/forgejo/forgejo:1.21\n" +" ports:\n" +" - \"3000:3000\"\n" +" volumes:\n" +" - forgejo_data:/data\n" +" networks:\n" +" - reverse_proxy_public\n" +" deploy:\n" +" labels:\n" +" - \"caddy=git.example.com\"\n" +" - \"caddy.reverse_proxy={{upstreams 3000}}\"\n" +"\n" +"volumes:\n" +" forgejo_data:\n" +"\n" +"networks:\n" +" reverse_proxy_public:\n" +" external: true\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Deploy Forgejo:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "docker stack deploy -c forgejo-stack.yml forgejo\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Replace `git.example.com` with your desired subdomain." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +msgid "After deployment, access Forgejo at `https://git.example.com` and complete the initial setup. Make sure to enable the container registry in the settings." +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Option 2: Using Gitea" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "To deploy Gitea create a file `gitea-stack.yml`:" +msgstr "" + +#. type: Fenced code block (yaml) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#, no-wrap +msgid "" +"services:\n" +" gitea:\n" +" image: gitea/gitea:latest\n" +" ports:\n" +" - \"3000:3000\"\n" +" volumes:\n" +" - gitea_data:/data\n" +" networks:\n" +" - reverse_proxy_public\n" +" deploy:\n" +" labels:\n" +" - \"caddy=git.example.com\"\n" +" - \"caddy.reverse_proxy={{upstreams 3000}}\"\n" +"\n" +"volumes:\n" +" gitea_data:\n" +"\n" +"networks:\n" +" reverse_proxy_public:\n" +" external: true\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Deploy Gitea:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "docker stack deploy -c gitea-stack.yml gitea\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "After deployment, access Gitea at `https://git.example.com` and complete the initial setup. Make sure to enable the container registry in the settings." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Configuring your Yii application" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Update the Makefile configuration" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "The [Yii application template](https://github.com/yiisoft/app) includes a Makefile with deployment commands. Update the `docker/.env` file in your project:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "" +"STACK_NAME=myapp\n" +"\n" +"#\n" +"# Production\n" +"#\n" +"\n" +"PROD_HOST=app.example.com\n" +"PROD_SSH=\"ssh://user@your-server-ip\"\n" +"\n" +"IMAGE=git.example.com/username/myapp\n" +"IMAGE_TAG=latest\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Replace the values: - `STACK_NAME`: A unique name for your application stack - `PROD_HOST`: The domain name where your app will be accessible - `PROD_SSH`: SSH connection string to your server (format: `ssh://user@host`) - `IMAGE`: Full path to your container image in the registry - `IMAGE_TAG`: Image tag, typically `latest` or a version number" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Configure the production environment" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Update `docker/prod/.env` with your production environment variables:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "" +"APP_ENV=prod\n" +"YII_DEBUG=false\n" +"YII_ENV=prod\n" +"\n" +"# Database configuration\n" +"DB_HOST=db\n" +"DB_NAME=myapp\n" +"DB_USER=myapp\n" +"DB_PASSWORD=secure_password_here\n" +"\n" +"# Add other environment-specific variables\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "" +"> [!WARNING]\n" +"> Never commit sensitive credentials to version control. Use `docker/prod/override.env` for sensitive values and add it to `.gitignore`.\n" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Review the production Docker Compose configuration" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +msgid "The default `docker/prod/compose.yml` includes:" +msgstr "" + +#. type: Fenced code block (yaml) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#, no-wrap +msgid "" +"services:\n" +" app:\n" +" image: ${IMAGE}:${IMAGE_TAG}\n" +" networks:\n" +" - reverse_proxy_public\n" +" volumes:\n" +" - runtime:/app/runtime\n" +" - caddy_data:/data\n" +" - caddy_config:/config\n" +" env_file:\n" +" - path: ./prod/.env\n" +" - path: ./prod/override.env\n" +" required: false\\\n" +" environment:\n" +" CADDY_EXTRA_CONFIG: 'auto_https off'\n" +" deploy:\n" +" replicas: 2\n" +" update_config:\n" +" delay: 10s\n" +" parallelism: 1\n" +" order: start-first\n" +" failure_action: rollback\n" +" monitor: 10s\n" +" rollback_config:\n" +" parallelism: 0\n" +" order: stop-first\n" +" restart_policy:\n" +" condition: on-failure\n" +" delay: 5s\n" +" max_attempts: 3\n" +" window: 120s\n" +" labels:\n" +" caddy: ${PROD_HOST:-app.example.com}\n" +" caddy.reverse_proxy: \"{{upstreams 80}}\"\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "" +"This configuration:\n" +"- Runs 2 replicas for high availability\n" +"- Uses a rolling update strategy with automatic rollback on failure\n" +"- Configures `labels` for automatic HTTPS on the reverse proxy\n" +"- Disables obtaining of HTTPs certificates on the container itself\n" +" since proxy communicates with the container via HTTP. That is `auto_https off`.\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "If you need a database, add it to the stack:" +msgstr "" + +#. type: Fenced code block (yaml) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "" +"services:\n" +" app:\n" +" # ... existing configuration ...\n" +" \n" +" db:\n" +" image: postgres:18-alpine\n" +" environment:\n" +" POSTGRES_DB: myapp\n" +" POSTGRES_USER: myapp\n" +" POSTGRES_PASSWORD_FILE: /run/secrets/db_password\n" +" POSTGRES_INITDB_ARGS: \"--locale-provider=icu --icu-locale=und --encoding=UTF8\"\n" +" volumes:\n" +" - db_data:/var/lib/postgresql\n" +" networks:\n" +" - reverse_proxy_public\n" +" deploy:\n" +" placement:\n" +" constraints:\n" +" - node.role == manager\n" +" secrets:\n" +" - db_password\n" +"\n" +"volumes:\n" +" runtime:\n" +" db_data:\n" +"\n" +"secrets:\n" +" db_password:\n" +" external: true\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Create the database password secret on the server:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "echo \"your_secure_password\" | docker secret create db_password -\n" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Building and pushing the image" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Set up Docker login on your local machine" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Configure Docker to authenticate with your container registry:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "docker login git.example.com\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Enter your username and password when prompted." +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Build the production image" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Use the Makefile to build your production image:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "make prod-build\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "This runs the command defined in the Makefile:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "docker build --file docker/Dockerfile --target prod --pull -t ${IMAGE}:${IMAGE_TAG} .\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "The Dockerfile uses a multi-stage build: 1. Installs Composer dependencies in a builder stage 2. Creates a minimal production image with only the necessary files 3. Runs as a non-root user (`www-data`)" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Push the image to the registry" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Push your built image to the container registry:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "make prod-push\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "This executes:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "docker push ${IMAGE}:${IMAGE_TAG}\n" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Deploying to Docker Swarm" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Configure SSH access" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Set up SSH key-based authentication to your server:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "" +"# Generate SSH key (if you don't have one)\n" +"ssh-keygen -t ed25519 -C \"your_email@example.com\"\n" +"\n" +"# Copy the key to your server\n" +"ssh-copy-id user@your-server-ip\n" +"\n" +"# Add the SSH host to your SSH config (~/.ssh/config)\n" +"cat >> ~/.ssh/config << EOF\n" +"Host docker-web\n" +" HostName your-server-ip\n" +" User user\n" +" IdentityFile ~/.ssh/id_ed25519\n" +"EOF\n" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Set up Docker context" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Create a Docker context for remote deployment:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "docker context create swarm-prod --docker \"host=ssh://docker-web\"\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Alternatively, configure the `DOCKER_HOST` environment variable:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "export DOCKER_HOST=ssh://docker-web\n" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Deploy the application" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Deploy your application stack to Docker Swarm:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "make prod-deploy\n" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "docker -H ${PROD_SSH} stack deploy --prune --detach=false --with-registry-auth -c docker/compose.yml -c docker/prod/compose.yml ${STACK_NAME}\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "The `--with-registry-auth` flag ensures the Swarm nodes can pull images from your private registry." +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Verify the deployment" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Check the status of your services:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "" +"docker -H ssh://docker-web service ls\n" +"docker -H ssh://docker-web service ps ${STACK_NAME}_app\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "View logs:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "docker -H ssh://docker-web service logs ${STACK_NAME}_app\n" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Monitoring and maintenance" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "View service logs" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "" +"# View all logs\n" +"docker -H ssh://docker-web service logs -f ${STACK_NAME}_app\n" +"\n" +"# View logs from the last 100 lines\n" +"docker -H ssh://docker-web service logs --tail 100 ${STACK_NAME}_app\n" +"\n" +"# View logs with timestamps\n" +"docker -H ssh://docker-web service logs -t ${STACK_NAME}_app\n" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Scale the application" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Adjust the number of replicas:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "docker -H ssh://docker-web service scale ${STACK_NAME}_app=3\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Or update the `replicas` value in `docker/prod/compose.yml` and redeploy." +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Resource limits" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Add resource limits to prevent containers from consuming all server resources. Update `docker/prod/compose.yml`:" +msgstr "" + +#. type: Fenced code block (yaml) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "" +"services:\n" +" app:\n" +" # ... existing configuration ...\n" +" deploy:\n" +" resources:\n" +" limits:\n" +" cpus: '0.5'\n" +" memory: 512M\n" +" reservations:\n" +" cpus: '0.25'\n" +" memory: 256M\n" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/disabling-csrf-protection.md +#, no-wrap +msgid "Security considerations" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Use Docker secrets for sensitive data" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Instead of environment variables, use Docker secrets for sensitive information:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "" +"# Create secrets\n" +"echo \"database_password\" | docker secret create db_password -\n" +"echo \"api_key\" | docker secret create api_key -\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Update `docker/prod/compose.yml`:" +msgstr "" + +#. type: Fenced code block (yaml) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "" +"services:\n" +" app:\n" +" secrets:\n" +" - db_password\n" +" - api_key\n" +"\n" +"secrets:\n" +" db_password:\n" +" external: true\n" +" api_key:\n" +" external: true\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Access secrets in your application at `/run/secrets/secret_name`." +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Set up a firewall" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Configure UFW (Uncomplicated Firewall) on your server:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "" +"# Allow SSH\n" +"sudo ufw allow 22/tcp\n" +"\n" +"# Allow HTTP and HTTPS\n" +"sudo ufw allow 80/tcp\n" +"sudo ufw allow 443/tcp\n" +"\n" +"# Allow Docker Swarm ports (if you plan to add more nodes)\n" +"sudo ufw allow 2377/tcp\n" +"sudo ufw allow 7946/tcp\n" +"sudo ufw allow 7946/udp\n" +"sudo ufw allow 4789/udp\n" +"\n" +"# Enable the firewall\n" +"sudo ufw enable\n" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Keep the system updated" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Regularly update your server and Docker:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "" +"# Update system packages\n" +"sudo apt-get update && sudo apt-get upgrade -y\n" +"\n" +"# Update Docker images\n" +"docker -H ssh://docker-web service update --image ${IMAGE}:${IMAGE_TAG} ${STACK_NAME}_app\n" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Service won't start" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Check service events and logs:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "" +"docker -H ssh://docker-web service ps ${STACK_NAME}_app --no-trunc\n" +"docker -H ssh://docker-web service logs ${STACK_NAME}_app\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Common issues: - **Image pull errors**: Verify registry authentication with `docker -H ssh://docker-web login` - **Port conflicts**: Ensure no other services are using ports 80/443 - **Resource constraints**: Check available resources with `docker -H ssh://docker-web node ls`" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "SSL certificate issues" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +msgid "If Caddy can't obtain certificates: - Verify DNS is pointing to your server - Check that ports 80 and 443 are accessible from the internet - Ensure the email in the Let's Encrypt configuration is valid - Check logs: `docker -H ssh://docker-web service logs caddy`" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Container registry connection issues" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Test registry connectivity:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "" +"# From your local machine\n" +"docker pull git.example.com/username/myapp:latest\n" +"\n" +"# From the server\n" +"docker -H ssh://docker-web pull git.example.com/username/myapp:latest\n" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/guide/start/forms.md ../src/guide/start/hello.md +#, no-wrap +msgid "Summary" +msgstr "Resumo" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +msgid "You've successfully deployed a Yii application to Docker Swarm with: - A container registry (Forgejo or Gitea) - Automatic HTTPS via Caddy - Zero-downtime deployments with rolling updates - High availability with multiple replicas" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "The Makefile commands simplify the deployment workflow: - `make prod-build` - Build the production image - `make prod-push` - Push to the registry - `make prod-deploy` - Deploy to Docker Swarm" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +msgid "For more information, see: - [Yii Application Template](https://github.com/yiisoft/app) - [Docker Swarm Documentation](https://docs.docker.com/engine/swarm/) - [Caddy Docker Proxy](https://github.com/lucaslorentz/caddy-docker-proxy)" +msgstr "" diff --git a/_translations/po/pt-BR/cookbook_deployment_docker-swarm-traefik.md.po b/_translations/po/pt-BR/cookbook_deployment_docker-swarm-traefik.md.po new file mode 100644 index 00000000..167d424d --- /dev/null +++ b/_translations/po/pt-BR/cookbook_deployment_docker-swarm-traefik.md.po @@ -0,0 +1,1100 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-05-07 14:37+0000\n" +"PO-Revision-Date: 2026-05-07 14:37+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/cookbook/configuring-xdebug.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/guide/views/asset.md +#, no-wrap +msgid "Troubleshooting" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/preface.md +#, no-wrap +msgid "Prerequisites" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "A server with a fresh installation of a Linux distribution (Ubuntu 22.04 LTS or later recommended)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "A domain name pointing to your server's IP address" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "SSH access to your server" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Basic knowledge of Docker and command-line tools" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Server preparation" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Install Docker" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "For installation instructions, see the [official Docker documentation](https://docs.docker.com/engine/install/ubuntu/)." +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Initialize Docker Swarm" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Initialize your server as a Docker Swarm manager:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "docker swarm init --advertise-addr \n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Replace `` with your server's public IP address.\n" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Set up the reverse proxy network" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Create a dedicated overlay network for reverse proxy to communicate with your services:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "docker network create --driver=overlay reverse_proxy_public\n" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Setting up a container registry" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "You need a container registry to store your Docker images. Choose one of the following options." +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Option 1: Using Forgejo" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "To deploy Forgejo create a file `forgejo-stack.yml`:" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Deploy Forgejo:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "docker stack deploy -c forgejo-stack.yml forgejo\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Replace `git.example.com` with your desired subdomain." +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Option 2: Using Gitea" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "To deploy Gitea create a file `gitea-stack.yml`:" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Deploy Gitea:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "docker stack deploy -c gitea-stack.yml gitea\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "After deployment, access Gitea at `https://git.example.com` and complete the initial setup. Make sure to enable the container registry in the settings." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Configuring your Yii application" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Update the Makefile configuration" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "The [Yii application template](https://github.com/yiisoft/app) includes a Makefile with deployment commands. Update the `docker/.env` file in your project:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "" +"STACK_NAME=myapp\n" +"\n" +"#\n" +"# Production\n" +"#\n" +"\n" +"PROD_HOST=app.example.com\n" +"PROD_SSH=\"ssh://user@your-server-ip\"\n" +"\n" +"IMAGE=git.example.com/username/myapp\n" +"IMAGE_TAG=latest\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Replace the values: - `STACK_NAME`: A unique name for your application stack - `PROD_HOST`: The domain name where your app will be accessible - `PROD_SSH`: SSH connection string to your server (format: `ssh://user@host`) - `IMAGE`: Full path to your container image in the registry - `IMAGE_TAG`: Image tag, typically `latest` or a version number" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Configure the production environment" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Update `docker/prod/.env` with your production environment variables:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "" +"APP_ENV=prod\n" +"YII_DEBUG=false\n" +"YII_ENV=prod\n" +"\n" +"# Database configuration\n" +"DB_HOST=db\n" +"DB_NAME=myapp\n" +"DB_USER=myapp\n" +"DB_PASSWORD=secure_password_here\n" +"\n" +"# Add other environment-specific variables\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "" +"> [!WARNING]\n" +"> Never commit sensitive credentials to version control. Use `docker/prod/override.env` for sensitive values and add it to `.gitignore`.\n" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Review the production Docker Compose configuration" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "" +"This configuration:\n" +"- Runs 2 replicas for high availability\n" +"- Uses a rolling update strategy with automatic rollback on failure\n" +"- Configures `labels` for automatic HTTPS on the reverse proxy\n" +"- Disables obtaining of HTTPs certificates on the container itself\n" +" since proxy communicates with the container via HTTP. That is `auto_https off`.\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "If you need a database, add it to the stack:" +msgstr "" + +#. type: Fenced code block (yaml) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "" +"services:\n" +" app:\n" +" # ... existing configuration ...\n" +" \n" +" db:\n" +" image: postgres:18-alpine\n" +" environment:\n" +" POSTGRES_DB: myapp\n" +" POSTGRES_USER: myapp\n" +" POSTGRES_PASSWORD_FILE: /run/secrets/db_password\n" +" POSTGRES_INITDB_ARGS: \"--locale-provider=icu --icu-locale=und --encoding=UTF8\"\n" +" volumes:\n" +" - db_data:/var/lib/postgresql\n" +" networks:\n" +" - reverse_proxy_public\n" +" deploy:\n" +" placement:\n" +" constraints:\n" +" - node.role == manager\n" +" secrets:\n" +" - db_password\n" +"\n" +"volumes:\n" +" runtime:\n" +" db_data:\n" +"\n" +"secrets:\n" +" db_password:\n" +" external: true\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Create the database password secret on the server:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "echo \"your_secure_password\" | docker secret create db_password -\n" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Building and pushing the image" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Set up Docker login on your local machine" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Configure Docker to authenticate with your container registry:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "docker login git.example.com\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Enter your username and password when prompted." +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Build the production image" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Use the Makefile to build your production image:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "make prod-build\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "This runs the command defined in the Makefile:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "docker build --file docker/Dockerfile --target prod --pull -t ${IMAGE}:${IMAGE_TAG} .\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "The Dockerfile uses a multi-stage build: 1. Installs Composer dependencies in a builder stage 2. Creates a minimal production image with only the necessary files 3. Runs as a non-root user (`www-data`)" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Push the image to the registry" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Push your built image to the container registry:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "make prod-push\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "This executes:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "docker push ${IMAGE}:${IMAGE_TAG}\n" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Deploying to Docker Swarm" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Configure SSH access" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Set up SSH key-based authentication to your server:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "" +"# Generate SSH key (if you don't have one)\n" +"ssh-keygen -t ed25519 -C \"your_email@example.com\"\n" +"\n" +"# Copy the key to your server\n" +"ssh-copy-id user@your-server-ip\n" +"\n" +"# Add the SSH host to your SSH config (~/.ssh/config)\n" +"cat >> ~/.ssh/config << EOF\n" +"Host docker-web\n" +" HostName your-server-ip\n" +" User user\n" +" IdentityFile ~/.ssh/id_ed25519\n" +"EOF\n" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Set up Docker context" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Create a Docker context for remote deployment:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "docker context create swarm-prod --docker \"host=ssh://docker-web\"\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Alternatively, configure the `DOCKER_HOST` environment variable:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "export DOCKER_HOST=ssh://docker-web\n" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Deploy the application" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Deploy your application stack to Docker Swarm:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "make prod-deploy\n" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "docker -H ${PROD_SSH} stack deploy --prune --detach=false --with-registry-auth -c docker/compose.yml -c docker/prod/compose.yml ${STACK_NAME}\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "The `--with-registry-auth` flag ensures the Swarm nodes can pull images from your private registry." +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Verify the deployment" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Check the status of your services:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "" +"docker -H ssh://docker-web service ls\n" +"docker -H ssh://docker-web service ps ${STACK_NAME}_app\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "View logs:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "docker -H ssh://docker-web service logs ${STACK_NAME}_app\n" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Monitoring and maintenance" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "View service logs" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "" +"# View all logs\n" +"docker -H ssh://docker-web service logs -f ${STACK_NAME}_app\n" +"\n" +"# View logs from the last 100 lines\n" +"docker -H ssh://docker-web service logs --tail 100 ${STACK_NAME}_app\n" +"\n" +"# View logs with timestamps\n" +"docker -H ssh://docker-web service logs -t ${STACK_NAME}_app\n" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Scale the application" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Adjust the number of replicas:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "docker -H ssh://docker-web service scale ${STACK_NAME}_app=3\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Or update the `replicas` value in `docker/prod/compose.yml` and redeploy." +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Resource limits" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Add resource limits to prevent containers from consuming all server resources. Update `docker/prod/compose.yml`:" +msgstr "" + +#. type: Fenced code block (yaml) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "" +"services:\n" +" app:\n" +" # ... existing configuration ...\n" +" deploy:\n" +" resources:\n" +" limits:\n" +" cpus: '0.5'\n" +" memory: 512M\n" +" reservations:\n" +" cpus: '0.25'\n" +" memory: 256M\n" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/disabling-csrf-protection.md +#, no-wrap +msgid "Security considerations" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Use Docker secrets for sensitive data" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Instead of environment variables, use Docker secrets for sensitive information:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "" +"# Create secrets\n" +"echo \"database_password\" | docker secret create db_password -\n" +"echo \"api_key\" | docker secret create api_key -\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Update `docker/prod/compose.yml`:" +msgstr "" + +#. type: Fenced code block (yaml) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "" +"services:\n" +" app:\n" +" secrets:\n" +" - db_password\n" +" - api_key\n" +"\n" +"secrets:\n" +" db_password:\n" +" external: true\n" +" api_key:\n" +" external: true\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Access secrets in your application at `/run/secrets/secret_name`." +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Set up a firewall" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Configure UFW (Uncomplicated Firewall) on your server:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "" +"# Allow SSH\n" +"sudo ufw allow 22/tcp\n" +"\n" +"# Allow HTTP and HTTPS\n" +"sudo ufw allow 80/tcp\n" +"sudo ufw allow 443/tcp\n" +"\n" +"# Allow Docker Swarm ports (if you plan to add more nodes)\n" +"sudo ufw allow 2377/tcp\n" +"sudo ufw allow 7946/tcp\n" +"sudo ufw allow 7946/udp\n" +"sudo ufw allow 4789/udp\n" +"\n" +"# Enable the firewall\n" +"sudo ufw enable\n" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Keep the system updated" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Regularly update your server and Docker:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "" +"# Update system packages\n" +"sudo apt-get update && sudo apt-get upgrade -y\n" +"\n" +"# Update Docker images\n" +"docker -H ssh://docker-web service update --image ${IMAGE}:${IMAGE_TAG} ${STACK_NAME}_app\n" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Service won't start" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Check service events and logs:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "" +"docker -H ssh://docker-web service ps ${STACK_NAME}_app --no-trunc\n" +"docker -H ssh://docker-web service logs ${STACK_NAME}_app\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Common issues: - **Image pull errors**: Verify registry authentication with `docker -H ssh://docker-web login` - **Port conflicts**: Ensure no other services are using ports 80/443 - **Resource constraints**: Check available resources with `docker -H ssh://docker-web node ls`" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "SSL certificate issues" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Container registry connection issues" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Test registry connectivity:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "" +"# From your local machine\n" +"docker pull git.example.com/username/myapp:latest\n" +"\n" +"# From the server\n" +"docker -H ssh://docker-web pull git.example.com/username/myapp:latest\n" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Summary" +msgstr "Resumo" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "The Makefile commands simplify the deployment workflow: - `make prod-build` - Build the production image - `make prod-push` - Push to the registry - `make prod-deploy` - Deploy to Docker Swarm" +msgstr "" + +#. type: Title # +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Deploying Yii applications to Docker Swarm and Traefik" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "This guide walks you through deploying a Yii application to [Docker Swarm](https://docs.docker.com/engine/swarm/) starting from a blank server, using [Traefik](https://traefik.io/traefik) as a reverse proxy and deploying from a container registry ([Forgejo](https://forgejo.org/) or [Gitea](https://about.gitea.com/))." +msgstr "" + +#. type: Fenced code block (mermaid) +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "" +"graph LR\n" +" A[Internet] --> B[Reverse Proxy: Traefik]\n" +" B --> C[app1.example.com]\n" +" B --> D[app2.example.com]\n" +" \n" +" subgraph Docker Swarm Cluster\n" +" B\n" +" C\n" +" D\n" +" end\n" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "Setting up Traefik as reverse proxy" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "To deploy Traefik as reverse proxy create a file `traefik-stack.yml`:" +msgstr "" + +#. type: Fenced code block (yaml) +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "" +"services:\n" +" traefik:\n" +" image: traefik:v2.10\n" +" command:\n" +" - \"--api.insecure=true\"\n" +" - \"--providers.docker=true\"\n" +" - \"--providers.docker.swarmMode=true\"\n" +" - \"--providers.docker.exposedbydefault=false\"\n" +" - \"--entrypoints.web.address=:80\"\n" +" - \"--entrypoints.websecure.address=:443\"\n" +" - \"--certificatesresolvers.letsencrypt.acme.tlschallenge=true\"\n" +" - \"--certificatesresolvers.letsencrypt.acme.email=admin@example.com\"\n" +" - \"--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json\"\n" +" ports:\n" +" - \"80:80\"\n" +" - \"443:443\"\n" +" - \"8080:8080\"\n" +" volumes:\n" +" - \"/var/run/docker.sock:/var/run/docker.sock:ro\"\n" +" - \"traefik_certificates:/letsencrypt\"\n" +" networks:\n" +" - reverse_proxy_public\n" +" deploy:\n" +" placement:\n" +" constraints:\n" +" - node.role == manager\n" +"\n" +"volumes:\n" +" traefik_certificates:\n" +"\n" +"networks:\n" +" reverse_proxy_public:\n" +" external: true\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "Deploy Traefik:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "docker stack deploy -c traefik-stack.yml traefik\n" +msgstr "" + +#. type: Fenced code block (yaml) +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "" +"services:\n" +" forgejo:\n" +" image: codeberg.org/forgejo/forgejo:1.21\n" +" ports:\n" +" - \"3000:3000\"\n" +" volumes:\n" +" - forgejo_data:/data\n" +" networks:\n" +" - reverse_proxy_public\n" +" deploy:\n" +" labels:\n" +" - \"traefik.enable=true\"\n" +" - \"traefik.http.routers.app.rule=Host(`git.example.com`)\"\n" +" - \"traefik.http.routers.app.entrypoints=websecure\"\n" +" - \"traefik.http.routers.app.tls.certresolver=letsencrypt\"\n" +" - \"traefik.http.services.app.loadbalancer.server.port=3000\" \n" +"\n" +"volumes:\n" +" forgejo_data:\n" +"\n" +"networks:\n" +" reverse_proxy_public:\n" +" external: true\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "After deployment, access Forgejo at `https://git.example.com` and complete the initial setup. Make sure to enable the container registry in the settings." +msgstr "" + +#. type: Fenced code block (yaml) +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "" +"services:\n" +" gitea:\n" +" image: gitea/gitea:latest\n" +" ports:\n" +" - \"3000:3000\"\n" +" volumes:\n" +" - gitea_data:/data\n" +" networks:\n" +" - reverse_proxy_public\n" +" deploy:\n" +" labels:\n" +" - \"traefik.enable=true\"\n" +" - \"traefik.http.routers.app.rule=Host(`git.example.com`)\"\n" +" - \"traefik.http.routers.app.entrypoints=websecure\"\n" +" - \"traefik.http.routers.app.tls.certresolver=letsencrypt\"\n" +" - \"traefik.http.services.app.loadbalancer.server.port=3000\" \n" +"\n" +"volumes:\n" +" gitea_data:\n" +"\n" +"networks:\n" +" reverse_proxy_public:\n" +" external: true\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "When using Traefik, you'll need to modify the Yii application's `docker/prod/compose.yml` to use Traefik labels instead of Caddy labels:" +msgstr "" + +#. type: Fenced code block (yaml) +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#, no-wrap +msgid "" +"services:\n" +" app:\n" +" image: ${IMAGE}:${IMAGE_TAG}\n" +" networks:\n" +" - reverse_proxy_public\n" +" volumes:\n" +" - runtime:/app/runtime\n" +" - caddy_data:/data\n" +" - caddy_config:/config\n" +" env_file:\n" +" - path: ./prod/.env\n" +" - path: ./prod/override.env\n" +" required: false\\\n" +" environment:\n" +" CADDY_EXTRA_CONFIG: 'auto_https off'\n" +" deploy:\n" +" replicas: 2\n" +" update_config:\n" +" delay: 10s\n" +" parallelism: 1\n" +" order: start-first\n" +" failure_action: rollback\n" +" monitor: 10s\n" +" rollback_config:\n" +" parallelism: 0\n" +" order: stop-first\n" +" restart_policy:\n" +" condition: on-failure\n" +" delay: 5s\n" +" max_attempts: 3\n" +" window: 120s\n" +" labels:\n" +" - \"traefik.enable=true\"\n" +" - \"traefik.http.routers.app.rule=Host(`${PROD_HOST:-app.example.com}`)\"\n" +" - \"traefik.http.routers.app.entrypoints=websecure\"\n" +" - \"traefik.http.routers.app.tls.certresolver=letsencrypt\"\n" +" - \"traefik.http.services.app.loadbalancer.server.port=80\"\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "If Traefik can't obtain certificates: - Verify DNS is pointing to your server - Check that ports 80 and 443 are accessible from the internet - Ensure the email in the Let's Encrypt configuration is valid - Check logs: `docker -H ssh://docker-web service logs traefik_traefik`" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "You've successfully deployed a Yii application to Docker Swarm with: - A container registry (Forgejo or Gitea) - Automatic HTTPS via Traefik - Zero-downtime deployments with rolling updates - High availability with multiple replicas" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/docker-swarm-traefik.md +msgid "For more information, see: - [Yii Application Template](https://github.com/yiisoft/app) - [Docker Swarm Documentation](https://docs.docker.com/engine/swarm/) - [Traefik Documentation](https://doc.traefik.io/traefik/)" +msgstr "" diff --git a/_translations/po/pt-BR/cookbook_deployment_docker-swarm.md.po b/_translations/po/pt-BR/cookbook_deployment_docker-swarm.md.po new file mode 100644 index 00000000..8f4c87a7 --- /dev/null +++ b/_translations/po/pt-BR/cookbook_deployment_docker-swarm.md.po @@ -0,0 +1,32 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-01-02 23:54+0000\n" +"PO-Revision-Date: 2026-01-02 23:54+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/cookbook/deployment/docker-swarm.md +#, no-wrap +msgid "Deploying Yii applications to Docker Swarm" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/docker-swarm.md +msgid "[Using Caddy](docker-swarm-caddy.md)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/docker-swarm.md +msgid "[Using Traefik](docker-swarm-traefik.md)" +msgstr "" diff --git a/_translations/po/pt-BR/cookbook_deployment_rolling-update-migrations.md.po b/_translations/po/pt-BR/cookbook_deployment_rolling-update-migrations.md.po new file mode 100644 index 00000000..21f8bf78 --- /dev/null +++ b/_translations/po/pt-BR/cookbook_deployment_rolling-update-migrations.md.po @@ -0,0 +1,490 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-05-30 09:18+0000\n" +"PO-Revision-Date: 2026-05-30 09:18+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/cookbook/deployment/rolling-update-migrations.md +#, no-wrap +msgid "Applying migrations during rolling updates" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Rolling updates keep old and new application instances running at the same time. This makes database changes more delicate than in a single-server deployment: both application versions must work with the same database while the deployment is in progress." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "The safe rule is:" +msgstr "" + +#. type: Bullet: '1. ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Apply database changes that are compatible with the current production code." +msgstr "" + +#. type: Bullet: '2. ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Deploy code that starts using these database changes." +msgstr "" + +#. type: Bullet: '3. ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Remove obsolete database structures only after every old application instance is gone." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "This is often called the expand and contract pattern. First expand the schema so both versions can use it. Then move the application code. Finally contract the schema in a later deployment." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/rolling-update-migrations.md +#, no-wrap +msgid "Why this matters" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "During a rolling update, requests may be served by different versions of the application:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "old code that does not know about the new schema;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "new code that expects the new schema;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "background workers that may lag behind web instances;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "scheduled commands that may run during deployment." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "If a migration drops or renames a column before all old instances stop using it, old code fails. If code that requires a new column is deployed before the column exists, new code fails. The migration plan must keep every intermediate state valid." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/rolling-update-migrations.md +#, no-wrap +msgid "Deployment flow" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Use this flow for changes that must not interrupt production traffic:" +msgstr "" + +#. type: Bullet: '1. ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Create a migration that only adds compatible schema." +msgstr "" + +#. type: Bullet: '2. ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Apply this migration to production while the current application version is still running." +msgstr "" + +#. type: Bullet: '3. ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Deploy the new application version with a rolling update." +msgstr "" + +#. type: Bullet: '4. ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Verify that all instances and workers run the new version." +msgstr "" + +#. type: Bullet: '5. ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "In a later release, apply cleanup migrations that remove old columns, indexes, tables, or compatibility code." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "For Yii applications, run migrations with the same command you use in regular deployments, for example:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/cookbook/deployment/rolling-update-migrations.md +#, no-wrap +msgid "./yii migrate\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Run migrations from a single deployment job or one dedicated console container. Do not let every rolling application instance run migrations on startup." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/rolling-update-migrations.md +#, no-wrap +msgid "Adding a column" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Adding a nullable column is usually compatible with old code:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/deployment/rolling-update-migrations.md +#, no-wrap +msgid "" +"public function up(MigrationBuilder $b): void\n" +"{\n" +" $cb = $b->columnBuilder();\n" +"\n" +" $b->addColumn('user', 'display_name', $cb::string());\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Then deploy code that writes and reads `display_name`." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "If the column must eventually be required:" +msgstr "" + +#. type: Bullet: '1. ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Add it as nullable." +msgstr "" + +#. type: Bullet: '2. ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Deploy code that writes it for new and updated rows." +msgstr "" + +#. type: Bullet: '3. ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Backfill existing rows in batches." +msgstr "" + +#. type: Bullet: '4. ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Add a `NOT NULL` constraint in a later migration." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Do not add a `NOT NULL` column without a database default while old code still inserts rows without that column." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/rolling-update-migrations.md +#, no-wrap +msgid "Renaming a column" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Renaming is not compatible because old code uses the old name and new code uses the new name. Use a multi-release change instead:" +msgstr "" + +#. type: Bullet: '1. ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Add the new column." +msgstr "" + +#. type: Bullet: '2. ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Backfill it from the old column." +msgstr "" + +#. type: Bullet: '3. ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Deploy code that writes both columns and reads the new column with a fallback to the old one." +msgstr "" + +#. type: Bullet: '4. ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Wait until all old code is gone." +msgstr "" + +#. type: Bullet: '5. ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Deploy code that uses only the new column." +msgstr "" + +#. type: Bullet: '6. ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Drop the old column in a later cleanup migration." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "The same approach works for moving data to a different table." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/rolling-update-migrations.md +#, no-wrap +msgid "Changing a column type" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Changing a column type in place may lock the table or break either the old or new code. Prefer a new column:" +msgstr "" + +#. type: Bullet: '1. ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Add a column with the target type." +msgstr "" + +#. type: Bullet: '2. ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Backfill it in batches." +msgstr "" + +#. type: Bullet: '3. ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Deploy code that writes both columns." +msgstr "" + +#. type: Bullet: '4. ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Deploy code that reads the new column." +msgstr "" + +#. type: Bullet: '5. ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Drop the old column after all code uses the new one." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "For small tables, an in-place type change may be acceptable. For production tables with traffic, verify locking behavior on the exact database engine and version before applying it." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/rolling-update-migrations.md +#, no-wrap +msgid "Dropping columns and tables" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Dropping is a cleanup step, not the first step:" +msgstr "" + +#. type: Bullet: '1. ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Deploy code that no longer reads or writes the column or table." +msgstr "" + +#. type: Bullet: '2. ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Confirm that old application instances, workers, and scheduled commands are stopped." +msgstr "" + +#. type: Bullet: '3. ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Confirm that no external reporting or maintenance scripts depend on it." +msgstr "" + +#. type: Bullet: '4. ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Drop it in a separate migration." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "This makes rollback safer. If you need to roll back application code before cleanup, the old schema is still available." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/rolling-update-migrations.md +#, no-wrap +msgid "Adding indexes and constraints" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Indexes and constraints may be logically compatible but operationally risky because they can lock tables." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "For indexes:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "use online index creation when the database supports it;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "for PostgreSQL, consider `CREATE INDEX CONCURRENTLY` from a migration or command that is not wrapped in a transaction;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "for MySQL and MariaDB, check whether the operation can use online DDL for your table and engine." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "For constraints:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "clean invalid data before adding the constraint;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "add the constraint only after deployed code preserves it;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "for PostgreSQL, consider adding foreign keys and check constraints as `NOT VALID`, then validating them separately." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Keep long-running index creation and validation separate from unrelated schema changes so it is easier to monitor and retry them." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/rolling-update-migrations.md +#, no-wrap +msgid "Data migrations" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Data migrations that touch many rows should be safe to run while the application is live:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "make them idempotent so rerunning them does not corrupt data;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "process rows in small batches;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "avoid depending on current application service or entity logic because that logic changes over time;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "prefer forward-compatible values that both old and new code can handle;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "store progress when a backfill is too large for a single migration run." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "For very large backfills, use a console command or background job after the schema migration. The schema migration should prepare the database; the background process should move the data gradually." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/rolling-update-migrations.md +#, no-wrap +msgid "Reverting" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "In production rolling deployments, reverting a destructive migration is often harder than deploying a corrective migration. Treat `down()` methods for destructive operations as a local-development convenience, not as the main production rollback plan." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "A practical rollback plan is:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "before cleanup, roll back code only because old schema is still present;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "after cleanup, deploy a new forward migration that restores the required structure or compatibility;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "restore from backup only when data was actually lost and no forward repair is possible." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/deployment/rolling-update-migrations.md +#, no-wrap +msgid "Checklist" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "Before applying a production migration, verify that:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "the current production code works after the migration;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "the new code works before and after all instances are updated;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "old workers and scheduled commands are covered;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "inserts and updates keep required columns valid in every deployment phase;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "long-running schema operations will not block production traffic unexpectedly;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/deployment/rolling-update-migrations.md +msgid "cleanup happens in a separate release after the rollout is complete." +msgstr "" diff --git a/_translations/po/pt-BR/cookbook_disabling-csrf-protection.md.po b/_translations/po/pt-BR/cookbook_disabling-csrf-protection.md.po new file mode 100644 index 00000000..b695a18d --- /dev/null +++ b/_translations/po/pt-BR/cookbook_disabling-csrf-protection.md.po @@ -0,0 +1,310 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-06-29 17:10+0000\n" +"PO-Revision-Date: 2026-06-29 17:10+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/disabling-csrf-protection.md +#, no-wrap +msgid "Security considerations" +msgstr "" + +#. type: Title # +#: ../src/cookbook/disabling-csrf-protection.md +#, no-wrap +msgid "Disabling CSRF protection" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/disabling-csrf-protection.md +#, no-wrap +msgid "What is CSRF protection?" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/disabling-csrf-protection.md +msgid "Cross-Site Request Forgery (CSRF) protection is a security mechanism that prevents malicious websites from making unauthorized requests on behalf of authenticated users. Yii3 includes built-in CSRF protection through the `Yiisoft\\Yii\\Web\\Middleware\\CsrfTokenMiddleware` middleware." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/disabling-csrf-protection.md +msgid "For a comprehensive understanding of CSRF attacks and protection mechanisms, see the [Security best practices](../guide/security/best-practices.md#avoiding-csrf) section in the main guide." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/disabling-csrf-protection.md +#, no-wrap +msgid "When to disable CSRF protection" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/disabling-csrf-protection.md +msgid "While CSRF protection should generally remain enabled for web applications, there are specific scenarios where you might need to disable it:" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/disabling-csrf-protection.md +#, no-wrap +msgid "When external systems cannot provide CSRF tokens" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/disabling-csrf-protection.md +msgid "When building APIs or handling automated requests from external systems, CSRF protection can interfere with legitimate requests since these systems cannot provide valid CSRF tokens:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/disabling-csrf-protection.md +msgid "**Third-party integrations**: External services cannot provide valid CSRF tokens" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/disabling-csrf-protection.md +msgid "**Mobile applications**: Native mobile apps typically don't use cookies or sessions in the same way as web browsers" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/disabling-csrf-protection.md +msgid "**Server-to-server communication**: API endpoints designed for machine-to-machine communication" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/disabling-csrf-protection.md +msgid "**Payment processors**: PayPal, Stripe, and other payment systems send webhook notifications" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/disabling-csrf-protection.md +msgid "**Version control systems**: GitHub, GitLab webhooks for CI/CD pipelines" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/disabling-csrf-protection.md +msgid "**Social media platforms**: Twitter, Facebook webhook notifications" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/disabling-csrf-protection.md +msgid "**Communication services**: Slack, Discord bot integrations" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/disabling-csrf-protection.md +#, no-wrap +msgid "How to disable CSRF protection" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/disabling-csrf-protection.md +msgid "First, you need to remove CSRF middleware from your main application middleware list in `config/web/di/application.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/disabling-csrf-protection.md +#, no-wrap +msgid "" +"return [\n" +" Application::class => [\n" +" '__construct()' => [\n" +" 'dispatcher' => DynamicReference::to([\n" +" 'class' => MiddlewareDispatcher::class,\n" +" 'withMiddlewares()' => [\n" +" [\n" +" ErrorCatcher::class,\n" +" SessionMiddleware::class,\n" +" CsrfTokenMiddleware::class, // <- Remove this line \n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/disabling-csrf-protection.md +msgid "Now, if you need to leave CSRF on for specific routes or route groups, you can do so by adding the `CsrfTokenMiddleware` middleware to the router configuration in `config/common/routes.php`. For a group that would be the following:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/disabling-csrf-protection.md +#, no-wrap +msgid "" +"return [\n" +" Group::create()\n" +" ->middleware(CsrfTokenMiddleware::class)\n" +" ->routes(\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/disabling-csrf-protection.md +msgid "For a single route, you can add the middleware directly to the route:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/disabling-csrf-protection.md +#, no-wrap +msgid "" +"Route::methods([Method::GET, Method::POST], '/say[/{test}]')\n" +" ->action(\\App\\Controller\\Echo\\Action::class)\n" +" ->name('echo/say')\n" +" ->middleware(CsrfTokenMiddleware::class)\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/disabling-csrf-protection.md +msgid "When disabling CSRF protection, keep these security considerations in mind:" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/disabling-csrf-protection.md +#, no-wrap +msgid "Alternative authentication methods" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/disabling-csrf-protection.md +msgid "For API endpoints, implement proper authentication mechanisms:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/disabling-csrf-protection.md +msgid "**API keys**: Require API keys for authentication" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/disabling-csrf-protection.md +msgid "**Bearer tokens**: Use JWT or similar token-based authentication" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/disabling-csrf-protection.md +msgid "**OAuth 2.0**: Implement OAuth 2.0 for third-party access" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/disabling-csrf-protection.md +msgid "**IP whitelisting**: Restrict access to known IP addresses for webhooks" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/disabling-csrf-protection.md +#, no-wrap +msgid "Request validation" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/disabling-csrf-protection.md +msgid "Implement additional validation for requests without CSRF protection:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/disabling-csrf-protection.md +msgid "**Signature verification**: Verify webhook signatures (e.g., GitHub's X-Hub-Signature)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/disabling-csrf-protection.md +msgid "**Timestamp validation**: Check request timestamps to prevent replay attacks" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/disabling-csrf-protection.md +msgid "**Rate limiting**: Implement rate limiting to prevent abuse" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/disabling-csrf-protection.md +msgid "**Input validation**: Strictly validate all input parameters" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/disabling-csrf-protection.md +#, no-wrap +msgid "Example: Webhook signature verification" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/disabling-csrf-protection.md +#, no-wrap +msgid "" +"getHeaderLine('X-Webhook-Signature');\n" +" $payload = (string) $request->getBody();\n" +" $expectedSignature = hash_hmac('sha256', $payload, $this->webhookSecret);\n" +" \n" +" if (!hash_equals($signature, $expectedSignature)) {\n" +" throw new \\RuntimeException('Invalid webhook signature');\n" +" }\n" +" \n" +" // Process webhook payload\n" +" // ...\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/disabling-csrf-protection.md +#, no-wrap +msgid "Best practices" +msgstr "" + +#. type: Bullet: '1. ' +#: ../src/cookbook/disabling-csrf-protection.md +msgid "**Minimize exposure**: Only disable CSRF protection where absolutely necessary" +msgstr "" + +#. type: Bullet: '2. ' +#: ../src/cookbook/disabling-csrf-protection.md +msgid "**Use HTTPS**: Always use HTTPS for API endpoints and webhooks" +msgstr "" + +#. type: Bullet: '3. ' +#: ../src/cookbook/disabling-csrf-protection.md +msgid "**Monitor logs**: Log all requests to API endpoints for security monitoring" +msgstr "" + +#. type: Bullet: '4. ' +#: ../src/cookbook/disabling-csrf-protection.md +msgid "**Regular security audits**: Periodically review your API endpoints and their security measures" +msgstr "" + +#. type: Bullet: '5. ' +#: ../src/cookbook/disabling-csrf-protection.md +msgid "**Documentation**: Clearly document which endpoints have CSRF protection disabled and why" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/disabling-csrf-protection.md +#, no-wrap +msgid "Conclusion" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/disabling-csrf-protection.md +msgid "While CSRF protection is crucial for web applications, there are legitimate scenarios where it needs to be disabled, particularly for external APIs and webhooks. When disabling CSRF protection, always implement alternative security measures and follow security best practices to maintain the overall security of your application." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/disabling-csrf-protection.md +msgid "Remember that disabling CSRF protection increases security risks, so careful consideration and proper implementation of alternative security measures are essential." +msgstr "" diff --git a/_translations/po/pt-BR/cookbook_index.md.po b/_translations/po/pt-BR/cookbook_index.md.po new file mode 100644 index 00000000..04c869ee --- /dev/null +++ b/_translations/po/pt-BR/cookbook_index.md.po @@ -0,0 +1,147 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-10-15 11:09+0000\n" +"PO-Revision-Date: 2026-10-15 11:09+0000\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/cookbook/index.md +#, no-wrap +msgid "Yii3 community cookbook" +msgstr "Cookbook da comunidade Yii3" + +#. type: Plain text +#: ../src/cookbook/index.md +msgid "Yii3 Community Cookbook is an OpenSource book full of tips and tricks about the [Yii3](https://www.yiiframework.com/) PHP framework." +msgstr "O Cookbook da comunidade Yii3 é um livro de código aberto cheio de dicas e truques sobre o framework PHP [Yii3](https://www.yiiframework.com/)." + +#. type: Bullet: '- ' +#: ../src/cookbook/index.md +msgid "The Yii community creates the cookbook." +msgstr "A comunidade Yii escreve o cookbook." + +#. type: Bullet: '- ' +#: ../src/cookbook/index.md ../src/cookbook/third-party-integrations/index.md +msgid "Yii core team members curate and edit it." +msgstr "Membros do time principal do Yii fazem a curadoria e a edição." + +#. type: Plain text +#: ../src/cookbook/index.md ../src/cookbook/third-party-integrations/index.md +msgid "Feel free to pull-request your own writings. Team members will review it, give feedback and merge the best possible way." +msgstr "Fique à vontade para enviar seus próprios textos via pull request. Os membros do time vão revisar, dar feedback e fazer o merge da melhor forma possível." + +#. type: Plain text +#: ../src/cookbook/index.md +msgid "This book conforms to the [Terms of Yii Documentation](https://www.yiiframework.com/license#docs)." +msgstr "Este livro segue os [Termos da documentação do Yii](https://www.yiiframework.com/license#docs)." + +#. type: Bullet: '- ' +#: ../src/cookbook/index.md +msgid "[Preface](preface.md)" +msgstr "[Prefácio](preface.md)" + +#. type: Bullet: '- ' +#: ../src/cookbook/index.md +msgid "[Making HTTP requests](making-http-requests.md)" +msgstr "[Fazendo requisições HTTP](making-http-requests.md)" + +#. type: Bullet: '- ' +#: ../src/cookbook/index.md +msgid "[Using htmx for partial page reloads](using-htmx-for-partial-reloads.md)" +msgstr "[Usando htmx para recarregar partes da página](using-htmx-for-partial-reloads.md)" + +#. type: Bullet: '- ' +#: ../src/cookbook/index.md +msgid "[Disabling CSRF protection](disabling-csrf-protection.md)" +msgstr "[Desativando a proteção CSRF](disabling-csrf-protection.md)" + +#. type: Bullet: '- ' +#: ../src/cookbook/index.md +msgid "[Sentry integration](sentry-integration.md)" +msgstr "[Integração com o Sentry](sentry-integration.md)" + +#. type: Bullet: '- ' +#: ../src/cookbook/index.md +msgid "[Using a custom migration template](custom-migration-template.md)" +msgstr "[Usando um template de migration personalizado](custom-migration-template.md)" + +#. type: Bullet: '- ' +#: ../src/cookbook/index.md +msgid "[Custom hydrator type casters](custom-hydrator-type-casters.md)" +msgstr "[Type casters personalizados para o hydrator](custom-hydrator-type-casters.md)" + +#. type: Bullet: '- ' +#: ../src/cookbook/index.md +msgid "[Using Yii in third-party applications](using-yii-in-third-party-apps.md)" +msgstr "[Usando o Yii em aplicações de terceiros](using-yii-in-third-party-apps.md)" + +#. type: Bullet: '- ' +#: ../src/cookbook/index.md +msgid "[Third-party integrations](third-party-integrations/index.md)" +msgstr "[Integrações com terceiros](third-party-integrations/index.md)" + +#. type: Bullet: '- ' +#: ../src/cookbook/index.md +msgid "[Working on Windows](working-on-windows.md)" +msgstr "[Trabalhando no Windows](working-on-windows.md)" + +#. type: Bullet: '- ' +#: ../src/cookbook/index.md +msgid "[Opening files directly in PhpStorm](opening-files-in-phpstorm.md)" +msgstr "[Abrindo arquivos direto no PhpStorm](opening-files-in-phpstorm.md)" + +#. type: Bullet: '- ' +#: ../src/cookbook/index.md +msgid "[Configuring Xdebug](configuring-xdebug.md)" +msgstr "[Configurando o Xdebug](configuring-xdebug.md)" + +#. type: Bullet: '- ' +#: ../src/cookbook/index.md +msgid "[Configuring webservers](configuring-webservers/general.md)" +msgstr "[Configurando servidores web](configuring-webservers/general.md)" + +#. type: Bullet: '- ' +#: ../src/cookbook/index.md +msgid "[Structuring code by use-case with vertical slices](organizing-code/structuring-by-use-case-with-vertical-slices.md)" +msgstr "[Estruturando o código por caso de uso com vertical slices](organizing-code/structuring-by-use-case-with-vertical-slices.md)" + +#. type: Bullet: '- ' +#: ../src/cookbook/index.md +msgid "[Domain](organizing-code/domain.md)" +msgstr "[Domínio](organizing-code/domain.md)" + +#. type: Bullet: '- ' +#: ../src/cookbook/index.md +msgid "[Service components](organizing-code/service.md)" +msgstr "[Componentes de serviço](organizing-code/service.md)" + +#. type: Bullet: '- ' +#: ../src/cookbook/index.md +msgid "[Deploying to Docker Swarm](deployment/docker-swarm.md)" +msgstr "[Deploy com Docker Swarm](deployment/docker-swarm.md)" + +#. type: Bullet: '- ' +#: ../src/cookbook/index.md +msgid "[Deploying Yii applications with Angie Docker Proxy](deployment/angie-docker-proxy.md)" +msgstr "[Deploy de aplicações Yii com Angie Docker Proxy](deployment/angie-docker-proxy.md)" + +#. type: Bullet: '- ' +#: ../src/cookbook/index.md +msgid "[Configuring an application for autoscaling](deployment/autoscaling.md)" +msgstr "[Configurando uma aplicação para autoscaling](deployment/autoscaling.md)" + +#. type: Bullet: '- ' +#: ../src/cookbook/index.md +msgid "[Applying migrations during rolling updates](deployment/rolling-update-migrations.md)" +msgstr "[Aplicando migrations durante rolling updates](deployment/rolling-update-migrations.md)" diff --git a/_translations/po/pt-BR/cookbook_making-http-requests.md.po b/_translations/po/pt-BR/cookbook_making-http-requests.md.po new file mode 100644 index 00000000..84bb70e4 --- /dev/null +++ b/_translations/po/pt-BR/cookbook_making-http-requests.md.po @@ -0,0 +1,295 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-05-06 19:16+0000\n" +"PO-Revision-Date: 2026-05-06 19:16+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/cookbook/making-http-requests.md +#, no-wrap +msgid "Making HTTP requests" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/making-http-requests.md +msgid "Yii doesn't include its own HTTP client implementation. Use a client that implements [PSR-18](https://www.php-fig.org/psr/psr-18/) and depend on PSR interfaces in your application code." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/making-http-requests.md +msgid "This recipe uses [Guzzle](https://docs.guzzlephp.org/) as the HTTP client. Guzzle provides a PSR-18 client and uses PSR-7 messages." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/making-http-requests.md +#: ../src/cookbook/sentry-integration.md +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#: ../src/guide/tutorial/using-yii-with-swoole.md ../src/guide/views/asset.md +#: ../src/guide/views/view.md ../src/guide/views/widget.md +#, no-wrap +msgid "Installation" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/making-http-requests.md +msgid "Install Guzzle:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/cookbook/making-http-requests.md +#, no-wrap +msgid "composer require guzzlehttp/guzzle\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/making-http-requests.md +msgid "The package installs the PSR HTTP interfaces and `guzzlehttp/psr7`, which provides PSR-7 messages and PSR-17 factories." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/making-http-requests.md +#, no-wrap +msgid "Configure the container" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/making-http-requests.md +msgid "Create `config/common/di/http-client.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/making-http-requests.md +#, no-wrap +msgid "" +" [\n" +" 'class' => Client::class,\n" +" '__construct()' => [\n" +" 'config' => [\n" +" 'timeout' => 10.0,\n" +" 'connect_timeout' => 3.0,\n" +" ],\n" +" ],\n" +" ],\n" +"\n" +" HttpFactory::class => HttpFactory::class,\n" +" RequestFactoryInterface::class => Reference::to(HttpFactory::class),\n" +" ResponseFactoryInterface::class => Reference::to(HttpFactory::class),\n" +" StreamFactoryInterface::class => Reference::to(HttpFactory::class),\n" +" UriFactoryInterface::class => Reference::to(HttpFactory::class),\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/making-http-requests.md +msgid "Use `ClientInterface` for sending requests and PSR-17 factories for creating requests, streams, and URIs." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/making-http-requests.md +#, no-wrap +msgid "Send a GET request" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/making-http-requests.md +msgid "Inject `Psr\\Http\\Client\\ClientInterface` and `Psr\\Http\\Message\\RequestFactoryInterface` into the service that talks to the external API:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/making-http-requests.md +#, no-wrap +msgid "" +"\n" +" */\n" +" public function latest(string $owner, string $repository): array\n" +" {\n" +" $request = $this->requestFactory\n" +" ->createRequest(\n" +" 'GET',\n" +" sprintf(\n" +" 'https://api.github.com/repos/%s/%s/releases/latest',\n" +" rawurlencode($owner),\n" +" rawurlencode($repository),\n" +" ),\n" +" )\n" +" ->withHeader('Accept', 'application/vnd.github+json');\n" +"\n" +" try {\n" +" $response = $this->httpClient->sendRequest($request);\n" +" } catch (ClientExceptionInterface $e) {\n" +" throw new RuntimeException('GitHub request failed.', previous: $e);\n" +" }\n" +"\n" +" if ($response->getStatusCode() !== 200) {\n" +" throw new RuntimeException(sprintf(\n" +" 'GitHub returned HTTP %d.',\n" +" $response->getStatusCode(),\n" +" ));\n" +" }\n" +"\n" +" return json_decode((string) $response->getBody(), true, 512, JSON_THROW_ON_ERROR);\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/making-http-requests.md +msgid "PSR-18 clients throw `ClientExceptionInterface` for request sending errors. HTTP status codes such as `404` and `500` are valid responses, so check the status code in your service." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/making-http-requests.md +#, no-wrap +msgid "Send JSON" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/making-http-requests.md +msgid "Use `StreamFactoryInterface` when you need a request body:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/making-http-requests.md +#, no-wrap +msgid "" +" $payload\n" +" */\n" +" public function send(array $payload): void\n" +" {\n" +" $body = $this->streamFactory->createStream(json_encode($payload, JSON_THROW_ON_ERROR));\n" +"\n" +" $request = $this->requestFactory\n" +" ->createRequest('POST', 'https://api.example.com/webhooks')\n" +" ->withHeader('Content-Type', 'application/json')\n" +" ->withHeader('Accept', 'application/json')\n" +" ->withBody($body);\n" +"\n" +" $this->httpClient->sendRequest($request);\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/making-http-requests.md ../src/guide/index.md +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "Testing" +msgstr "Testes" + +#. type: Plain text +#: ../src/cookbook/making-http-requests.md +msgid "For unit tests, pass a client configured with Guzzle's `MockHandler`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/making-http-requests.md +#, no-wrap +msgid "" +" '1.0.0'], JSON_THROW_ON_ERROR)),\n" +" ]);\n" +"\n" +" $client = new Client(['handler' => HandlerStack::create($handler)]);\n" +" $factory = new HttpFactory();\n" +"\n" +" $releaseClient = new ReleaseClient($client, $factory);\n" +"\n" +" $release = $releaseClient->latest('yiisoft', 'docs');\n" +"\n" +" $this->assertSame('1.0.0', $release['tag_name']);\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/making-http-requests.md +#, no-wrap +msgid "When to use Guzzle directly" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/making-http-requests.md +msgid "Depend on PSR interfaces for regular application services. Use `GuzzleHttp\\Client` directly in infrastructure code that needs Guzzle-only features such as asynchronous requests, handler stacks, or middleware." +msgstr "" diff --git a/_translations/po/pt-BR/cookbook_opening-files-in-phpstorm.md.po b/_translations/po/pt-BR/cookbook_opening-files-in-phpstorm.md.po new file mode 100644 index 00000000..6733e6db --- /dev/null +++ b/_translations/po/pt-BR/cookbook_opening-files-in-phpstorm.md.po @@ -0,0 +1,210 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-05-06 19:23+0000\n" +"PO-Revision-Date: 2026-05-06 19:23+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/cookbook/opening-files-in-phpstorm.md +#, no-wrap +msgid "Opening files directly in PhpStorm" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/opening-files-in-phpstorm.md +msgid "Yii error pages can show links that open stack trace files in PhpStorm at the failing line. This is useful in local development when the error page runs in a browser and the project is open in the IDE." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/opening-files-in-phpstorm.md +#, no-wrap +msgid "Check Toolbox links" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/opening-files-in-phpstorm.md +#, no-wrap +msgid "" +"PhpStorm supports Toolbox URLs that use the `jetbrains://` protocol. To get the `project` value and path format,\n" +"right-click a project file in the Project tool window and select **Copy Path/Reference** > **Toolbox URL**.\n" +"If the copied URL has `origin`, keep the `origin` parameter and its value in your links.\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/opening-files-in-phpstorm.md +msgid "On Linux, check that Toolbox registered the protocol handler:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/cookbook/opening-files-in-phpstorm.md +#, no-wrap +msgid "xdg-mime query default x-scheme-handler/jetbrains\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/opening-files-in-phpstorm.md +msgid "The command should print a Toolbox or JetBrains daemon desktop file, for example `jetbrainsd.desktop`." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/opening-files-in-phpstorm.md +msgid "PhpStorm should be running with the project open when you click stack trace links." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/opening-files-in-phpstorm.md +#, no-wrap +msgid "Configure error trace links" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/opening-files-in-phpstorm.md +msgid "The Yii application template configures `Yiisoft\\ErrorHandler\\Renderer\\HtmlRenderer` in `config/common/di/error-handler.php`. It reads a `traceLink` parameter and uses it for stack trace file links." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/opening-files-in-phpstorm.md +msgid "Add the parameter to `config/common/params.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/opening-files-in-phpstorm.md +#, no-wrap +msgid "" +" 'jetbrains://phpstorm/navigate/reference?project=my-app&path={file}:{line}',\n" +" // Other parameters.\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/opening-files-in-phpstorm.md +msgid "Replace `my-app` with the `project` value from the Toolbox URL. If the Toolbox URL uses `origin`, keep `origin` in the link template and use its value." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/opening-files-in-phpstorm.md +msgid "After that, open a debug error page and click a file link in the stack trace." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/opening-files-in-phpstorm.md +#, no-wrap +msgid "Map Docker paths to host paths" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/opening-files-in-phpstorm.md +msgid "When the application runs in Docker, stack traces usually contain container paths such as `/app/src/...`. PhpStorm needs the matching host path." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/opening-files-in-phpstorm.md +msgid "Set `APP_HOST_PATH` in `docker/dev/override.env` to the project path on the host machine. Set `APP_IDE_PROJECT` to the `project` value from a Toolbox URL. If the URL uses `origin`, store the `origin` value instead and use `origin` in the final URL template:" +msgstr "" + +#. type: Fenced code block (dotenv) +#: ../src/cookbook/opening-files-in-phpstorm.md +#, no-wrap +msgid "" +"APP_HOST_PATH=/home/user/projects/my-app\n" +"APP_IDE_PROJECT=my-app\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/opening-files-in-phpstorm.md +msgid "`docker/dev/override.env` is for developer-specific settings and shouldn't be committed. See [Override env files](../guide/tutorial/docker.md#override-env-files) for details." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/opening-files-in-phpstorm.md +msgid "In the application parameters, expose these environment values as `$params['app']['hostPath']` and `$params['app']['ideProject']`." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/opening-files-in-phpstorm.md +msgid "With the default application template, `/app/src/Web/HomePage/Action.php` will be linked as `/home/user/projects/my-app/src/Web/HomePage/Action.php`." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/opening-files-in-phpstorm.md +#, no-wrap +msgid "Configure `HtmlRenderer` manually" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/opening-files-in-phpstorm.md +msgid "If your application doesn't have the template's `error-handler.php` configuration, configure `HtmlRenderer` directly:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/opening-files-in-phpstorm.md +#, no-wrap +msgid "" +" [\n" +" '__construct()' => [\n" +" 'traceLink' => 'jetbrains://phpstorm/navigate/reference?project=my-app&path={file}:{line}',\n" +" ],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/opening-files-in-phpstorm.md +msgid "For Docker, use a closure to map the container path to the host path:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/opening-files-in-phpstorm.md +#, no-wrap +msgid "" +" [\n" +" '__construct()' => [\n" +" 'traceLink' => static function (string $file, ?int $line) use ($hostPath, $project): string {\n" +" $file = preg_replace('~^/app/~', $hostPath, $file);\n" +" $path = $line === null ? $file : $file . ':' . $line;\n" +"\n" +" return str_replace(\n" +" ['{project}', '{path}'],\n" +" [$project, $path],\n" +" 'jetbrains://phpstorm/navigate/reference?project={project}&path={path}',\n" +" );\n" +" },\n" +" ],\n" +" ],\n" +"];\n" +msgstr "" diff --git a/_translations/po/pt-BR/cookbook_organizing-code_domain.md.po b/_translations/po/pt-BR/cookbook_organizing-code_domain.md.po new file mode 100644 index 00000000..56ecbdbb --- /dev/null +++ b/_translations/po/pt-BR/cookbook_organizing-code_domain.md.po @@ -0,0 +1,192 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-10-11 10:37+0000\n" +"PO-Revision-Date: 2026-10-11 10:37+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/cookbook/organizing-code/domain.md +#, no-wrap +msgid "Domain" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/organizing-code/domain.md +#, no-wrap +msgid "" +"The Domain or domain model is what makes the project unique. With requirements and terminology of the problem being solved\n" +"in mind (the problem context), you build an abstraction that consists of entities, their relationships, and logic that\n" +"operates these entities. To focus on the complex part of the problem, domain is, ideally, separated from\n" +" the infrastructure part of the system (that's how to save data into a database, how to form HTTP response, etc.).\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/organizing-code/domain.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> Such isolation is suitable for complex systems. If your project domain is basically create/read/update/delete\n" +"> for a set of records with not much complex logic, it makes no sense to apply a complex solution to a simple problem.\n" +"> The individual concepts of domain design below could be applied separately, so make sure to check these even if your\n" +"> project isn't that complicated. \n" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/organizing-code/domain.md +#, no-wrap +msgid "Bounded context" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/organizing-code/domain.md +msgid "It's nearly impossible to build a model that solves multiple problems that aren't too complicated by itself. Therefore, it's a good practice to divide the domain into several use-cases and have a separate model for each use-case. Such separated models are called \"bounded contexts.\"" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/organizing-code/domain.md +#, no-wrap +msgid "Building blocks" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/organizing-code/domain.md +msgid "There are various building blocks that are typically used when describing domain models. It isn't mandatory to use them all." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/organizing-code/domain.md +#: ../src/cookbook/organizing-code/service.md +#, no-wrap +msgid "Entity" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/organizing-code/domain.md +msgid "Entity is a uniquely identifiable object such as user, product, payment, etc. When comparing them, you're checking ID, not the attribute values. If there are two objects with different attributes but the same ID, they're considered being the same thing." +msgstr "" + +#. type: Title ### +#: ../src/cookbook/organizing-code/domain.md +#, no-wrap +msgid "Value object" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/organizing-code/domain.md +msgid "Value object describes an object by its characteristics. For example, a price that consists of value and currency. When comparing such objects, you're checking actual values. If they match, an object is considered to be the same." +msgstr "" + +#. type: Title ### +#: ../src/cookbook/organizing-code/domain.md +#, no-wrap +msgid "Aggregate" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/organizing-code/domain.md +msgid "Aggregate is a set of domain objects such as entities and value objects and additional data that could be treated as a single unit. It usually represents a compound object from a domain model such as shop order or HR person dossier." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/organizing-code/domain.md +msgid "One of the components of an aggregate is called a root. The root identifies an aggregate as a whole and should be used to access it." +msgstr "" + +#. type: Title ### +#: ../src/cookbook/organizing-code/domain.md +#, no-wrap +msgid "Domain event" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/organizing-code/domain.md +msgid "An aggregate, while processed, may raise events. For example, when order is confirmed, `OrderConfirmed` event would be risen so other parts of the system may react on these." +msgstr "" + +#. type: Title ### +#: ../src/cookbook/organizing-code/domain.md +#, no-wrap +msgid "Data transfer object" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/organizing-code/domain.md +msgid "Data transfer object or DTO is an object whose only purpose is to hold data as it is. It's commonly used to pass data between different services." +msgstr "" + +#. type: Title ### +#: ../src/cookbook/organizing-code/domain.md +#, no-wrap +msgid "Service" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/organizing-code/domain.md +msgid "Service is a class that contains a standalone operation within the context of your domain model. See \"[service components](service.md)\"." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/organizing-code/domain.md +#: ../src/cookbook/organizing-code/service.md ../src/guide/start/databases.md +#, no-wrap +msgid "Repository" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/organizing-code/domain.md +msgid "The repository task is to abstract away how domain objects are obtained. These are usually separated into two parts: an interface that stays in the domain layer and an implementation that's situated in the infrastructure layer. In such a way, domain doesn't care how data is obtained and saved and may be focused around the complicated business logic instead." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/organizing-code/domain.md +msgid "Repository is usually implemented as a service." +msgstr "" + +#. type: Title ### +#: ../src/cookbook/organizing-code/domain.md +#, no-wrap +msgid "Instantiating building blocks" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/organizing-code/domain.md +msgid "Entity, value object, aggregate, and domain events aren't services and shouldn't be instantiated through DI container. Using `new` is the way to go with these." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/organizing-code/domain.md +#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md +#: ../src/guide/concept/autoloading.md ../src/guide/concept/di-container.md +#: ../src/guide/security/best-practices.md +#: ../src/guide/tutorial/console-applications.md +#: ../src/internals/004-namespaces.md ../src/internals/007-exceptions.md +#: ../src/internals/008-interfaces.md +#, no-wrap +msgid "References" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/organizing-code/domain.md +msgid "[BoundedContext by Martin Fowler](https://martinfowler.com/bliki/BoundedContext.html)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/organizing-code/domain.md +msgid "[ValueObject by Martin Fowler](https://martinfowler.com/bliki/ValueObject.html)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/organizing-code/domain.md +msgid "[Aggregate by Marting Fowler](https://martinfowler.com/bliki/DDD_Aggregate.html)" +msgstr "" diff --git a/_translations/po/pt-BR/cookbook_organizing-code_service.md.po b/_translations/po/pt-BR/cookbook_organizing-code_service.md.po new file mode 100644 index 00000000..d5380918 --- /dev/null +++ b/_translations/po/pt-BR/cookbook_organizing-code_service.md.po @@ -0,0 +1,196 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-10-11 10:37+0000\n" +"PO-Revision-Date: 2026-10-11 10:37+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Bullet: '- ' +#: ../src/cookbook/organizing-code/domain.md +#: ../src/cookbook/organizing-code/service.md +#, no-wrap +msgid "Entity" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/organizing-code/domain.md +#: ../src/cookbook/organizing-code/service.md ../src/guide/start/databases.md +#, no-wrap +msgid "Repository" +msgstr "" + +#. type: Title # +#: ../src/cookbook/organizing-code/service.md +#, no-wrap +msgid "Service components" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/organizing-code/service.md +msgid "Application may get complicated, so it makes sense to extract focused parts of business logic or infrastructure into service components. They're typically injected into other components or action handlers. It's usually done via autowiring:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/organizing-code/service.md +#, no-wrap +msgid "" +"public function actionIndex(CurrentRoute $route, MyService $myService): ResponseInterface\n" +"{\n" +" $id = $route->getArgument('id');\n" +" \n" +" // ...\n" +" $extraData = $myService->getExtraData($id);\n" +" \n" +" // ...\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/organizing-code/service.md +msgid "Yii3 doesn't technically imply any limitations on how you build services. In general, there's no need to extend from a base class or implement a certain interface:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/organizing-code/service.md +#, no-wrap +msgid "" +"final readonly class MyService\n" +"{\n" +" public function __construct(\n" +" private ExtraDataStorage $extraDataStorage\n" +" )\n" +" {\n" +" }\n" +"\n" +" public function getExtraData(string $id): array\n" +" {\n" +" return $this->extraDataStorage->get($id);\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/organizing-code/service.md +msgid "Services either perform a task or return data. They're created once, put into a DI container and then could be used multiple times. Because of that, it's a good idea to keep your services stateless that's both service itself and any of its dependencies shouldn't hold state. You can ensure it by using `readonly` PHP keyword at class level." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/organizing-code/service.md +#, no-wrap +msgid "Service dependencies and configuration" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/organizing-code/service.md +msgid "Services should always define all their dependencies on other services via `__construct()`. It both allows you to use a service right away after it's created and serves as an indicator of a service doing too much if there are too many dependencies." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/organizing-code/service.md +msgid "After the service is created, it shouldn't be re-configured in runtime." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/organizing-code/service.md +msgid "DI container instance usually **shouldn't** be injected as a dependency. Prefer concrete interfaces." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/organizing-code/service.md +msgid "In case of complicated or \"heavy\" initialization, try to postpone it until the service method is called." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/organizing-code/service.md +msgid "The same is valid for configuration values. They should be provided as a constructor argument. Related values could be grouped together into value objects. For example, database connection usually requires DSN string, username and password. These three could be combined into Dsn class:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/organizing-code/service.md +#, no-wrap +msgid "" +"final readonly class Dsn\n" +"{\n" +" public function __construct(\n" +" public string $dsn,\n" +" public string $username,\n" +" public string $password\n" +" )\n" +" {\n" +" if (!$this->isValidDsn($dsn)) {\n" +" throw new \\InvalidArgumentException('DSN provided is not valid.');\n" +" }\n" +" }\n" +" \n" +" private function isValidDsn(string $dsn): bool\n" +" {\n" +" // check DSN validity \n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/organizing-code/service.md +#, no-wrap +msgid "Service methods" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/organizing-code/service.md +msgid "Service method usually does something. It could be a simple thing repeated exactly, but usually it depends on the context. For example:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/organizing-code/service.md +#, no-wrap +msgid "" +"final readonly class PostPersister\n" +"{\n" +" public function __construct(\n" +" private Storage $db\n" +" )\n" +" {\n" +" }\n" +" \n" +" public function persist(Post $post)\n" +" {\n" +" $this->db->insertOrUpdate('post', $post); \n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/organizing-code/service.md +msgid "There's a service that is saving posts into permanent storage such as a database. An object allowing communication with a concrete storage is always the same, so it's injected using constructor while the post saved could vary, so it's passed as a method argument." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/organizing-code/service.md +#, no-wrap +msgid "Is everything a service?" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/organizing-code/service.md +msgid "Often it makes sense to choose another class type to place your code into. Check:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/organizing-code/service.md +msgid "Widget" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/organizing-code/service.md +msgid "[Middleware](middleware.md)" +msgstr "" diff --git a/_translations/po/pt-BR/cookbook_organizing-code_structuring-by-use-case-with-vertical-slices.md.po b/_translations/po/pt-BR/cookbook_organizing-code_structuring-by-use-case-with-vertical-slices.md.po new file mode 100644 index 00000000..97ef749d --- /dev/null +++ b/_translations/po/pt-BR/cookbook_organizing-code_structuring-by-use-case-with-vertical-slices.md.po @@ -0,0 +1,119 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-10-11 10:37+0000\n" +"PO-Revision-Date: 2026-10-11 10:37+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/cookbook/organizing-code/domain.md +#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md +#: ../src/guide/concept/autoloading.md ../src/guide/concept/di-container.md +#: ../src/guide/security/best-practices.md +#: ../src/guide/tutorial/console-applications.md +#: ../src/internals/004-namespaces.md ../src/internals/007-exceptions.md +#: ../src/internals/008-interfaces.md +#, no-wrap +msgid "References" +msgstr "" + +#. type: Title # +#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md +#, no-wrap +msgid "Structuring code by use-case with vertical slices" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md +msgid "When building an application, it's important to organize the code in a way that makes it easy to understand, support, and scale. One popular approach is to structure the code by use-case with vertical slices." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md +msgid "Vertical slices are self-contained pieces of functionality that cover the entire stack, from the user interface to the data access layer. Developer organizes each slice around a specific use case, such as creating a new user or updating a product." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md +msgid "When structuring code classically by type (such as models, views, controllers, helpers, etc.), it can be easy to lose sight of the bigger picture and how different pieces of code interact to support specific features or use cases. This can lead to code duplication, tight coupling, and poor maintainability as the application grows." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md +msgid "On the other hand, structuring code by use-case makes developers focus on a specific feature or workflow and understand how different pieces of code work together to support that feature. This approach also helps to keep related code together in a single directory, making it easier to navigate and support. Vertical slicing also encourages the use of domain-driven design concepts, such as entities, repositories, and services, which can help to promote good separation of concerns and modularity." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md +msgid "Additionally, structuring code by use-case can make it easier to test and debug the application since use-case namespace encapsulates each feature or workflow in its own directory with clear boundaries and well-defined interfaces." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md +msgid "Here's an example directory structure for a PHP application organized using vertical slices:" +msgstr "" + +#. type: Fenced code block +#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md +#, no-wrap +msgid "" +"src/\n" +"└── Blog/\n" +" ├── Model/\n" +" │ ├── Comment.php\n" +" │ ├── CommentRepository.php\n" +" │ ├── Post.php\n" +" │ └── PostRepository.php\n" +" ├── Service/ \n" +" │ └── MarkdownProcessor.php\n" +" ├── UseCase/\n" +" │ ├── CreateComment/\n" +" │ │ ├── CreateCommentAction.php\n" +" │ │ ├── CreateCommentRequest.php\n" +" │ ├── CreatePost/\n" +" │ │ ├── CreatePostAction.php\n" +" │ │ ├── CreatePostRequest.php\n" +" │ ├── DeleteComment/\n" +" │ │ ├── DeleteCommentAction.php\n" +" │ │ ├── DeleteCommentRequest.php\n" +" │ ├── DeletePost/\n" +" │ │ ├── DeletePostAction.php\n" +" │ │ ├── DeletePostRequest.php\n" +" │ ├── ListComments/\n" +" │ │ ├── ListCommentsAction.php\n" +" │ ├── ListPosts/\n" +" │ │ ├── ListPostsAction.php\n" +" │ ├── UpdatePost/\n" +" │ │ ├── UpdatePostAction.php\n" +" │ │ ├── UpdatePostRequest.php\n" +" │ ├── ViewPost/\n" +" │ │ ├── ViewPostAction.php\n" +" │ ├── Rss/\n" +" │ │ ├── RssAction.php\n" +" | | ├── RssBuilder.php\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md +msgid "Each vertical slice has its own directory, which has code associated with the use case." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md +msgid "The use-case subdirectories and their respective classes are organized by type within each directory, omitting a directory if there's a single class of the type. If code is shared between multiple use-cases, it's moved one level up such as `Model` or `Service`." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md +msgid "[Application structure overview](../../guide/structure/overview.md)" +msgstr "" diff --git a/_translations/po/pt-BR/cookbook_preface.md.po b/_translations/po/pt-BR/cookbook_preface.md.po new file mode 100644 index 00000000..a761945f --- /dev/null +++ b/_translations/po/pt-BR/cookbook_preface.md.po @@ -0,0 +1,80 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-12-24 08:02+0000\n" +"PO-Revision-Date: 2025-12-24 08:02+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/en/cookbook/deployment/docker-swarm.md ../src/en/cookbook/preface.md +#, no-wrap +msgid "Prerequisites" +msgstr "" + +#. type: Title # +#: ../src/en/cookbook/preface.md +#, no-wrap +msgid "Preface" +msgstr "" + +#. type: Plain text +#: ../src/en/cookbook/preface.md ../src/en/guide/intro/what-is-yii.md +msgid "Yii is a high-performance, package-based PHP framework for developing modern applications. The name Yii (pronounced `Yee` or `[ji:]`) means \"simple and evolutionary\" in Chinese. You can also think about it as an acronym for **Yes It Is**!" +msgstr "O Yii é um framework PHP de alto desempenho, baseado em pacotes, para desenvolver aplicações modernas. O nome Yii (pronuncia-se `Yee` ou `[ji:]`) significa \"simples e evolutivo\" em chinês. Você também pode pensar nele como um acrônimo de **Yes It Is**!" + +#. type: Plain text +#: ../src/en/cookbook/preface.md ../src/en/guide/intro/what-is-yii.md +msgid "Yii is a generic Web programming framework. You can use it for developing all kinds of Web applications using PHP. Because of its architecture and sophisticated caching support, it's especially suitable for developing large-scale applications such as portals, content management systems, e-commerce, REST APIs, etc." +msgstr "O Yii é um framework genérico de programação web. Você pode usá-lo para desenvolver todo tipo de aplicação web com PHP. Por causa da sua arquitetura e do suporte sofisticado a cache, ele é especialmente indicado para aplicações de grande porte, como portais, sistemas de gerenciamento de conteúdo, e-commerce, APIs REST etc." + +#. type: Plain text +#: ../src/en/cookbook/preface.md +msgid "With comprehensive documentation and an enthusiastic user community, Yii can significantly reduce your development time in the long run." +msgstr "" + +#. type: Title ## +#: ../src/en/cookbook/preface.md +#, no-wrap +msgid "What's the book about" +msgstr "" + +#. type: Plain text +#: ../src/en/cookbook/preface.md +msgid "This book is for you if you're familiar with Yii3, building Yii applications, and read the official Yii3 guide. It covers fundamentally important development concepts, application architecture approaches, integrating third party services with Yii3, etc." +msgstr "" + +#. type: Plain text +#: ../src/en/cookbook/preface.md +msgid "The book consists of individual recipes gathered from Yii experts that you can apply in your applications. These go by topic, but you are free to read them in any order as there is no dependency between them." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/cookbook/preface.md +msgid "You should have Yii3 installed." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/cookbook/preface.md +msgid "You should be familiar with the framework basics and the official guide." +msgstr "" + +#. type: Title ## +#: ../src/en/cookbook/preface.md +#, no-wrap +msgid "How to participate" +msgstr "" + +#. type: Plain text +#: ../src/en/cookbook/preface.md +msgid "If you've found any errata, wrong information, want to improve something or have a good recipe, create an issue or make a pull request in [the book GitHub repository](https://github.com/yiisoft/docs)." +msgstr "" diff --git a/_translations/po/pt-BR/cookbook_sentry-integration.md.po b/_translations/po/pt-BR/cookbook_sentry-integration.md.po new file mode 100644 index 00000000..7d7bed24 --- /dev/null +++ b/_translations/po/pt-BR/cookbook_sentry-integration.md.po @@ -0,0 +1,250 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-12-24 08:02+0000\n" +"PO-Revision-Date: 2025-12-24 08:02+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/en/cookbook/making-http-requests.md +#: ../src/en/cookbook/sentry-integration.md +#: ../src/en/guide/tutorial/using-yii-with-roadrunner.md +#: ../src/en/guide/tutorial/using-yii-with-swoole.md +#: ../src/en/guide/views/asset.md ../src/en/guide/views/view.md +#: ../src/en/guide/views/widget.md +#, no-wrap +msgid "Installation" +msgstr "" + +#. type: Title # +#: ../src/en/cookbook/sentry-integration.md +#, no-wrap +msgid "Sentry integration" +msgstr "" + +#. type: Title ## +#: ../src/en/cookbook/sentry-integration.md +#, no-wrap +msgid "What is Sentry" +msgstr "" + +#. type: Plain text +#: ../src/en/cookbook/sentry-integration.md +#, no-wrap +msgid "" +"[Sentry](https://sentry.io/) is a tool for monitoring and debugging application stability and performance.\n" +"Sentry gives you access to the events that you send there from your application.\n" +msgstr "" + +#. type: Plain text +#: ../src/en/cookbook/sentry-integration.md +msgid "Most often, Sentry is used for monitoring errors (exceptions). You can enrich errors with context to better understand the problem: - Request arguments - Tags for grouping exceptions - Environment state: environment variables, application state, and other global attributes" +msgstr "" + +#. type: Plain text +#: ../src/en/cookbook/sentry-integration.md +msgid "You can find the full list of features on the official website: https://sentry.io/welcome/" +msgstr "" + +#. type: Title ### +#: ../src/en/cookbook/sentry-integration.md +#, no-wrap +msgid "Install the package" +msgstr "" + +#. type: Plain text +#: ../src/en/cookbook/sentry-integration.md +msgid "Install the required package `yiisoft/yii-sentry` with the following command:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/en/cookbook/sentry-integration.md +#, no-wrap +msgid "composer require yiisoft/yii-sentry --prefer-dist\n" +msgstr "" + +#. type: Title ### +#: ../src/en/cookbook/sentry-integration.md +#, no-wrap +msgid "Install an HTTP driver" +msgstr "" + +#. type: Plain text +#: ../src/en/cookbook/sentry-integration.md +msgid "The [`getsentry/sentry-php`](https://github.com/getsentry/sentry-php) library requires the `php-http/httplug` package and any HTTP driver. In the example below we’ll use the Guzzle adapter." +msgstr "" + +#. type: Plain text +#: ../src/en/cookbook/sentry-integration.md +#, no-wrap +msgid "> You can find the list of all adapters on [this page](https://docs.php-http.org/en/latest/clients.html#clients-adapters).\n" +msgstr "" + +#. type: Plain text +#: ../src/en/cookbook/sentry-integration.md +msgid "To install the packages, run the following command:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/en/cookbook/sentry-integration.md +#, no-wrap +msgid "composer require php-http/httplug php-http/guzzle7-adapter --prefer-dist\n" +msgstr "" + +#. type: Title ## +#: ../src/en/cookbook/sentry-integration.md +#: ../src/en/guide/concept/configuration.md +#: ../src/en/guide/tutorial/using-yii-with-roadrunner.md +#: ../src/en/guide/views/view-injections.md +#, no-wrap +msgid "Configuration" +msgstr "" + +#. type: Title ### +#: ../src/en/cookbook/sentry-integration.md +#, no-wrap +msgid "Get and store the token" +msgstr "" + +#. type: Plain text +#: ../src/en/cookbook/sentry-integration.md +msgid "Next, configure the application." +msgstr "" + +#. type: Plain text +#: ../src/en/cookbook/sentry-integration.md +msgid "First, register at [Sentry](https://sentry.io) and create a project." +msgstr "" + +#. type: Plain text +#: ../src/en/cookbook/sentry-integration.md +msgid "Then, in the project settings on the “General Settings” tab, find the “Security Token” field and copy its value." +msgstr "" + +#. type: Plain text +#: ../src/en/cookbook/sentry-integration.md +#, no-wrap +msgid "" +"Now put this token into the package configuration. By default, the config is located at `config/packages/yiisoft/yii-sentry/config/params.php`.\n" +"Set the copied token as the value of the array element at `yiisoft/yii-sentry` => `options` => `dsn`. Example:\n" +msgstr "" + +#. type: Fenced code block (diff) +#: ../src/en/cookbook/sentry-integration.md +#, no-wrap +msgid "" +"'yiisoft/yii-sentry' => [\n" +" 'enabled' => true,\n" +" 'options' => [\n" +"- 'dsn' => '',\n" +"+ 'dsn' => 'TOKEN',\n" +" ],\n" +"],\n" +msgstr "" + +#. type: Title ### +#: ../src/en/cookbook/sentry-integration.md +#, no-wrap +msgid "Configure the HTTP client" +msgstr "" + +#. type: Plain text +#: ../src/en/cookbook/sentry-integration.md +msgid "After installing the HTTP client, configure it." +msgstr "" + +#. type: Plain text +#: ../src/en/cookbook/sentry-integration.md +msgid "Create the file `config/common/sentry.php` and put the following code into it:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/en/cookbook/sentry-integration.md +#, no-wrap +msgid "" +" \\GuzzleHttp\\Client::class,\n" +" \\Http\\Client\\HttpAsyncClient::class => [\n" +" 'class' => \\Http\\Adapter\\Guzzle7\\Client::class,\n" +" '__construct()' => [\n" +" \\Yiisoft\\Factory\\Definition\\Reference::to(\\Http\\Client\\HttpClient::class),\n" +" ],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Title # +#: ../src/en/cookbook/sentry-integration.md +#, no-wrap +msgid "Integration" +msgstr "" + +#. type: Title ### +#: ../src/en/cookbook/sentry-integration.md +#, no-wrap +msgid "Web" +msgstr "" + +#. type: Plain text +#: ../src/en/cookbook/sentry-integration.md +msgid "Sentry support for `web` is implemented as middleware." +msgstr "" + +#. type: Plain text +#: ../src/en/cookbook/sentry-integration.md +msgid "That means you only need to add `SentryMiddleware` to the global middleware list in `config/web/application.php`:" +msgstr "" + +#. type: Fenced code block (diff) +#: ../src/en/cookbook/sentry-integration.md +#, no-wrap +msgid "" +"return [\n" +" Yiisoft\\Yii\\Web\\Application::class => [\n" +" '__construct()' => [\n" +" 'dispatcher' => DynamicReference::to(static function (Injector $injector) {\n" +" return ($injector->make(MiddlewareDispatcher::class))\n" +" ->withMiddlewares(\n" +" [\n" +" Router::class,\n" +" SubFolder::class,\n" +"+ SentryMiddleware::class,\n" +" ErrorCatcher::class,\n" +" ]\n" +" );\n" +" }),\n" +" 'fallbackHandler' => Reference::to(NotFoundHandler::class),\n" +" ],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Title ## +#: ../src/en/cookbook/sentry-integration.md ../src/en/internals/003-roadmap.md +#, no-wrap +msgid "Console" +msgstr "" + +#. type: Plain text +#: ../src/en/cookbook/sentry-integration.md +msgid "Sentry supports `console` via a handler for the [ConsoleEvents::ERROR](https://symfony.com/doc/current/components/console/events.html#the-consoleevents-error-event) event." +msgstr "" + +#. type: Plain text +#: ../src/en/cookbook/sentry-integration.md +msgid "The package provides a configuration file that automatically subscribes the application to this event." +msgstr "" diff --git a/_translations/po/pt-BR/cookbook_third-party-integrations_index.md.po b/_translations/po/pt-BR/cookbook_third-party-integrations_index.md.po new file mode 100644 index 00000000..7a826276 --- /dev/null +++ b/_translations/po/pt-BR/cookbook_third-party-integrations_index.md.po @@ -0,0 +1,52 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-10-07 20:23+0000\n" +"PO-Revision-Date: 2026-10-07 20:23+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Bullet: '- ' +#: ../src/cookbook/index.md ../src/cookbook/third-party-integrations/index.md +msgid "Yii core team members curate and edit it." +msgstr "Membros do time principal do Yii fazem a curadoria e a edição." + +#. type: Plain text +#: ../src/cookbook/index.md ../src/cookbook/third-party-integrations/index.md +msgid "Feel free to pull-request your own writings. Team members will review it, give feedback and merge the best possible way." +msgstr "Fique à vontade para enviar seus próprios textos via pull request. Os membros do time vão revisar, dar feedback e fazer o merge da melhor forma possível." + +#. type: Title # +#: ../src/cookbook/third-party-integrations/index.md +#, no-wrap +msgid "Third-Party Integrations" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/third-party-integrations/index.md +msgid "This is a collection of community-contributed guides for integrating third-party packages with Yii3." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/third-party-integrations/index.md +msgid "The Yii community creates the guides." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/third-party-integrations/index.md +msgid "[Symfony Messenger integration guide](symfony-messenger-integration-guide.md)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/third-party-integrations/index.md +msgid "[Symfony Scheduler integration guide](symfony-scheduler-integration-guide.md)" +msgstr "" diff --git a/_translations/po/pt-BR/cookbook_third-party-integrations_symfony-messenger-integration-guide.md.po b/_translations/po/pt-BR/cookbook_third-party-integrations_symfony-messenger-integration-guide.md.po new file mode 100644 index 00000000..b2f94256 --- /dev/null +++ b/_translations/po/pt-BR/cookbook_third-party-integrations_symfony-messenger-integration-guide.md.po @@ -0,0 +1,471 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-09-25 14:35+0000\n" +"PO-Revision-Date: 2026-09-25 14:35+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/cookbook/making-http-requests.md +#: ../src/cookbook/sentry-integration.md +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#: ../src/guide/tutorial/using-yii-with-swoole.md ../src/guide/views/asset.md +#: ../src/guide/views/view.md ../src/guide/views/widget.md +#, no-wrap +msgid "Installation" +msgstr "" + +#. type: Title # +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#, no-wrap +msgid "Symfony Messenger integration guide" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +msgid "The [Symfony Messenger](https://symfony.com/doc/current/components/messenger.html) component helps applications send and receive messages to/from other applications or via message queues." +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#, no-wrap +msgid "composer require symfony/messenger\n" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#, no-wrap +msgid "How to use with Yii" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#, no-wrap +msgid "1. Create a Message and Handler." +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#, no-wrap +msgid "" +"namespace App\\Messages;\n" +"\n" +"final readonly class MyMessage\n" +"{\n" +" public function __construct(public string $content)\n" +" {\n" +" }\n" +"}\n" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#, no-wrap +msgid "" +"namespace App\\Messages;\n" +"\n" +"use Psr\\Log\\LoggerInterface;\n" +"\n" +"final readonly class MyMessageHandler\n" +"{\n" +" public function __construct(private LoggerInterface $logger)\n" +" {\n" +" }\n" +" public function __invoke(MyMessage $message): void\n" +" {\n" +" // ...\n" +" $this->logger->info(\"The message with the content '$message->content' has been received.\");\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#, no-wrap +msgid "2. Implement the ServiceProviderInterface." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +msgid "This instance of the ServiceProviderInterface is used to configure certain Symfony Messenger commands." +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#, no-wrap +msgid "" +"namespace App\\Services;\n" +"\n" +"use Psr\\Container\\ContainerInterface;\n" +"use Symfony\\Contracts\\Service\\ServiceProviderInterface;\n" +"\n" +"final readonly class ServiceProvider implements ServiceProviderInterface\n" +"{\n" +" /**\n" +" * @param ContainerInterface $container\n" +" * @param array $serviceMap\n" +" */\n" +" public function __construct(\n" +" private ContainerInterface $container,\n" +" private array $serviceMap)\n" +" {\n" +" }\n" +"\n" +" /**\n" +" * @inheritDoc\n" +" */\n" +" public function get(string $id): mixed\n" +" {\n" +" return $this->container->get($id);\n" +" }\n" +"\n" +" public function has(string $id): bool\n" +" {\n" +" return $this->container->has($id);\n" +" }\n" +"\n" +" /**\n" +" * @inheritDoc\n" +" */\n" +" public function getProvidedServices(): array\n" +" {\n" +" return $this->serviceMap;\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#, no-wrap +msgid "3. Configure the Symfony Messenger." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +msgid "Example uses the [symfony/doctrine-messenger](https://packagist.org/packages/symfony/doctrine-messenger) package for transport:" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +msgid "Add the Doctrine packages to the `composer.json`:" +msgstr "" + +#. type: Fenced code block (json) +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#, no-wrap +msgid "" +"{\n" +" // ...\n" +" \"require\": {\n" +" // ...\n" +" \"doctrine/orm\": \"^3\",\n" +" \"doctrine/dbal\": \"^4\",\n" +" \"symfony/cache\": \"^7\"\n" +" },\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +msgid "Install Doctrine:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#, no-wrap +msgid "composer install\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +msgid "Configure the Doctrine connection in the `config/common/params.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#, no-wrap +msgid "" +"return [\n" +" // ...\n" +" 'doctrine' => [\n" +" 'paths' => [\n" +" ],\n" +" 'isDevMode' => false,\n" +" 'connection' => [\n" +" 'driver' => 'pdo_mysql',\n" +" 'user' => 'site1',\n" +" 'password' => 'secret',\n" +" 'dbname' => 'site3'\n" +" ]\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +msgid "Install the Symfony Doctrine Messenger package:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#, no-wrap +msgid "composer require symfony/doctrine-messenger\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +msgid "Configure the Doctrine and Symfony Messenger dependencies in the `config/common/di/application.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#, no-wrap +msgid "" +"use App\\Messages\\MyMessage;\n" +"use App\\Messages\\MyMessageHandler;\n" +"use App\\Services\\ServiceProvider;\n" +"use Doctrine\\DBAL\\DriverManager;\n" +"use Doctrine\\ORM\\Configuration;\n" +"use Doctrine\\ORM\\EntityManager;\n" +"use Doctrine\\ORM\\EntityManagerInterface;\n" +"use Doctrine\\ORM\\ORMSetup;\n" +"use Doctrine\\ORM\\Proxy\\ProxyFactory;\n" +"use Doctrine\\ORM\\Tools\\Console\\EntityManagerProvider;\n" +"use Doctrine\\ORM\\Tools\\Console\\EntityManagerProvider\\SingleManagerProvider;\n" +"use Psr\\Cache\\CacheItemPoolInterface;\n" +"use Psr\\Container\\ContainerInterface;\n" +"use Psr\\Log\\LoggerInterface;\n" +"use Symfony\\Component\\Cache\\Adapter\\FilesystemAdapter;\n" +"use Symfony\\Component\\EventDispatcher\\EventDispatcher;\n" +"use Symfony\\Component\\EventDispatcher\\EventDispatcherInterface;\n" +"use Symfony\\Component\\Messenger\\Bridge\\Doctrine\\Transport\\Connection;\n" +"use Symfony\\Component\\Messenger\\Bridge\\Doctrine\\Transport\\DoctrineTransport;\n" +"use Symfony\\Component\\Messenger\\Command\\ConsumeMessagesCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\DebugCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\FailedMessagesRemoveCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\FailedMessagesRetryCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\FailedMessagesShowCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\SetupTransportsCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\StatsCommand;\n" +"use Symfony\\Component\\Messenger\\EventListener\\StopWorkerOnRestartSignalListener;\n" +"use Symfony\\Component\\Messenger\\Handler\\HandlersLocator;\n" +"use Symfony\\Component\\Messenger\\MessageBus;\n" +"use Symfony\\Component\\Messenger\\Middleware\\HandleMessageMiddleware;\n" +"use Symfony\\Component\\Messenger\\Middleware\\SendMessageMiddleware;\n" +"use Symfony\\Component\\Messenger\\RoutableMessageBus;\n" +"use Symfony\\Component\\Messenger\\Transport\\Sender\\SendersLocator;\n" +"use Symfony\\Component\\Messenger\\Transport\\Serialization\\PhpSerializer;\n" +"use Symfony\\Component\\Messenger\\Transport\\Serialization\\SerializerInterface;\n" +"use Symfony\\Contracts\\Service\\ServiceProviderInterface;\n" +"use Yiisoft\\Aliases\\Aliases;\n" +"use Yiisoft\\Definitions\\Reference;\n" +"\n" +"class_alias(MessageBus::class, 'MyMessageBus');\n" +"\n" +"return [\n" +" // ...\n" +" CacheItemPoolInterface::class => static function (ContainerInterface $container) {\n" +" return new FilesystemAdapter(directory: $container->get(Aliases::class)->get('@runtime'));\n" +" }, //One of the following adapters can be used instead: Psr16Adapter, RedisAdapter, MemcachedAdapter, DoctrineDbalAdapter, and so forth.\n" +"\n" +" Configuration::class => static function (ContainerInterface $container) use ($params) {\n" +" $config = ORMSetup::createAttributeMetadataConfiguration( // on PHP >= 8.4, use ORMSetup::createAttributeMetadataConfig()\n" +" paths: $params['doctrine']['paths'],\n" +" isDevMode: $params['doctrine']['isDevMode'],\n" +" cache: $container->get(CacheItemPoolInterface::class));\n" +" $config->setAutoGenerateProxyClasses(ProxyFactory::AUTOGENERATE_FILE_NOT_EXISTS_OR_CHANGED);\n" +" return $config;\n" +" },\n" +"\n" +" EntityManagerInterface::class => static function (ContainerInterface $container) use ($params) {\n" +" $configuration = $container->get(Configuration::class);\n" +" return new EntityManager(\n" +" DriverManager::getConnection(\n" +" $params['doctrine']['connection'],\n" +" $configuration\n" +" ),\n" +" $configuration);\n" +" },\n" +" EntityManagerProvider::class => SingleManagerProvider::class,\n" +"\n" +" SerializerInterface::class => PhpSerializer::class,\n" +" 'DoctrineTransport' => static function (ContainerInterface $container) use ($params) {\n" +" $configuration = $container->get(Configuration::class);\n" +" $connection = new Connection([], DriverManager::getConnection(\n" +" $params['doctrine']['connection'],\n" +" $configuration\n" +" ));\n" +" return new DoctrineTransport($connection, $container->get(SerializerInterface::class));\n" +" },\n" +"\n" +" MyMessageBus::class => static function (ContainerInterface $container) {\n" +" return new MyMessageBus([\n" +" new SendMessageMiddleware(sendersLocator: new SendersLocator([\n" +" MyMessage::class => ['DoctrineTransport']\n" +" ], $container)),\n" +" new HandleMessageMiddleware(new HandlersLocator([\n" +" MyMessage::class => [$container->get(MyMessageHandler::class)]\n" +" ])),\n" +" ]);\n" +" },\n" +"\n" +" EventDispatcherInterface::class => static function (ContainerInterface $container) {\n" +" $eventDispatcher = new EventDispatcher();\n" +" $eventDispatcher->addSubscriber($container->get(StopWorkerOnRestartSignalListener::class));\n" +" return $eventDispatcher;\n" +" },\n" +" ServiceProviderInterface::class => [\n" +" 'class' => ServiceProvider::class,\n" +" '__construct()' => [\n" +" 'container' => Reference::to(ContainerInterface::class),\n" +" 'serviceMap' => [\n" +" 'DoctrineTransport' => DoctrineTransport::class\n" +" ]\n" +" ],\n" +" ],\n" +"\n" +" ConsumeMessagesCommand::class => static function (ContainerInterface $container) {\n" +" return new ConsumeMessagesCommand(\n" +" $container->get(RoutableMessageBus::class),\n" +" $container,\n" +" $container->get(EventDispatcherInterface::class),\n" +" $container->get(LoggerInterface::class),\n" +" array_keys($container->get(ServiceProviderInterface::class)->getProvidedServices())\n" +" );\n" +" },\n" +" DebugCommand::class => [\n" +" '__construct()' => [\n" +" 'mapping' => [\n" +" MyMessageBus::class => [Reference::to(MyMessageHandler::class)]\n" +" ]\n" +" ],\n" +" ],\n" +" FailedMessagesRemoveCommand::class => [\n" +" '__construct()' => [\n" +" 'globalFailureReceiverName' => null,\n" +" 'failureTransports' => Reference::to(ServiceProviderInterface::class)\n" +" ],\n" +" ],\n" +" FailedMessagesRetryCommand::class => [\n" +" '__construct()' => [\n" +" 'globalReceiverName' => null,\n" +" 'failureTransports' => Reference::to(ServiceProviderInterface::class),\n" +" 'messageBus' => Reference::to(MyMessageBus::class),\n" +" 'eventDispatcher' => Reference::to(EventDispatcherInterface::class),\n" +" 'logger' => Reference::to(LoggerInterface::class),\n" +" ],\n" +" ],\n" +" FailedMessagesShowCommand::class => [\n" +" '__construct()' => [\n" +" 'globalFailureReceiverName' => null,\n" +" 'failureTransports' => Reference::to(ServiceProviderInterface::class)\n" +" ],\n" +" ],\n" +" SetupTransportsCommand::class => static function (ContainerInterface $container) {\n" +" return new SetupTransportsCommand(\n" +" $container,\n" +" array_keys($container->get(ServiceProviderInterface::class)->getProvidedServices())\n" +" );\n" +" },\n" +" StatsCommand::class => static function (ContainerInterface $container) {\n" +" return new StatsCommand(\n" +" $container,\n" +" array_keys($container->get(ServiceProviderInterface::class)->getProvidedServices())\n" +" );\n" +" },\n" +"];\n" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#, no-wrap +msgid "4. Integrate the Symfony Messenger commands into the Yii console." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +msgid "Add the commands to `config/console/commands.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#, no-wrap +msgid "" +"use Symfony\\Component\\Messenger\\Command\\ConsumeMessagesCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\DebugCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\FailedMessagesRemoveCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\FailedMessagesRetryCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\FailedMessagesShowCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\SetupTransportsCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\StatsCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\StopWorkersCommand;\n" +"\n" +"return [\n" +" // ...\n" +" 'symfony:messenger:consume' => ConsumeMessagesCommand::class,\n" +" 'symfony:messenger:debug' => DebugCommand::class,\n" +" 'symfony:messenger:failed:remove' => FailedMessagesRemoveCommand::class,\n" +" 'symfony:messenger:failed:retry' => FailedMessagesRetryCommand::class,\n" +" 'symfony:messenger:failed:show' => FailedMessagesShowCommand::class,\n" +" 'symfony:messenger:setup-transports' => SetupTransportsCommand::class,\n" +" 'symfony:messenger:stats' => StatsCommand::class,\n" +" 'symfony:messenger:stop-workers' => StopWorkersCommand::class\n" +"];\n" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#, no-wrap +msgid "5. Dispatch a message." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +msgid "Example:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#, no-wrap +msgid "" +"use App\\Messages\\MyMessage;\n" +"use MyMessageBus;\n" +"use Psr\\Http\\Message\\ResponseInterface;\n" +"\n" +"final readonly class MyController\n" +"{\n" +" public function __construct(private MyMessageBus $bus)\n" +" {\n" +" }\n" +" \n" +" public function sendMessage(): ResponseInterface\n" +" {\n" +" $this->bus->dispatch(new MyMessage('Hello Symfony Messenger!'));\n" +" // ...\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#, no-wrap +msgid "6. Consume messages." +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#, no-wrap +msgid "./yii symfony:messenger:consume DoctrineTransport --bus=MyMessageBus\n" +msgstr "" diff --git a/_translations/po/pt-BR/cookbook_third-party-integrations_symfony-scheduler-integration-guide.md.po b/_translations/po/pt-BR/cookbook_third-party-integrations_symfony-scheduler-integration-guide.md.po new file mode 100644 index 00000000..30edcac1 --- /dev/null +++ b/_translations/po/pt-BR/cookbook_third-party-integrations_symfony-scheduler-integration-guide.md.po @@ -0,0 +1,401 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-10-08 12:04+0000\n" +"PO-Revision-Date: 2026-10-08 12:04+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/cookbook/making-http-requests.md +#: ../src/cookbook/sentry-integration.md +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#: ../src/guide/tutorial/using-yii-with-rapira.md +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#: ../src/guide/tutorial/using-yii-with-swoole.md ../src/guide/views/asset.md +#: ../src/guide/views/view.md ../src/guide/views/widget.md +#, no-wrap +msgid "Installation" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +#, no-wrap +msgid "composer require symfony/messenger\n" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +#, no-wrap +msgid "How to use with Yii" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +#, no-wrap +msgid "1. Create a Message and Handler." +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +#, no-wrap +msgid "" +"namespace App\\Messages;\n" +"\n" +"final readonly class MyMessage\n" +"{\n" +" public function __construct(public string $content)\n" +" {\n" +" }\n" +"}\n" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +#, no-wrap +msgid "" +"namespace App\\Messages;\n" +"\n" +"use Psr\\Log\\LoggerInterface;\n" +"\n" +"final readonly class MyMessageHandler\n" +"{\n" +" public function __construct(private LoggerInterface $logger)\n" +" {\n" +" }\n" +" public function __invoke(MyMessage $message): void\n" +" {\n" +" // ...\n" +" $this->logger->info(\"The message with the content '$message->content' has been received.\");\n" +" }\n" +"}\n" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +#, no-wrap +msgid "" +"namespace App\\Services;\n" +"\n" +"use Psr\\Container\\ContainerInterface;\n" +"use Symfony\\Contracts\\Service\\ServiceProviderInterface;\n" +"\n" +"final readonly class ServiceProvider implements ServiceProviderInterface\n" +"{\n" +" /**\n" +" * @param ContainerInterface $container\n" +" * @param array $serviceMap\n" +" */\n" +" public function __construct(\n" +" private ContainerInterface $container,\n" +" private array $serviceMap)\n" +" {\n" +" }\n" +"\n" +" /**\n" +" * @inheritDoc\n" +" */\n" +" public function get(string $id): mixed\n" +" {\n" +" return $this->container->get($id);\n" +" }\n" +"\n" +" public function has(string $id): bool\n" +" {\n" +" return $this->container->has($id);\n" +" }\n" +"\n" +" /**\n" +" * @inheritDoc\n" +" */\n" +" public function getProvidedServices(): array\n" +" {\n" +" return $this->serviceMap;\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +#, no-wrap +msgid "4. Integrate the Symfony Messenger commands into the Yii console." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +msgid "Add the commands to `config/console/commands.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +#, no-wrap +msgid "" +"use Symfony\\Component\\Messenger\\Command\\ConsumeMessagesCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\DebugCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\FailedMessagesRemoveCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\FailedMessagesRetryCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\FailedMessagesShowCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\SetupTransportsCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\StatsCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\StopWorkersCommand;\n" +"\n" +"return [\n" +" // ...\n" +" 'symfony:messenger:consume' => ConsumeMessagesCommand::class,\n" +" 'symfony:messenger:debug' => DebugCommand::class,\n" +" 'symfony:messenger:failed:remove' => FailedMessagesRemoveCommand::class,\n" +" 'symfony:messenger:failed:retry' => FailedMessagesRetryCommand::class,\n" +" 'symfony:messenger:failed:show' => FailedMessagesShowCommand::class,\n" +" 'symfony:messenger:setup-transports' => SetupTransportsCommand::class,\n" +" 'symfony:messenger:stats' => StatsCommand::class,\n" +" 'symfony:messenger:stop-workers' => StopWorkersCommand::class\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +msgid "Example:" +msgstr "" + +#. type: Title # +#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +#, no-wrap +msgid "Symfony Scheduler integration guide" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +msgid "The [Symfony Scheduler](https://symfony.com/doc/current/scheduler.html) component manages task scheduling within your PHP application, like running a task each night at 3 AM, every two weeks except for holidays or any other custom schedule you might need." +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +#, no-wrap +msgid "composer require symfony/scheduler\n" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +#, no-wrap +msgid "2. Attaching Recurring Messages to a Schedule." +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +#, no-wrap +msgid "" +"namespace App\\Scheduler;\n" +"\n" +"use App\\Messages\\MyMessage;\n" +"use Symfony\\Component\\Scheduler\\RecurringMessage;\n" +"use Symfony\\Component\\Scheduler\\Schedule;\n" +"use Symfony\\Component\\Scheduler\\ScheduleProviderInterface;\n" +"\n" +"class MyScheduleProvider implements ScheduleProviderInterface\n" +"{\n" +" public function getSchedule(): Schedule\n" +" {\n" +" return (new Schedule())\n" +" ->with(\n" +" RecurringMessage::every(\n" +" '10 seconds',\n" +" new MyMessage('Hello Symfony Scheduler!'))\n" +" );\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +#, no-wrap +msgid "3. Configure the Symfony Scheduler." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +msgid "Depending on your needs, the Symfony Scheduler component offers two ways to consume messages: using the `messenger:consume` command or [creating a worker programmatically](https://symfony.com/doc/current/scheduler.html#creating-a-consumer-programmatically). The example uses the [symfony/messenger](https://packagist.org/packages/symfony/messenger) package to consume messages." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +msgid "Install the Symfony Messenger package:" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +msgid "Install the Symfony Cache package:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +#, no-wrap +msgid "composer require symfony/cache\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +msgid "Implement the ServiceProviderInterface. This instance of the ServiceProviderInterface is used to configure certain Symfony Messenger commands." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +msgid "Configure the Symfony Scheduler and Symfony Messenger dependencies in the `config/common/di/application.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +#, no-wrap +msgid "" +"use App\\Messages\\MyMessage;\n" +"use App\\Messages\\MyMessageHandler;\n" +"use App\\Scheduler\\MyScheduleProvider;\n" +"use App\\Services\\ServiceProvider;\n" +"use Psr\\Cache\\CacheItemPoolInterface;\n" +"use Psr\\Container\\ContainerInterface;\n" +"use Psr\\EventDispatcher\\EventDispatcherInterface;\n" +"use Psr\\Log\\LoggerInterface;\n" +"use Symfony\\Component\\Cache\\Adapter\\FilesystemAdapter;\n" +"use Symfony\\Component\\EventDispatcher\\EventDispatcher;\n" +"use Symfony\\Component\\Messenger\\Command\\ConsumeMessagesCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\DebugCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\FailedMessagesRemoveCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\FailedMessagesRetryCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\FailedMessagesShowCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\SetupTransportsCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\StatsCommand;\n" +"use Symfony\\Component\\Messenger\\EventListener\\StopWorkerOnRestartSignalListener;\n" +"use Symfony\\Component\\Messenger\\Handler\\HandlersLocator;\n" +"use Symfony\\Component\\Messenger\\MessageBus;\n" +"use Symfony\\Component\\Messenger\\Middleware\\HandleMessageMiddleware;\n" +"use Symfony\\Component\\Messenger\\RoutableMessageBus;\n" +"use Symfony\\Component\\Scheduler\\Generator\\MessageGenerator;\n" +"use Symfony\\Component\\Scheduler\\Messenger\\SchedulerTransport;\n" +"use Symfony\\Contracts\\Service\\ServiceProviderInterface;\n" +"use Yiisoft\\Aliases\\Aliases;\n" +"use Yiisoft\\Definitions\\Reference;\n" +"\n" +"class_alias(MessageBus::class, 'MyMessageBus');\n" +"\n" +"return [\n" +" // ...\n" +" CacheItemPoolInterface::class => static function (ContainerInterface $container) {\n" +" return new FilesystemAdapter(directory: $container->get(Aliases::class)->get('@runtime'));\n" +" }, //One of the following adapters can be used instead: Psr16Adapter, RedisAdapter, MemcachedAdapter, DoctrineDbalAdapter, and so forth.\n" +"\n" +"\n" +" 'SchedulerTransport' => static function () {\n" +" return new SchedulerTransport(\n" +" new MessageGenerator(\n" +" new MyScheduleProvider(),\n" +" 'MySchedule'\n" +" )\n" +" );\n" +" },\n" +"\n" +" MyMessageBus::class => static function (ContainerInterface $container) {\n" +" return new MyMessageBus([\n" +" new HandleMessageMiddleware(new HandlersLocator([\n" +" MyMessage::class => [$container->get(MyMessageHandler::class)]\n" +" ])),\n" +" ]);\n" +" },\n" +"\n" +" EventDispatcherInterface::class => static function (ContainerInterface $container) {\n" +" $eventDispatcher = new EventDispatcher();\n" +" $eventDispatcher->addSubscriber($container->get(StopWorkerOnRestartSignalListener::class));\n" +" return $eventDispatcher;\n" +" },\n" +" ServiceProviderInterface::class => [\n" +" 'class' => ServiceProvider::class,\n" +" '__construct()' => [\n" +" 'container' => Reference::to(ContainerInterface::class),\n" +" 'serviceMap' => [\n" +" 'SchedulerTransport' => SchedulerTransport::class\n" +" ]\n" +" ],\n" +" ],\n" +"\n" +" ConsumeMessagesCommand::class => static function (ContainerInterface $container) {\n" +" return new ConsumeMessagesCommand(\n" +" $container->get(RoutableMessageBus::class),\n" +" $container,\n" +" $container->get(EventDispatcherInterface::class),\n" +" $container->get(LoggerInterface::class),\n" +" array_keys($container->get(ServiceProviderInterface::class)->getProvidedServices())\n" +" );\n" +" },\n" +" DebugCommand::class => [\n" +" '__construct()' => [\n" +" 'mapping' => [\n" +" MyMessageBus::class => [Reference::to(MyMessageHandler::class)]\n" +" ]\n" +" ],\n" +" ],\n" +" FailedMessagesRemoveCommand::class => [\n" +" '__construct()' => [\n" +" 'globalFailureReceiverName' => null,\n" +" 'failureTransports' => Reference::to(ServiceProviderInterface::class)\n" +" ],\n" +" ],\n" +" FailedMessagesRetryCommand::class => [\n" +" '__construct()' => [\n" +" 'globalReceiverName' => null,\n" +" 'failureTransports' => Reference::to(ServiceProviderInterface::class),\n" +" 'messageBus' => Reference::to(MyMessageBus::class),\n" +" 'eventDispatcher' => Reference::to(EventDispatcherInterface::class),\n" +" 'logger' => Reference::to(LoggerInterface::class),\n" +" ],\n" +" ],\n" +" FailedMessagesShowCommand::class => [\n" +" '__construct()' => [\n" +" 'globalFailureReceiverName' => null,\n" +" 'failureTransports' => Reference::to(ServiceProviderInterface::class)\n" +" ],\n" +" ],\n" +" SetupTransportsCommand::class => static function (ContainerInterface $container) {\n" +" return new SetupTransportsCommand(\n" +" $container,\n" +" array_keys($container->get(ServiceProviderInterface::class)->getProvidedServices())\n" +" );\n" +" },\n" +" StatsCommand::class => static function (ContainerInterface $container) {\n" +" return new StatsCommand(\n" +" $container,\n" +" array_keys($container->get(ServiceProviderInterface::class)->getProvidedServices())\n" +" );\n" +" },\n" +"];\n" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +#, no-wrap +msgid "5. Consume messages." +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +#, no-wrap +msgid "./yii symfony:messenger:consume SchedulerTransport --bus=MyMessageBus\n" +msgstr "" diff --git a/_translations/po/pt-BR/cookbook_using-htmx-for-partial-reloads.md.po b/_translations/po/pt-BR/cookbook_using-htmx-for-partial-reloads.md.po new file mode 100644 index 00000000..3a79c896 --- /dev/null +++ b/_translations/po/pt-BR/cookbook_using-htmx-for-partial-reloads.md.po @@ -0,0 +1,541 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-05-09 10:43+0000\n" +"PO-Revision-Date: 2026-05-09 10:43+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/cookbook/using-htmx-for-partial-reloads.md +#, no-wrap +msgid "Using htmx for partial page reloads" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-htmx-for-partial-reloads.md +#, no-wrap +msgid "" +"[htmx](https://htmx.org/) lets links and forms request HTML fragments and swap them into the current page. In a Yii\n" +"application, this works well for grids: sorting, filtering, and pagination can update only the grid while the rest of\n" +"the page stays in place.\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-htmx-for-partial-reloads.md +msgid "This recipe uses `GridView` as an example because it has links and forms that naturally benefit from partial reloads. The same pattern works for any widget or page fragment: render the fragment separately, add htmx attributes to the controls that should refresh it, and return only that fragment for htmx requests." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/using-htmx-for-partial-reloads.md +#, no-wrap +msgid "Install GridView" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-htmx-for-partial-reloads.md +msgid "Install the data view package if the application doesn't use it yet:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/cookbook/using-htmx-for-partial-reloads.md +#, no-wrap +msgid "composer require yiisoft/yii-dataview\n" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/using-htmx-for-partial-reloads.md +#, no-wrap +msgid "Load htmx" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-htmx-for-partial-reloads.md +msgid "The simplest setup is loading htmx from a CDN. Create `src/Web/Shared/Layout/Main/HtmxAsset.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/using-htmx-for-partial-reloads.md +#, no-wrap +msgid "" +" 'sha384-H5SrcfygHmAuTDZphMHqBJLc3FhssKjG7w/CeCpFReSfwBWDTKpkzPP8c+cLsK+V',\n" +" 'crossorigin' => 'anonymous',\n" +" ];\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-htmx-for-partial-reloads.md +msgid "When updating the htmx version, update the URL and `integrity` value together." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-htmx-for-partial-reloads.md +msgid "For production applications, consider serving htmx from your application assets to avoid depending on a third-party CDN. Download `htmx.min.js` into `assets/main/js/htmx.min.js` and use a local asset bundle:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/using-htmx-for-partial-reloads.md +#, no-wrap +msgid "" +" */\n" +" $pagination = OffsetPagination::widget();\n" +"\n" +" return GridView::widget()\n" +" ->containerAttributes([\n" +" 'id' => 'UsersGridView',\n" +" 'class' => 'mt-4 position-relative',\n" +" ])\n" +" ->dataReader($this->dataReader())\n" +" ->pageSizeConstraint(5)\n" +" ->paginationWidget($pagination)\n" +" ->columns(\n" +" new DataColumn('id', header: 'ID', filter: true),\n" +" new DataColumn('login', header: 'Login', filter: true),\n" +" new DataColumn('name', header: 'Name', filter: true),\n" +" new DataColumn('status', header: 'Status', filter: true),\n" +" )\n" +" ->render();\n" +" }\n" +"\n" +" private function dataReader(): IterableDataReader\n" +" {\n" +" return new IterableDataReader([\n" +" ['id' => 1, 'login' => 'admin', 'name' => 'Alice Adams', 'status' => 'Active'],\n" +" ['id' => 2, 'login' => 'editor', 'name' => 'Eve Editor', 'status' => 'Active'],\n" +" ['id' => 3, 'login' => 'author', 'name' => 'Arthur Author', 'status' => 'Active'],\n" +" ['id' => 4, 'login' => 'reviewer', 'name' => 'Rita Reviewer', 'status' => 'Inactive'],\n" +" ['id' => 5, 'login' => 'support', 'name' => 'Sam Support', 'status' => 'Active'],\n" +" ['id' => 6, 'login' => 'guest', 'name' => 'Grace Guest', 'status' => 'Inactive'],\n" +" ]);\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-htmx-for-partial-reloads.md +msgid "For a real application, replace `dataReader()` with a reader backed by a database query or repository. Keep the widget responsible for rendering the grid fragment." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-htmx-for-partial-reloads.md +msgid "Create `src/Web/Users/Index/template.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/using-htmx-for-partial-reloads.md +#, no-wrap +msgid "" +"setTitle('Users');\n" +"?>\n" +"

Users

\n" +"\n" +"\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-htmx-for-partial-reloads.md +msgid "Create `src/Web/Users/Index/Action.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/using-htmx-for-partial-reloads.md +#, no-wrap +msgid "" +"viewRenderer->render(__DIR__ . '/template');\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-htmx-for-partial-reloads.md +msgid "Add the action to `config/common/routes.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/using-htmx-for-partial-reloads.md +#, no-wrap +msgid "" +"routes(\n" +" Route::get('/')\n" +" ->action(Web\\HomePage\\Action::class)\n" +" ->name('home'),\n" +" Route::get('/users')\n" +" ->action(Web\\Users\\Index\\Action::class)\n" +" ->name('users/index'),\n" +" ),\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-htmx-for-partial-reloads.md +msgid "Open `/users` and make sure sorting, filtering, and pagination work with full page reloads first." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/using-htmx-for-partial-reloads.md +#, no-wrap +msgid "Add htmx attributes to the grid" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-htmx-for-partial-reloads.md +msgid "Now update `UsersGrid` so the grid controls request a fragment and swap it into `#UsersGridView`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/using-htmx-for-partial-reloads.md +#, no-wrap +msgid "" +" '#UsersGridView',\n" +" 'hx-target' => '#UsersGridView',\n" +" 'hx-replace-url' => 'true',\n" +" 'hx-swap' => 'outerHTML',\n" +" ];\n" +"\n" +" /** @var PaginationWidgetInterface */\n" +" $pagination = OffsetPagination::widget()->addLinkAttributes([\n" +" 'hx-boost' => 'true',\n" +" ...$htmxLoadAttributes,\n" +" ]);\n" +"\n" +" return GridView::widget()\n" +" ->containerAttributes([\n" +" 'id' => 'UsersGridView',\n" +" 'class' => 'mt-4 position-relative',\n" +" ])\n" +" ->dataReader($this->dataReader())\n" +" ->pageSizeConstraint(5)\n" +" ->sortableLinkAttributes([\n" +" 'hx-boost' => 'true',\n" +" ...$htmxLoadAttributes,\n" +" ])\n" +" ->filterFormAttributes([\n" +" 'hx-boost' => 'true',\n" +" ...$htmxLoadAttributes,\n" +" ])\n" +" ->paginationWidget($pagination)\n" +" ->columns(\n" +" new DataColumn('id', header: 'ID', filter: true),\n" +" new DataColumn('login', header: 'Login', filter: true),\n" +" new DataColumn('name', header: 'Name', filter: true),\n" +" new DataColumn('status', header: 'Status', filter: true),\n" +" )\n" +" ->render();\n" +" }\n" +"\n" +" private function dataReader(): IterableDataReader\n" +" {\n" +" return new IterableDataReader([\n" +" ['id' => 1, 'login' => 'admin', 'name' => 'Alice Adams', 'status' => 'Active'],\n" +" ['id' => 2, 'login' => 'editor', 'name' => 'Eve Editor', 'status' => 'Active'],\n" +" ['id' => 3, 'login' => 'author', 'name' => 'Arthur Author', 'status' => 'Active'],\n" +" ['id' => 4, 'login' => 'reviewer', 'name' => 'Rita Reviewer', 'status' => 'Inactive'],\n" +" ['id' => 5, 'login' => 'support', 'name' => 'Sam Support', 'status' => 'Active'],\n" +" ['id' => 6, 'login' => 'guest', 'name' => 'Grace Guest', 'status' => 'Inactive'],\n" +" ]);\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-htmx-for-partial-reloads.md +msgid "The important part is the shared `$htmxLoadAttributes` array:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/using-htmx-for-partial-reloads.md +msgid "`hx-boost=\"true\"` makes the grid links and filter form send htmx requests." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/using-htmx-for-partial-reloads.md +msgid "`hx-target=\"#UsersGridView\"` tells htmx which element to replace." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/using-htmx-for-partial-reloads.md +msgid "`hx-swap=\"outerHTML\"` replaces the whole grid container with the response." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/using-htmx-for-partial-reloads.md +msgid "`hx-replace-url=\"true\"` keeps the browser URL in sync with the current sort, filter, and page." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/using-htmx-for-partial-reloads.md +msgid "`hx-indicator=\"#UsersGridView\"` marks the grid as the loading indicator element while the request is active." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-htmx-for-partial-reloads.md +msgid "The target selector and the container `id` must match. In this example, both use `UsersGridView`." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/using-htmx-for-partial-reloads.md +#, no-wrap +msgid "Return partial HTML for htmx requests" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-htmx-for-partial-reloads.md +msgid "htmx sends the `HX-Request` header with its requests." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-htmx-for-partial-reloads.md +msgid "In the action, return only the widget when the header is present:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/using-htmx-for-partial-reloads.md +#, no-wrap +msgid "" +"getHeaderLine('HX-Request') === 'true'\n" +" ? $this->htmlResponseFactory->createResponse(UsersGrid::widget())\n" +" : $this->viewRenderer->render(__DIR__ . '/template');\n" +"\n" +" return $response->withAddedHeader('Vary', 'HX-Request');\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-htmx-for-partial-reloads.md +msgid "The `Vary` header matters when a browser, proxy, or CDN caches responses. The same URL can return a full page without `HX-Request` and a fragment with `HX-Request: true`, so caches must keep these responses separate." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/using-htmx-for-partial-reloads.md +#, no-wrap +msgid "Try it" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-htmx-for-partial-reloads.md +msgid "Open the list page and use sorting, filtering, or pagination. The browser URL should change, and only the grid HTML should be replaced." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-htmx-for-partial-reloads.md +msgid "In the browser developer tools, the htmx requests should include the `HX-Request` header. Their responses should contain only the grid container." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-htmx-for-partial-reloads.md +msgid "Use the same pattern for other widgets or page fragments:" +msgstr "" + +#. type: Bullet: '1. ' +#: ../src/cookbook/using-htmx-for-partial-reloads.md +msgid "Put the reloadable HTML into a widget or another small renderer." +msgstr "" + +#. type: Bullet: '2. ' +#: ../src/cookbook/using-htmx-for-partial-reloads.md +msgid "Add htmx attributes to the links and forms that should refresh it." +msgstr "" + +#. type: Bullet: '3. ' +#: ../src/cookbook/using-htmx-for-partial-reloads.md +msgid "Return the fragment for htmx requests and the full page for regular requests." +msgstr "" diff --git a/_translations/po/pt-BR/cookbook_using-yii-in-third-party-apps.md.po b/_translations/po/pt-BR/cookbook_using-yii-in-third-party-apps.md.po new file mode 100644 index 00000000..81c1cba4 --- /dev/null +++ b/_translations/po/pt-BR/cookbook_using-yii-in-third-party-apps.md.po @@ -0,0 +1,289 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-06-05 22:11+0000\n" +"PO-Revision-Date: 2026-06-05 22:11+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Fenced code block (sh) +#: ../src/cookbook/custom-migration-template.md +#: ../src/cookbook/using-yii-in-third-party-apps.md +#: ../src/guide/structure/designing-packages.md +#: ../src/guide/structure/module.md ../src/guide/structure/package.md +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "composer yii-config-rebuild\n" +msgstr "" + +#. type: Title # +#: ../src/cookbook/using-yii-in-third-party-apps.md +#, no-wrap +msgid "Using Yii in third-party applications" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-yii-in-third-party-apps.md +msgid "Sometimes a project already has an entry point owned by another framework, CMS, or legacy application, but you still want to reuse Yii services: configuration, DI definitions, domain services, logging, mailers, database connections, or console-oriented application code." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-yii-in-third-party-apps.md +msgid "Yii3 has no global application singleton. Bootstrap the Yii container explicitly and pass the services you need to the third-party code." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/using-yii-in-third-party-apps.md +#, no-wrap +msgid "Bootstrap the Yii container" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-yii-in-third-party-apps.md +msgid "Create a small adapter in the host application, for example `bootstrap-yii-services.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/using-yii-in-third-party-apps.md +#, no-wrap +msgid "" +"withValidate(Environment::appDebug())\n" +" ->withDefinitions(array_merge(\n" +" $config->get('di-console'),\n" +" [ConfigInterface::class => $config],\n" +" ))\n" +" ->withProviders($config->get('di-providers-console'))\n" +" ->withDelegates($config->get('di-delegates-console'));\n" +"\n" +" if ($config->has('di-tags-console')) {\n" +" $containerConfig = $containerConfig->withTags($config->get('di-tags-console'));\n" +" }\n" +"\n" +" $container = new Container($containerConfig);\n" +"\n" +" foreach ($config->get('bootstrap-console') as $callback) {\n" +" if (!is_callable($callback)) {\n" +" throw new RuntimeException(sprintf(\n" +" 'Bootstrap callback must be callable, \"%s\" given.',\n" +" get_debug_type($callback),\n" +" ));\n" +" }\n" +"\n" +" $callback($container);\n" +" }\n" +"\n" +" return $container;\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-yii-in-third-party-apps.md +msgid "The adapter builds only the Yii configuration and DI container, then runs the configured bootstrap callbacks. It does not create or run a Yii application runner, so the third-party application keeps ownership of the entry point and process lifecycle." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-yii-in-third-party-apps.md +msgid "Use console configuration groups when you need common services and console-safe services. Use web groups instead only when you intentionally need web-specific definitions from the `di-web` group, such as PSR-17 HTTP factories or web middleware dependencies." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/using-yii-in-third-party-apps.md +#, no-wrap +msgid "Get Yii services from the host application" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-yii-in-third-party-apps.md +msgid "Use the adapter from the third-party application:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/cookbook/using-yii-in-third-party-apps.md +#, no-wrap +msgid "" +"get(ApplicationParams::class);\n" +"\n" +"echo $params->name;\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-yii-in-third-party-apps.md +msgid "In real integrations, prefer getting your own application services instead of framework infrastructure. For example, expose `InvoiceSender`, `ReportBuilder`, or `CatalogImporter` from Yii and call that service from the host application." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/using-yii-in-third-party-apps.md +#, no-wrap +msgid "Keep boundaries explicit" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-yii-in-third-party-apps.md +msgid "Avoid mixing request lifecycles. Let the host application continue to own its HTTP request and response. Let Yii provide services that do not assume Yii is handling the current request." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-yii-in-third-party-apps.md +msgid "Good candidates for reuse:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/using-yii-in-third-party-apps.md +msgid "domain services;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/using-yii-in-third-party-apps.md +msgid "repositories and database connections;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/using-yii-in-third-party-apps.md +msgid "mailers and notification services;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/using-yii-in-third-party-apps.md +msgid "loggers;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/using-yii-in-third-party-apps.md +msgid "validators;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/using-yii-in-third-party-apps.md +msgid "queue producers;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/using-yii-in-third-party-apps.md +msgid "command-like application services." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-yii-in-third-party-apps.md +msgid "Avoid pulling in Yii actions, middleware stacks, sessions, CSRF middleware, or view rendering unless the host application explicitly delegates that whole responsibility to Yii." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/using-yii-in-third-party-apps.md +#, no-wrap +msgid "Configuration groups" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-yii-in-third-party-apps.md +msgid "The default application template separates configuration by group:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/using-yii-in-third-party-apps.md +msgid "`di` is shared by web and console entry points;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/using-yii-in-third-party-apps.md +msgid "`di-console` is console-specific and includes `di` in the template;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/using-yii-in-third-party-apps.md +msgid "`di-web` is web-specific and includes `di`;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/cookbook/using-yii-in-third-party-apps.md +msgid "`params-console` and `params-web` extend common `params`." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-yii-in-third-party-apps.md +msgid "Choose the smallest group that contains the services you need. If the host application only needs domain services, keep those definitions in `config/common/di/*.php` so both Yii and the third-party app can use them without web-only dependencies." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-yii-in-third-party-apps.md +msgid "After changing `config/configuration.php`, rebuild the merge plan:" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/using-yii-in-third-party-apps.md +#, no-wrap +msgid "Error handling and logging" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-yii-in-third-party-apps.md +msgid "The host application should remain responsible for top-level error handling. Catch exceptions at the integration boundary when the host app needs to convert them into its own response or error format." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-yii-in-third-party-apps.md +msgid "Yii services can still use `Psr\\Log\\LoggerInterface`. Configure the Yii logger to write to the same destination as the host application or bridge both applications to the same PSR-3 logger." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/using-yii-in-third-party-apps.md +#, no-wrap +msgid "Long-running host processes" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/using-yii-in-third-party-apps.md +msgid "If the third-party application is a worker, daemon, or event-loop server, avoid mutable shared state in services. Yii services resolved from the container are shared by default, so design them as stateless services or create a fresh container for each isolated job when stateful dependencies are unavoidable." +msgstr "" diff --git a/_translations/po/pt-BR/cookbook_working-on-windows.md.po b/_translations/po/pt-BR/cookbook_working-on-windows.md.po new file mode 100644 index 00000000..96c79ebf --- /dev/null +++ b/_translations/po/pt-BR/cookbook_working-on-windows.md.po @@ -0,0 +1,160 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-05-05 22:18+0000\n" +"PO-Revision-Date: 2026-05-05 22:18+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/cookbook/working-on-windows.md +#, no-wrap +msgid "Working on Windows" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/working-on-windows.md +msgid "Yii applications usually run on Linux in production. On Windows, choose a local workflow that stays close to that environment and keeps filesystem performance predictable." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/working-on-windows.md +#, no-wrap +msgid "Recommended setup: WSL" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/working-on-windows.md +msgid "Use [Windows Subsystem for Linux](https://learn.microsoft.com/windows/wsl/) with a Linux distribution such as Ubuntu. Install PHP, Composer, Git, and Make inside WSL, then clone the project into the Linux filesystem:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/cookbook/working-on-windows.md +#, no-wrap +msgid "" +"cd ~\n" +"git clone https://github.com/yiisoft/app.git my-app\n" +"cd my-app\n" +"composer install\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/working-on-windows.md +msgid "Keep the project under the WSL filesystem, for example `/home/user/projects/my-app`. Avoid working from a mounted Windows path such as `/mnt/c/Users/user/projects/my-app`; it is much slower for Composer, tests, and tools that read many small files." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/working-on-windows.md +msgid "You can open the project from Windows editors through the WSL integration. In PhpStorm, open the project from the WSL filesystem. In VS Code, use the WSL extension and open the folder from inside the WSL session." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/working-on-windows.md +#, no-wrap +msgid "Docker with WSL" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/working-on-windows.md +msgid "Docker Desktop with the WSL backend is also a good Windows setup. Keep the project in the WSL filesystem and run Docker commands from WSL:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/cookbook/working-on-windows.md +#, no-wrap +msgid "" +"make build\n" +"make up\n" +"make yii\n" +"make test\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/working-on-windows.md +msgid "This keeps bind mounts fast and gives containers Linux paths that match the tooling used by the Yii application templates." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/working-on-windows.md +msgid "If you need IDE links from debug stack traces, set `APP_HOST_PATH` to the project path that your IDE can open." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/working-on-windows.md +#, no-wrap +msgid "Git Bash" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/working-on-windows.md +msgid "[Git for Windows](https://git-scm.com/downloads/win) installs Git Bash and common Unix tools. It can be enough when you want to run the application directly on Windows without WSL or Docker." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/working-on-windows.md +msgid "Use this option when your project does not depend on Linux-only extensions or shell scripts. Check the same commands you expect contributors to use:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/cookbook/working-on-windows.md +#, no-wrap +msgid "" +"composer install\n" +"composer test\n" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/working-on-windows.md +msgid "If the project uses `make`, Git for Windows includes a Bash environment, but `make` availability depends on your local installation. Install it separately when needed." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/working-on-windows.md +#, no-wrap +msgid "PowerShell and CMD" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/working-on-windows.md +msgid "PowerShell and CMD can run PHP and Composer, but they differ from the common Linux server environment in quoting, environment variables, paths, and shell utilities. Use them for simple commands only." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/working-on-windows.md +msgid "For regular Yii development on Windows, prefer WSL or Docker with WSL." +msgstr "" + +#. type: Title ## +#: ../src/cookbook/working-on-windows.md +#, no-wrap +msgid "Choosing a workflow" +msgstr "" + +#. type: Plain text +#: ../src/cookbook/working-on-windows.md +msgid "Use WSL when you want the closest local match to a Linux server and do not need containers for every service." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/working-on-windows.md +msgid "Use Docker with WSL when you want the application, database, and other services described by Compose files." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/working-on-windows.md +msgid "Use Git Bash for small projects or quick checks that run directly on Windows." +msgstr "" + +#. type: Plain text +#: ../src/cookbook/working-on-windows.md +msgid "Use PowerShell or CMD when the command is known to be platform-neutral." +msgstr "" diff --git a/_translations/po/pt-BR/guide_caching_data.md.po b/_translations/po/pt-BR/guide_caching_data.md.po new file mode 100644 index 00000000..ff3656c5 --- /dev/null +++ b/_translations/po/pt-BR/guide_caching_data.md.po @@ -0,0 +1,335 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" +"PO-Revision-Date: 2025-09-11 10:15+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../../guide/en/caching/data.md +#, no-wrap +msgid "Data caching" +msgstr "" + +#. type: Plain text +#: ../../guide/en/caching/data.md +msgid "Data caching is about storing some PHP variables in a cache and retrieving them later from the cache. It's also the foundation for more advanced caching features, such as [page caching](page.md)." +msgstr "" + +#. type: Plain text +#: ../../guide/en/caching/data.md +msgid "To use cache, install [yiisoft/cache](https://github.com/yiisoft/cache) package:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../../guide/en/caching/data.md +#, no-wrap +msgid "composer require yiisoft/cache\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/caching/data.md +msgid "The following code is a typical usage pattern of data caching, where `$cache` refers to a `Cache` instance from the package:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/caching/data.md +#, no-wrap +msgid "" +"public function getTopProducts(\\Yiisoft\\Cache\\CacheInterface $cache): array\n" +"{\n" +" $key = ['top-products', $count = 10];\n" +" \n" +" // Try retrieving $data from cache.\n" +" $data = $cache->getOrSet($key, function (\\Psr\\SimpleCache\\CacheInterface $cache) use ($count) {\n" +" // Can't find $data in a cache, calculate it from scratch.\n" +" return getTopProductsFromDatabase($count);\n" +" }, 3600);\n" +" \n" +" return $data;\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/caching/data.md +msgid "When cache has data associated with the `$key`, it returns the cached value. Otherwise, it executes the passed anonymous function to calculate the value to cache and return." +msgstr "" + +#. type: Plain text +#: ../../guide/en/caching/data.md +msgid "If the anonymous function requires some data from the outer scope, you can pass it with the `use` statement." +msgstr "" + +#. type: Title ## +#: ../../guide/en/caching/data.md +#, no-wrap +msgid "Cache handlers" +msgstr "" + +#. type: Plain text +#: ../../guide/en/caching/data.md +msgid "The cache service uses [PSR-16](https://www.php-fig.org/psr/psr-16/) compatible cache handlers which represent various cache storages, such as memory, files, and databases." +msgstr "" + +#. type: Plain text +#: ../../guide/en/caching/data.md +msgid "Yii provides the following handlers:" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/caching/data.md +msgid "`NullCache` — a cache placeholder which does no real caching. The purpose of this handler is to simplify the code that needs to check the availability of cache. For example, during development or if the server doesn't have actual cache support, you may configure a cache service to use this handler. When you enable actual cache support, you can switch to using the corresponding cache handler. In both cases, you may use the same code without extra checks." +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/caching/data.md +msgid "`ArrayCache` — provides caching for the current request only by storing the values in an array." +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/caching/data.md +msgid "[APCu](https://github.com/yiisoft/cache-apcu) - uses a PHP [APC](https://secure.php.net/manual/en/book.apc.php) extension. You can consider this option as the fastest one when dealing with cache for a centralized thick application (e.g., one server, no dedicated load balancers, etc.)." +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/caching/data.md +msgid "[Database](https://github.com/yiisoft/cache-db) — uses a database table to store cached data." +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/caching/data.md +msgid "[File](https://github.com/yiisoft/cache-file) — uses standard files to store cached data. This is particularly suitable to cache large chunks of data, such as page content." +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/caching/data.md +msgid "[Memcached](https://github.com/yiisoft/cache-memcached) — uses a PHP [memcached](https://secure.php.net/manual/en/book.memcached.php) extension. You can consider this option as the fastest one when dealing with cache in a distributed application" +msgstr "" + +#. type: Plain text +#: ../../guide/en/caching/data.md +#, no-wrap +msgid "" +" (e.g., with several servers, load balancers, etc.)\n" +"- [Wincache](https://github.com/yiisoft/cache-wincache) — uses PHP [WinCache](https://iis.net/downloads/microsoft/wincache-extension)\n" +" ([see also](https://secure.php.net/manual/en/book.wincache.php)) extension.\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/caching/data.md +msgid "[You could find more handlers at packagist.org](https://packagist.org/providers/psr/simple-cache-implementation)." +msgstr "" + +#. type: Plain text +#: ../../guide/en/caching/data.md +#, no-wrap +msgid "" +"> [!TIP]\n" +"> You may use different cache storage in the same application. A common strategy is:\n" +"> - To use memory-based cache storage to store small but constantly used data (e.g., statistics)\n" +"> - To use file-based or database-based cache storage to store big and less often used data (e.g., page content)\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/caching/data.md +msgid "Cache handlers are usually set up in a [dependency injection container](../concept/di-container.md) so that they can be globally configurable and accessible." +msgstr "" + +#. type: Plain text +#: ../../guide/en/caching/data.md +msgid "Because all cache handlers support the same set of APIs, you can swap the underlying cache handler with a different one. You can do it by reconfiguring the application without modifying the code that uses the cache." +msgstr "" + +#. type: Title ### +#: ../../guide/en/caching/data.md +#, no-wrap +msgid "Cache keys" +msgstr "" + +#. type: Plain text +#: ../../guide/en/caching/data.md +msgid "A key uniquely identifies each data item stored in the cache. When you store a data item, you have to specify a key for it. Later, when you retrieve the data item, you should give the corresponding key." +msgstr "" + +#. type: Plain text +#: ../../guide/en/caching/data.md +msgid "You may use a string or an arbitrary value as a cache key. When a key isn't a string, it will be automatically serialized into a string." +msgstr "" + +#. type: Plain text +#: ../../guide/en/caching/data.md +msgid "A common strategy of defining a cache key is to include all determining factors in terms of an array." +msgstr "" + +#. type: Plain text +#: ../../guide/en/caching/data.md +msgid "When different applications use the same cache storage, you should specify a unique cache key prefix for each application to avoid conflicts of cache keys. You can do this by using `\\Yiisoft\\Cache\\PrefixedCache` decorator:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/caching/data.md +#, no-wrap +msgid "" +"$arrayCacheWithPrefix = new \\Yiisoft\\Cache\\PrefixedCache(new \\Yiisoft\\Cache\\ArrayCache(), 'myapp_');\n" +"$cache = new \\Yiisoft\\Cache\\Cache($arrayCacheWithPrefix);\n" +msgstr "" + +#. type: Title ### +#: ../../guide/en/caching/data.md +#, no-wrap +msgid "Cache expiration" +msgstr "" + +#. type: Plain text +#: ../../guide/en/caching/data.md +msgid "A data item stored in a cache will remain there forever unless it's removed because of some caching policy enforcement. For example, caching space is full and cache storage removes the oldest data. To change this behavior, you can set a TTL parameter when calling a method to store a data item:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/caching/data.md +#, no-wrap +msgid "" +"$ttl = 3600;\n" +"$data = $cache->getOrSet($key, function (\\Psr\\SimpleCache\\CacheInterface $cache) use ($count) {\n" +"return getTopProductsFromDatabase($count);\n" +"}, $ttl);\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/caching/data.md +msgid "The `$ttl` parameter indicates for how many seconds the data item can remain valid in the cache. When you retrieve the data item, if it has passed the expiration time, the method will execute the function and set the resulting value into cache." +msgstr "" + +#. type: Plain text +#: ../../guide/en/caching/data.md +msgid "You may set the default TTL for the cache:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/caching/data.md +#, no-wrap +msgid "$cache = new \\Yiisoft\\Cache\\Cache($arrayCache, 60 * 60); // 1 hour\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/caching/data.md +msgid "Additionally, you can invalidate a cache key explicitly:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/caching/data.md +#, no-wrap +msgid "$cache->remove($key);\n" +msgstr "" + +#. type: Title ### +#: ../../guide/en/caching/data.md +#, no-wrap +msgid "Invalidation dependencies" +msgstr "" + +#. type: Plain text +#: ../../guide/en/caching/data.md +msgid "Besides the expiration setting, changes of the so-called **invalidation dependencies** may also invalidate cached data item. For example, `\\Yiisoft\\Cache\\Dependency\\FileDependency` represents the dependency of a file's modification time. When this dependency changes, it means something modifying the corresponding file. As a result, any outdated file content found in the cache should invalidate." +msgstr "" + +#. type: Plain text +#: ../../guide/en/caching/data.md +msgid "Cache dependencies are objects of `\\Yiisoft\\Cache\\Dependency\\Dependency` descendant classes. When you store a data item in the cache, you can pass along an associated cache dependency object. For example," +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/caching/data.md +#, no-wrap +msgid "" +"/**\n" +" * @var callable $callable\n" +" * @var \\Yiisoft\\Cache\\CacheInterface $cache\n" +" */\n" +"\n" +"use Yiisoft\\Cache\\Dependency\\TagDependency;\n" +"\n" +"// Set many cache values marking both with a tag.\n" +"$cache->getOrSet('item_42_price', $callable, null, new TagDependency('item_42'));\n" +"$cache->getOrSet('item_42_total', $callable, 3600, new TagDependency('item_42'));\n" +"\n" +"// Trigger invalidation by tag.\n" +"TagDependency::invalidate($cache, 'item_42');\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/caching/data.md +msgid "Below is a summary of the available cache dependencies:" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/caching/data.md +msgid "`\\Yiisoft\\Cache\\Dependency\\ValueDependency`: invalidates the cache when specified value changes." +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/caching/data.md +msgid "`\\Yiisoft\\Cache\\Dependency\\CallbackDependency`: invalidates the cache when the result of the specified PHP callback is different." +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/caching/data.md +msgid "`\\Yiisoft\\Cache\\Dependency\\FileDependency`: invalidates the cache when the file's last modification time is different." +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/caching/data.md +msgid "`\\Yiisoft\\Cache\\Dependency\\TagDependency`: associates a cached data item with one or many tags. You may invalidate the cached data items with the specified tag(s) by calling `TagDependency::invalidate()`." +msgstr "" + +#. type: Plain text +#: ../../guide/en/caching/data.md +msgid "You may combine many dependencies using `\\Yiisoft\\Cache\\Dependency\\AnyDependency` or `\\Yiisoft\\Cache\\Dependency\\AllDependencies`." +msgstr "" + +#. type: Plain text +#: ../../guide/en/caching/data.md +msgid "To implement your own dependency, extend from `\\Yiisoft\\Cache\\Dependency\\Dependency`." +msgstr "" + +#. type: Title ### +#: ../../guide/en/caching/data.md +#, no-wrap +msgid "Cache stampede prevention" +msgstr "" + +#. type: Plain text +#: ../../guide/en/caching/data.md +msgid "[A cache stampede](https://en.wikipedia.org/wiki/Cache_stampede) is a type of cascading failure that can occur when massively parallel computing systems with caching mechanisms come under a high load. This behavior is sometimes also called dog-piling." +msgstr "" + +#. type: Plain text +#: ../../guide/en/caching/data.md +msgid "The `\\Yiisoft\\Cache\\Cache` uses a built-in \"Probably early expiration\" algorithm that prevents cache stampede. This algorithm randomly fakes a cache miss for one user while others are still served the cached value. You can control its behavior with the fifth optional parameter of `getOrSet()`, which is a float value called `$beta`. By default, beta is `1.0`, which is usually enough. The higher the value, the earlier cache will be re-created." +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/caching/data.md +#, no-wrap +msgid "" +"/**\n" +" * @var mixed $key\n" +" * @var callable $callable\n" +" * @var \\DateInterval $ttl\n" +" * @var \\Yiisoft\\Cache\\CacheInterface $cache\n" +" * @var \\Yiisoft\\Cache\\Dependency\\Dependency $dependency\n" +" */\n" +"\n" +"$beta = 2.0;\n" +"$cache->getOrSet($key, $callable, $ttl, $dependency, $beta);\n" +msgstr "" diff --git a/_translations/po/pt-BR/guide_caching_overview.md.po b/_translations/po/pt-BR/guide_caching_overview.md.po new file mode 100644 index 00000000..14eb082d --- /dev/null +++ b/_translations/po/pt-BR/guide_caching_overview.md.po @@ -0,0 +1,57 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-12-24 08:23+0000\n" +"PO-Revision-Date: 2025-12-24 08:23+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/guide/caching/overview.md ../src/guide/index.md +#, no-wrap +msgid "Caching" +msgstr "Cache" + +#. type: Plain text +#: ../src/guide/caching/overview.md +msgid "Caching is an inexpensive and effective way to improve the performance of an application. By storing relatively static data in cache and serving it from cache when requested, the application saves the time that it otherwise would require to generate the data from scratch every time." +msgstr "" + +#. type: Plain text +#: ../src/guide/caching/overview.md +msgid "Caching can occur at different levels and places in an application. On the server-side, at the lower level, cache may be used to store basic data, such as a list of most recent article information fetched from the database; and at the higher level, cache may be used to store fragments or whole of Web pages, such as the rendering result of the most recent articles. On the client-side, you may use HTTP caching to keep most recently visited page content in the browser cache." +msgstr "" + +#. type: Plain text +#: ../src/guide/caching/overview.md +msgid "Yii supports all these caching mechanisms:" +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/caching/overview.md +msgid "[Data caching](data.md)" +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/caching/overview.md +msgid "[Fragment caching](fragment.md)" +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/caching/overview.md +msgid "[Page caching](page.md)" +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/caching/overview.md +msgid "[HTTP caching](http.md)" +msgstr "" diff --git a/_translations/po/pt-BR/guide_concept_aliases.md.po b/_translations/po/pt-BR/guide_concept_aliases.md.po new file mode 100644 index 00000000..22f6e2cc --- /dev/null +++ b/_translations/po/pt-BR/guide_concept_aliases.md.po @@ -0,0 +1,274 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-06-05 20:33+0000\n" +"PO-Revision-Date: 2026-06-05 20:33+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/guide/concept/aliases.md +#, no-wrap +msgid "Aliases" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/aliases.md +msgid "You can use aliases to represent file paths or URLs so that you don't have to hard-code absolute paths or URLs in your project. An alias must start with the `@` character to be differentiated from normal file paths and URLs. Alias defined without leading `@` will be prefixed with `@` character." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/aliases.md +msgid "Default Yii application has some aliases pre-defined in `config/params.php`. For example, the alias `@public` represents the web root path; `@baseUrl` represents the base URL for the currently running Web application." +msgstr "" + +#. type: Title ## +#: ../src/guide/concept/aliases.md +#, no-wrap +msgid "Defining aliases" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/aliases.md +msgid "You can define an alias via application's `config/params.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/aliases.md +#, no-wrap +msgid "" +"return [\n" +" // ...\n" +" \n" +" 'yiisoft/aliases' => [\n" +" 'aliases' => [\n" +" // ...\n" +" \n" +" // an alias of a file path\n" +" '@foo' => '/path/to/foo',\n" +" \n" +" // an alias of a URL\n" +" '@bar' => 'https://www.example.com',\n" +" \n" +" // an alias of a concrete file that contains a \\foo\\Bar class \n" +" '@foo/Bar.php' => '/definitely/not/foo/Bar.php',\n" +" ],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/aliases.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> The file path or URL being aliased may *not* necessarily refer to an existing file or resource.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/aliases.md +msgid "Given a defined alias, you may derive a new alias by appending a slash `/` followed with one or more path segments. For example, `@foo` is a root alias, while `@foo/bar/file.php` is a derived alias." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/aliases.md +msgid "You can define an alias using another alias (either root or derived):" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/aliases.md +#, no-wrap +msgid "'@foobar' => '@foo/bar', \n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/aliases.md +msgid "The `yiisoft/aliases` parameter initializes `Aliases` service from [`yiisoft/aliases`](https://github.com/yiisoft/aliases) package. You can set extra aliases in runtime by using the service:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/aliases.md +#, no-wrap +msgid "" +"use \\Yiisoft\\Aliases\\Aliases;\n" +"\n" +"public function actionIndex(Aliases $aliases)\n" +"{\n" +" $aliases->set('@uploads', '@root/uploads');\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/concept/aliases.md +#, no-wrap +msgid "Using aliases in configuration" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/aliases.md +msgid "It's preferred to resolve aliases at the configuration level, so services get URLs and paths as ready to use strings:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/aliases.md +#, no-wrap +msgid "" +" static fn (Aliases $aliases) => new FileCache(\n" +" $aliases->get($params['yiisoft/cache-file']['fileCache']['path'])\n" +" ),\n" +"];\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/concept/aliases.md +#, no-wrap +msgid "Resolving aliases" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/aliases.md +msgid "You can use `Aliases` service to resolve an alias or derived alias into the file path or URL it represents:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/aliases.md +#, no-wrap +msgid "" +"use \\Yiisoft\\Aliases\\Aliases;\n" +"\n" +"public function actionIndex(Aliases $aliases)\n" +"{\n" +" $foo = $aliases->get('@foo'); // /path/to/foo\n" +" $bar = $aliases->get('@bar'); // https://www.example.com\n" +" $file = $aliases->get('@foo/bar/file.php'); // /path/to/foo/bar/file.php\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/aliases.md +msgid "The path/URL represented by a derived alias is determined by replacing the root alias part with its corresponding path/URL in the derived alias." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/aliases.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> The `get()` method doesn't check whether the resulting path/URL refers to an existing file or resource.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/aliases.md +msgid "A root alias may also contain slash `/` characters. The `get()` method is intelligent enough to tell, which part of an alias is a root alias and thus correctly determines the corresponding file path or URL:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/aliases.md +#, no-wrap +msgid "" +"use \\Yiisoft\\Aliases\\Aliases;\n" +"\n" +"public function actionIndex(Aliases $aliases)\n" +"{\n" +" $aliases->set('@foo', '/path/to/foo');\n" +" $aliases->set('@foo/bar', '/path2/bar');\n" +"\n" +" $aliases->get('@foo/test/file.php'); // /path/to/foo/test/file.php\n" +" $aliases->get('@foo/bar/file.php'); // /path2/bar/file.php\n" +"} \n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/aliases.md +msgid "If `@foo/bar` isn't defined as a root alias, the last statement would display `/path/to/foo/bar/file.php`." +msgstr "" + +#. type: Title ## +#: ../src/guide/concept/aliases.md +#, no-wrap +msgid "Predefined aliases" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/aliases.md +msgid "[Yii application](https://github.com/yiisoft/app) predefines a set of aliases to reference commonly used file paths and URLs:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/aliases.md +msgid "`@root` - the base directory of the currently running application." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/aliases.md +msgid "`@assets` - application's public directory where it publishes assets." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/aliases.md +msgid "`@assetsUrl` - URL of base directory with published assets." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/aliases.md +msgid "`@baseUrl` - the base URL of the currently running Web application. Defaults to `/`." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/aliases.md +msgid "`@npm` - node packages directory." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/aliases.md +msgid "`@bower` - bower packages directory." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/aliases.md +msgid "`@vendor` - Composer's `vendor` directory." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/aliases.md +msgid "`@public` - application's publicly accessible directory that with `index.php`." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/aliases.md +msgid "`@runtime` - the runtime path of the currently running application. Defaults to `@root/runtime`." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/aliases.md +msgid "`@layout` - the directory with layouts." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/aliases.md +msgid "`@resources` - directory with views, asset sources and other resources." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/aliases.md +msgid "`@views` - application view templates base directory." +msgstr "" diff --git a/_translations/po/pt-BR/guide_concept_autoloading.md.po b/_translations/po/pt-BR/guide_concept_autoloading.md.po new file mode 100644 index 00000000..99319baf --- /dev/null +++ b/_translations/po/pt-BR/guide_concept_autoloading.md.po @@ -0,0 +1,76 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-01-08 08:54+0000\n" +"PO-Revision-Date: 2026-01-08 08:54+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md +#: ../src/guide/concept/autoloading.md ../src/guide/security/best-practices.md +#: ../src/guide/structure/domain.md +#: ../src/guide/tutorial/console-applications.md +#: ../src/internals/004-namespaces.md ../src/internals/007-exceptions.md +#: ../src/internals/008-interfaces.md +#, no-wrap +msgid "References" +msgstr "" + +#. type: Title # +#: ../src/guide/concept/autoloading.md +#, no-wrap +msgid "Class autoloading" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/autoloading.md +msgid "Since Yii uses [Composer](https://getcomposer.org) to manage packages, it automatically loads classes from these packages without the need to `require` their file explicitly. When it installs packages, it generates a [PSR-4 compatible autoloader](https://www.php-fig.org/psr/psr-4/). To use it, `require_once` autoloader `/vendor/autoload.php` in your `index.php` entry point file." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/autoloading.md +msgid "You can use autoloader not only for the packages installed, but for your application as well since it's also a package. To load classes of a certain namespace, add the following to `composer.json`:" +msgstr "" + +#. type: Fenced code block (json) +#: ../src/guide/concept/autoloading.md +#, no-wrap +msgid "" +"{\n" +" \"autoload\": {\n" +" \"psr-4\": {\n" +" \"App\\\\\": \"src/\"\n" +" }\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/autoloading.md +msgid "Where `App\\\\` is a root namespace and `src/` is a directory where you have your classes. You can add more source roots if needed. When done, execute `composer dump-autoload` or simply `composer du` and classes from the corresponding namespaces will start loading automatically." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/autoloading.md +msgid "If you need development-environment-specific autoloading that isn't used when executing Composer with `--no-dev` flag, add it to `autoload-dev` section instead of `autoload`." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/autoloading.md +msgid "[PSR-4: Autoloader](https://www.php-fig.org/psr/psr-4/)." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/autoloading.md +msgid "[Composer guide on autoloading](https://getcomposer.org/doc/01-basic-usage.md#autoloading)." +msgstr "" diff --git a/_translations/po/pt-BR/guide_concept_configuration.md.po b/_translations/po/pt-BR/guide_concept_configuration.md.po new file mode 100644 index 00000000..ca7f7eab --- /dev/null +++ b/_translations/po/pt-BR/guide_concept_configuration.md.po @@ -0,0 +1,681 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-05-29 19:04+0000\n" +"PO-Revision-Date: 2026-05-29 19:04+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/cookbook/sentry-integration.md ../src/guide/concept/configuration.md +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#: ../src/guide/views/view-injections.md +#, no-wrap +msgid "Configuration" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "There are many ways to configure your application. We will focus on concepts used in the [default project template](https://github.com/yiisoft/app)." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "Yii3 configs are part of the application. You can change many aspects of how the application works by editing configuration under `config/` directory." +msgstr "" + +#. type: Title ## +#: ../src/guide/concept/configuration.md +#, no-wrap +msgid "Config plugin" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "The application template uses [yiisoft/config](https://github.com/yiisoft/config) as a composer plugin to assemble configs." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "Packages provide default configurations through defined [config groups](https://github.com/yiisoft/config#config-groups) in the `config-plugin` key in the `extra` section of the `composer.json`:" +msgstr "" + +#. type: Fenced code block (json) +#: ../src/guide/concept/configuration.md +#, no-wrap +msgid "" +"\"extra\": {\n" +" \"config-plugin-options\": {\n" +" \"source-directory\": \"config\",\n" +" },\n" +" \"config-plugin\": {\n" +" \"params\": \"params.php\",\n" +" \"web\": \"web.php\"\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "After Composer updates autoload files, such as during `dump-autoload`, `install`, `require`, `update`, or `remove`, the plugin scans installed packages for configurations and writes a merge plan to `config/.merge-plan.php`. The merge plan declares the order of merging found configurations into the final configuration to be passed to [DI container](di-container.md)." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "At runtime, `Yiisoft\\Config\\Config` loads the defined config groups according to that merge plan. Configs are read in three layers:" +msgstr "" + +#. type: Bullet: '1. ' +#: ../src/guide/concept/configuration.md +msgid "Vendor package configs with default values." +msgstr "" + +#. type: Bullet: '2. ' +#: ../src/guide/concept/configuration.md +msgid "Root package configs from the application `config/` directory." +msgstr "" + +#. type: Bullet: '3. ' +#: ../src/guide/concept/configuration.md +msgid "Environment-specific configs from the application." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +#, no-wrap +msgid "" +"> [!WARNING]\n" +"> Config keys with the same name are not allowed within a single layer.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "The application template stores configurations in a PHP file instead of inline JSON:" +msgstr "" + +#. type: Fenced code block (json) +#: ../src/guide/concept/configuration.md +#, no-wrap +msgid "" +"\"extra\": {\n" +" \"config-plugin-file\": \"config/configuration.php\"\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "That file returns the same keys you could otherwise define in `composer.json`: `config-plugin`, `config-plugin-options`, and `config-plugin-environments`." +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/configuration.md +#, no-wrap +msgid "" +"use App\\Environment;\n" +"\n" +"return [\n" +" 'config-plugin-options' => [\n" +" 'source-directory' => 'config',\n" +" ],\n" +" 'config-plugin' => [\n" +" 'params' => 'common/params.php',\n" +" 'params-web' => [\n" +" '$params',\n" +" 'web/params.php',\n" +" ],\n" +" 'params-console' => [\n" +" '$params',\n" +" 'console/params.php',\n" +" ],\n" +" 'bootstrap' => 'common/bootstrap.php',\n" +" 'bootstrap-web' => '$bootstrap',\n" +" 'bootstrap-console' => '$bootstrap',\n" +" 'di' => 'common/di/*.php',\n" +" 'di-web' => [\n" +" '$di',\n" +" 'web/di/*.php',\n" +" ],\n" +" 'di-console' => '$di',\n" +" 'di-delegates' => [],\n" +" 'di-delegates-console' => '$di-delegates',\n" +" 'di-delegates-web' => '$di-delegates',\n" +" 'di-providers' => [],\n" +" 'di-providers-web' => '$di-providers',\n" +" 'di-providers-console' => '$di-providers',\n" +" 'events' => [],\n" +" 'events-web' => '$events',\n" +" 'events-console' => '$events',\n" +" 'routes' => 'common/routes.php',\n" +" ],\n" +" 'config-plugin-environments' => [\n" +" Environment::DEV => [\n" +" 'params' => [\n" +" 'environments/dev/params.php',\n" +" ],\n" +" ],\n" +" Environment::TEST => [\n" +" 'params' => [\n" +" 'environments/test/params.php',\n" +" ],\n" +" ],\n" +" Environment::PROD => [\n" +" 'params' => [\n" +" 'environments/prod/params.php',\n" +" ],\n" +" ],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "Config group names are mapping keys. Their values are file paths relative to the `source-directory` option, which defaults to the directory containing `composer.json`." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/configuration.md +msgid "A string value loads one file." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/configuration.md +msgid "An array loads and merges multiple files in the given order." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/configuration.md +msgid "`?` marks an optional file." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/configuration.md +msgid "`*` marks a wildcard path." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/configuration.md +msgid "`$group` references another config group to be merged." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "The `params` group is special: its values are available as `$params` in other config files by default." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "You can read more in the [yiisoft/config documentation](https://github.com/yiisoft/config/blob/master/README.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/concept/configuration.md +#, no-wrap +msgid "Config files" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "Now, as you know how the plugin assembles configs, look at the `config/` directory structure used by the default application template:" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/concept/configuration.md +#, no-wrap +msgid "" +"common/\n" +" bootstrap.php\n" +" params.php\n" +" routes.php\n" +" di/\n" +" *.php\n" +"console/\n" +" params.php\n" +"environments/\n" +" dev/\n" +" params.php\n" +" prod/\n" +" params.php\n" +" test/\n" +" params.php\n" +"web/\n" +" params.php\n" +" di/\n" +" *.php\n" +".merge-plan.php\n" +"configuration.php\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "This structure follows the groups defined in `config/configuration.php`:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/configuration.md +msgid "`params`, `params-web`, and `params-console` load parameter files from `common/`, `web/`, and `console/`." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/configuration.md +msgid "`di` and `di-web` load container definitions from `common/di/` and `web/di/`." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/configuration.md +msgid "`routes` and `bootstrap` load `common/routes.php` and `common/bootstrap.php`." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/configuration.md +msgid "`config-plugin-environments` adds environment-specific parameter files from `environments/dev/`, `environments/test/`, and `environments/prod/`." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "At runtime, `.merge-plan.php` stores the assembled merge plan generated from `configuration.php`." +msgstr "" + +#. type: Title ### +#: ../src/guide/concept/configuration.md +#, no-wrap +msgid "Container configuration" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "The application consists of services registered in a [dependency container](di-container.md). In the default template, direct container definitions live in `config/common/di/*.php` and `config/web/di/*.php`." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "Definitions from `common/di/` are shared by web and console entry points. The `di-web` group adds web-specific definitions from `web/di/`. The `di-console` group currently reuses the shared `di` definitions without extra files." +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/configuration.md +#, no-wrap +msgid "" +" [\n" +" '__construct()' => [\n" +" 'name' => $params['application']['name'],\n" +" 'charset' => $params['application']['charset'],\n" +" 'locale' => $params['application']['locale'],\n" +" ],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "Config plugin passes the special `$params` variable to all config files. The definition uses it to configure services." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "The guide on [\"Dependency injection and container\"](di-container.md) describes the configuration format and the idea of dependency injection in detail." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "For convenience, there is a naming convention for custom string keys:" +msgstr "" + +#. type: Bullet: '1. ' +#: ../src/guide/concept/configuration.md +msgid "Prefix package name such as `yiisoft/cache-file/custom-definition`." +msgstr "" + +#. type: Bullet: '2. ' +#: ../src/guide/concept/configuration.md +msgid "In case configuration are for the application itself, skip package prefix, such as `custom-definition`." +msgstr "" + +#. type: Title ### +#: ../src/guide/concept/configuration.md +#, no-wrap +msgid "Service providers" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "As an alternative to registering dependencies directly, you can use service providers. A service provider is a class that returns a reusable set of container definitions and extensions." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "The default template exposes three config groups for service providers: `di-providers`, `di-providers-web`, and `di-providers-console`. In the template they are initialized as empty arrays in `config/configuration.php`, and you can later populate them inline or switch them to load values from files." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "Prefer direct container configuration for application services with a simple definition: a class name, an interface implementation, constructor arguments from `$params`, or a closure that creates a single service." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "Use a service provider when the registration itself is a reusable unit:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/configuration.md +msgid "A package registers several related services, aliases, or extensions." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/configuration.md +msgid "A service registration also needs supporting definitions." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/configuration.md +msgid "The same registration should be reused in several applications." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/configuration.md +msgid "Registration depends on optional classes or environment-specific decisions." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "Use a factory class when construction logic belongs to one service. A factory returns an object. A service provider returns definitions for several related services." +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/configuration.md +#, no-wrap +msgid "" +"/* @var array $params */\n" +"\n" +"// ...\n" +"use App\\Provider\\CacheProvider;\n" +"use App\\Provider\\MiddlewareProvider;\n" +"// ...\n" +"\n" +"return [\n" +" // ...\n" +" 'yiisoft/yii-web/middleware' => MiddlewareProvider::class,\n" +" 'yiisoft/cache/cache' => new CacheProvider($params['yiisoft/cache-file']['file-cache']['path']),\n" +" // ...\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "In this config keys are provider names. By convention these are `vendor/package-name/provider-name`. Values are provider class names or provider instances. These classes could be either created in the project itself or provided by a package." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "If you need to configure some options for a service, similar to direct container configuration, take values from `$params` and pass them to providers." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "Provider should implement `Yiisoft\\Di\\ServiceProviderInterface`. Below is a provider for a cache service:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/configuration.md +#, no-wrap +msgid "" +"use Psr\\Container\\ContainerInterface;\n" +"use Psr\\SimpleCache\\CacheInterface;\n" +"use Yiisoft\\Aliases\\Aliases;\n" +"use Yiisoft\\Cache\\Cache;\n" +"use Yiisoft\\Cache\\CacheInterface as YiiCacheInterface;\n" +"use Yiisoft\\Cache\\File\\FileCache;\n" +"use Yiisoft\\Di\\ServiceProviderInterface;\n" +"\n" +"final readonly class CacheProvider implements ServiceProviderInterface\n" +"{\n" +" public function __construct(\n" +" private string $cachePath = '@runtime/cache'\n" +" )\n" +" {\n" +" }\n" +"\n" +" public function getDefinitions(): array\n" +" {\n" +" return [\n" +" CacheInterface::class => function (ContainerInterface $container) {\n" +" $aliases = $container->get(Aliases::class);\n" +"\n" +" return new FileCache($aliases->get($this->cachePath));\n" +" },\n" +" YiiCacheInterface::class => Cache::class,\n" +" ];\n" +" }\n" +"\n" +" public function getExtensions(): array\n" +" {\n" +" return [];\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/concept/configuration.md +#: ../src/guide/structure/designing-packages.md +#, no-wrap +msgid "Routes" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "You can configure how the web application responds to certain URLs in `config/common/routes.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/configuration.md ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"use App\\Web;\n" +"use Yiisoft\\Router\\Group;\n" +"use Yiisoft\\Router\\Route;\n" +"\n" +"return [\n" +" Group::create()\n" +" ->routes(\n" +" Route::get('/')\n" +" ->action(Web\\HomePage\\Action::class)\n" +" ->name('home'),\n" +" ),\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "Read more about it in [\"Routes\"](../runtime/routing.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/concept/configuration.md ../src/guide/concept/events.md +#: ../src/guide/structure/designing-packages.md +#: ../src/internals/022-config-groups.md +#, no-wrap +msgid "Events" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "Many services emit certain events that you can attach to. The default template defines three event config groups in `config/configuration.php`: `events`, `events-web`, and `events-console`. They are empty by default, but you can populate them inline or point them to event config files." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "The configuration is an array where keys are event names and values are arrays of handlers:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/configuration.md +#, no-wrap +msgid "" +"return [\n" +" EventName::class => [\n" +" // Just a regular closure, it will be called from the Dispatcher \"as is\".\n" +" static fn (EventName $event) => someStuff($event),\n" +" \n" +" // A regular closure with an extra dependency. All the parameters after the first one (the event itself)\n" +" // will be resolved from your DI container within `yiisoft/injector`.\n" +" static fn (EventName $event, DependencyClass $dependency) => someStuff($event),\n" +" \n" +" // An example with a regular callable. If the `staticMethodName` method has some dependencies,\n" +" // they will be resolved the same way as in the earlier example.\n" +" [SomeClass::class, 'staticMethodName'],\n" +" \n" +" // Non-static methods are allowed too. In this case, `SomeClass` will be instantiated by your DI container.\n" +" [SomeClass::class, 'methodName'],\n" +" \n" +" // An object of a class with the `__invoke` method implemented\n" +" new InvokableClass(),\n" +" \n" +" // In this case, the `InvokableClass` with the `__invoke` method will be instantiated by your DI container\n" +" InvokableClass::class,\n" +" \n" +" // Any invokable class definition may be here as long as `$container->has('the definition')` is true.\n" +" 'di-alias'\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "Read more about it in [\"Events\"](events.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/concept/configuration.md +#: ../src/guide/structure/designing-packages.md +#: ../src/internals/022-config-groups.md +#, no-wrap +msgid "Parameters" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "Base parameters are stored in `config/common/params.php`. They are then extended by `config/web/params.php`, `config/console/params.php`, and environment-specific files under `config/environments/`." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +#, no-wrap +msgid "" +"> [!TIP]\n" +"> Don't use parameters, constants, or environment variables directly in your application, configure\n" +"> services instead.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "The default application `common/params.php` looks like the following:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/configuration.md +#, no-wrap +msgid "" +" require __DIR__ . '/application.php',\n" +"\n" +" 'yiisoft/aliases' => [\n" +" 'aliases' => require __DIR__ . '/aliases.php',\n" +" ],\n" +"\n" +" 'yiisoft/view' => [\n" +" 'basePath' => null,\n" +" 'parameters' => [\n" +" 'assetManager' => Reference::to(AssetManager::class),\n" +" 'applicationParams' => Reference::to(ApplicationParams::class),\n" +" 'aliases' => Reference::to(Aliases::class),\n" +" 'urlGenerator' => Reference::to(UrlGeneratorInterface::class),\n" +" 'currentRoute' => Reference::to(CurrentRoute::class),\n" +" ],\n" +" ],\n" +"\n" +" 'yiisoft/yii-view-renderer' => [\n" +" 'viewPath' => null,\n" +" 'layout' => '@src/Web/Shared/Layout/Main/layout.php',\n" +" 'injections' => [\n" +" Reference::to(CsrfViewInjection::class),\n" +" ],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "For convenience, there is a naming convention about parameters:" +msgstr "" + +#. type: Bullet: '1. ' +#: ../src/guide/concept/configuration.md +msgid "Group parameters package name such as `yiisoft/cache-file`." +msgstr "" + +#. type: Bullet: '2. ' +#: ../src/guide/concept/configuration.md +msgid "In case parameters are for the application itself, as in `application`, skip package prefix." +msgstr "" + +#. type: Bullet: '3. ' +#: ../src/guide/concept/configuration.md +msgid "In case there are many services in the package, such as `file-target` and `file-rotator` in `yiisoft/log-target-file` package, group parameters by service name." +msgstr "" + +#. type: Bullet: '4. ' +#: ../src/guide/concept/configuration.md +msgid "Use `enabled` as parameter name to be able to disable or enable a service, such as `yiisoft/yii-debug`." +msgstr "" + +#. type: Title ### +#: ../src/guide/concept/configuration.md +#, no-wrap +msgid "Package configs" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "Config plugin does not copy vendor package configs automatically. It loads them directly from `vendor/` as the vendor layer and combines them with the root package and environment-specific layers." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "If you want to customize a package config file in your application, use the `yii-config-copy` Composer command to copy it into your `config/` directory, usually under `config/packages/`. Once copied, the file becomes part of the root package layer, so it can override vendor defaults." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/configuration.md +msgid "The merge plan stored in `.merge-plan.php` defines how config groups are assembled. If you add new config files or directories and update the root package configuration, rebuild the merge plan with `composer yii-config-rebuild`." +msgstr "" diff --git a/_translations/po/pt-BR/guide_concept_di-container.md.po b/_translations/po/pt-BR/guide_concept_di-container.md.po new file mode 100644 index 00000000..f06f945a --- /dev/null +++ b/_translations/po/pt-BR/guide_concept_di-container.md.po @@ -0,0 +1,535 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-06-05 20:33+0000\n" +"PO-Revision-Date: 2026-06-05 20:33+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md +#: ../src/guide/concept/autoloading.md ../src/guide/concept/di-container.md +#: ../src/guide/security/best-practices.md ../src/guide/structure/domain.md +#: ../src/guide/tutorial/console-applications.md +#: ../src/internals/004-namespaces.md ../src/internals/007-exceptions.md +#: ../src/internals/008-interfaces.md +#, no-wrap +msgid "References" +msgstr "" + +#. type: Title # +#: ../src/guide/concept/di-container.md +#, no-wrap +msgid "Dependency injection and container" +msgstr "" + +#. type: Title ## +#: ../src/guide/concept/di-container.md +#, no-wrap +msgid "Dependency injection" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +msgid "There are two ways of re-using things in OOP: inheritance and composition." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +msgid "Inheritance is simple:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/di-container.md +#, no-wrap +msgid "" +"class Cache\n" +"{\n" +" public function getCachedValue($key)\n" +" {\n" +" // ..\n" +" }\n" +"}\n" +"\n" +"final readonly class CachedWidget extends Cache\n" +"{\n" +" public function render(): string\n" +" {\n" +" $output = $this->getCachedValue('cachedWidget');\n" +" if ($output !== null) {\n" +" return $output;\n" +" }\n" +" // ... \n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +msgid "The issue here is that these two are becoming unnecessarily coupled or inter-dependent, making them more fragile." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +msgid "Another way to handle this is composition:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/di-container.md +#, no-wrap +msgid "" +"interface CacheInterface\n" +"{\n" +" public function getCachedValue($key);\n" +"}\n" +"\n" +"final readonly class Cache implements CacheInterface\n" +"{\n" +" public function getCachedValue($key)\n" +" {\n" +" // ..\n" +" }\n" +"}\n" +"\n" +"final readonly class CachedWidget\n" +"{\n" +" public function __construct(\n" +" private CacheInterface $cache\n" +" )\n" +" {\n" +" }\n" +" \n" +" public function render(): string\n" +" {\n" +" $output = $this->cache->getCachedValue('cachedWidget');\n" +" if ($output !== null) {\n" +" return $output;\n" +" }\n" +" // ... \n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +msgid "We've avoided unnecessary inheritance and used `CacheInterface` in the `CacheWidget` to reduce coupling. You can replace cache implementation without changing `CachedWidget` so it's becoming more stable. The less edits are made to the code, the less chance of breaking it." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +msgid "The `CacheInterface` here is a dependency: a contract our object needs to function. In other words, our object depends on the contract." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +msgid "The process of putting an instance of a contract into an object (`CachedWidget`) is called dependency injection. There are many ways to perform it:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/di-container.md +msgid "Constructor injection. Best for mandatory dependencies." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/di-container.md +msgid "Method injection. Best for optional dependencies." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/di-container.md +msgid "Property injection. Better to be avoided in PHP except maybe data transfer objects." +msgstr "" + +#. type: Title ### +#: ../src/guide/concept/di-container.md +#, no-wrap +msgid "Why use private properties" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +msgid "In the composition example above, note that the `$cache` property is declared as `private`." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +msgid "This approach embraces composition by ensuring objects have well-defined interfaces for interaction rather than direct property access, making the code more maintainable and less prone to certain types of mistakes." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +msgid "This design choice provides several benefits:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/di-container.md +msgid "**Encapsulation**: Private properties with getters/setters allow you to control access and make future changes without breaking existing code." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/di-container.md +msgid "**Data integrity**: Setters can validate, normalize, or format values before storing them, ensuring properties contain valid data." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/di-container.md +msgid "**Immutability**: Private properties enable immutable object patterns where setter `with*()` methods return new instances rather than modifying the current one." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/di-container.md +msgid "**Flexibility**: You can create read-only or write-only properties or add additional logic to property access later." +msgstr "" + +#. type: Title ## +#: ../src/guide/concept/di-container.md +#, no-wrap +msgid "DI container" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +msgid "Injecting basic dependencies is straightforward. You're choosing a place where you don't care about dependencies, which is usually an action handler, which you aren't going to unit-test ever, create instances of dependencies needed and pass these to dependent classes." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +msgid "It works well when there are few dependencies overall and when there are no nested dependencies. When there are many and each dependency has dependencies itself, instantiating the whole hierarchy becomes a tedious process, which requires lots of code and may lead to hardly debuggable mistakes." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +msgid "Additionally, lots of dependencies, such as certain third-party API wrappers, are the same for any class using it. So it makes sense to:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/di-container.md +msgid "Define how to instantiate such common dependencies." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/di-container.md +msgid "Instantiate them when required and only once per request." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +msgid "That's what dependency containers are for." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +msgid "A dependency injection (DI) container is an object that knows how to instantiate and configure objects and all objects they depend on." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +msgid "Yii provides the DI container feature through the [yiisoft/di](https://github.com/yiisoft/di) package and [yiisoft/injector](https://github.com/yiisoft/injector) package." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> The container contains only shared instances. If you need a factory, use the dedicated\n" +"> [yiisoft/factory](https://github.com/yiisoft/factory) package.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +#, no-wrap +msgid "" +"> [!TIP]\n" +"> [Martin Fowler's article](https://martinfowler.com/articles/injection.html) has well\n" +"> explained why DI container is useful. Here we will mainly explain the usage of the DI container provided by Yii.\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/concept/di-container.md +#, no-wrap +msgid "Configuring container" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +msgid "Because to create a new object you need its dependencies, you should register them as early as possible. You can do it in the application configuration, `config/web.php`. For the following service:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/di-container.md +#, no-wrap +msgid "" +"final class MyService implements MyServiceInterface\n" +"{\n" +" public function __construct(int $amount)\n" +" {\n" +" }\n" +"\n" +" public function setDiscount(int $discount): void\n" +" {\n" +" \n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +msgid "configuration could be:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/di-container.md +#, no-wrap +msgid "" +"return [\n" +" MyServiceInterface::class => [\n" +" 'class' => MyService::class,\n" +" '__construct()' => [42],\n" +" 'setDiscount()' => [10],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +msgid "That's equal to the following:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/di-container.md +#, no-wrap +msgid "" +"$myService = new MyService(42);\n" +"$myService->setDiscount(10);\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +msgid "You can provide arguments with names as well:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/di-container.md +#, no-wrap +msgid "" +"return [\n" +" MyServiceInterface::class => [\n" +" 'class' => MyService::class,\n" +" '__construct()' => ['amount' => 42],\n" +" 'setDiscount()' => ['discount' => 10],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +msgid "That's basically it. You define a map of interfaces to classes and define how to configure them. When an interface is requested in constructor or elsewhere, container creates an instance of a class and configures it as per the configuration:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/di-container.md +#, no-wrap +msgid "" +"final class MyAction\n" +"{\n" +" public function __construct(\n" +" private readonly MyServiceInterface $myService\n" +" ) {\n" +" }\n" +" \n" +" public function __invoke() \n" +" {\n" +" $this->myService->doSomething();\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +msgid "There are extra methods of declaring dependency configuration." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +msgid "For simplest cases where there are no custom values needed and all the constructor dependencies could be obtained from a container, you can use a class name as a value." +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/di-container.md +#, no-wrap +msgid "" +"interface EngineInterface\n" +"{\n" +" \n" +"}\n" +"\n" +"final class EngineMarkOne implements EngineInterface\n" +"{\n" +" public function __construct(CacheInterface $cache) {\n" +" } \n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +msgid "In the above example, if we already have cache defined in the container, nothing besides the class name is needed:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/di-container.md +#, no-wrap +msgid "" +"return [\n" +" // declare a class for an interface, resolve dependencies automatically\n" +" EngineInterface::class => EngineMarkOne::class,\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +msgid "If you have a dependency that has public properties, you can configure it as well." +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/di-container.md +#, no-wrap +msgid "" +"final class NameProvider\n" +"{\n" +" public string $name;\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +msgid "Here's how to do it for the example above:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/di-container.md +#, no-wrap +msgid "" +"NameProvider::class => [\n" +" 'class' => NameProvider::class, \n" +" '$name' => 'Alex',\n" +"],\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +msgid "In this example, you may notice `NameProvider` specified twice. The key is what you may request as dependency and the value is how to create it." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +msgid "If the configuration is tricky and requires some logic, a closure can be used:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/di-container.md +#, no-wrap +msgid "" +"MyServiceInterface::class => static function(ContainerInterface $container) {\n" +" return new MyService($container->get('db'));\n" +"},\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +msgid "Additionally, to `ContainerInterface`, you can request any registered service directly as a closure parameter. The injector will automatically resolve and inject these:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/di-container.md +#, no-wrap +msgid "" +"MyServiceInterface::class => static function(ConnectionInterface $db) {\n" +" return new MyService($db);\n" +"},\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +msgid "It's possible to use a static method call:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/di-container.md +#, no-wrap +msgid "MyServiceInterface::class => [MyFactory::class, 'create'],\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +msgid "Or an instance of an object:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/di-container.md +#, no-wrap +msgid "MyServiceInterface::class => new MyService(),\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/concept/di-container.md +#, no-wrap +msgid "Injecting dependencies properly" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +msgid "Directly referencing a container in a class is a bad idea since the code becomes non-generic, coupled to the container interface and, what's worse, dependencies are becoming hidden. Because of that, Yii inverts the control by automatically injecting objects from a container in some constructors and methods based on method argument types." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +msgid "This is primarily done in constructor and handing method of action handlers:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/di-container.md +#, no-wrap +msgid "" +"use \\Yiisoft\\Cache\\CacheInterface;\n" +"\n" +"final readonly class MyController\n" +"{\n" +" public function __construct(\n" +" private CacheInterface $cache\n" +" )\n" +" {\n" +" $this->cache = $cache; \n" +" }\n" +"\n" +" public function actionDashboard(RevenueReport $report)\n" +" {\n" +" $reportData = $this->cache->getOrSet('revenue_report', function() use ($report) {\n" +" return $report->getData(); \n" +" });\n" +"\n" +" return $this->render('dashboard', [\n" +" 'reportData' => $reportData,\n" +" ]);\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/di-container.md +msgid "Since it's [yiisoft/injector](https://github.com/yiisoft/injector) that instantiates and calls action handler, it checks the constructor and method argument types, gets dependencies of these types from a container and passes them as arguments. That's usually called auto-wiring. It happens for sub-dependencies as well, that's if you don't give dependency explicitly, the container would check if it has such a dependency first. It's enough to declare a dependency you need, and it would be got from a container automatically." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/di-container.md +msgid "[Inversion of Control Containers and the Dependency Injection pattern by Martin Fowler](https://martinfowler.com/articles/injection.html)" +msgstr "" diff --git a/_translations/po/pt-BR/guide_concept_events.md.po b/_translations/po/pt-BR/guide_concept_events.md.po new file mode 100644 index 00000000..ba44b834 --- /dev/null +++ b/_translations/po/pt-BR/guide_concept_events.md.po @@ -0,0 +1,316 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-06-05 20:33+0000\n" +"PO-Revision-Date: 2026-06-05 20:33+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/guide/concept/configuration.md ../src/guide/concept/events.md +#: ../src/guide/structure/designing-packages.md +#: ../src/internals/022-config-groups.md +#, no-wrap +msgid "Events" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/events.md +msgid "Events allow you to run custom code at certain execution points without changing the code that emits the event. You attach a custom code called a listener to an event. When the event is dispatched, the listener is executed." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/events.md +msgid "For example, when a user signs up, you need to send a welcome email. You can do it in `SignupService`. Later, when you also need to resize the user's avatar image, the service has to know about that too." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/events.md +msgid "A cleaner flow is to dispatch a `UserSignedUp` event from `SignupService`. The welcome email sender and the avatar processor listen to this event. Additional signup-related work can be added by registering another listener." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/events.md +msgid "Yii uses [yiisoft/yii-event](https://github.com/yiisoft/yii-event) for application event configuration. It builds on the [yiisoft/event-dispatcher](https://github.com/yiisoft/event-dispatcher) package, which provides a [PSR-14](https://www.php-fig.org/psr/psr-14/) compatible event dispatcher." +msgstr "" + +#. type: Title ## +#: ../src/guide/concept/events.md +#, no-wrap +msgid "Event classes" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/events.md +msgid "An event is an object. It usually contains data that listeners need:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/events.md +#, no-wrap +msgid "" +"final readonly class UserSignedUp\n" +"{\n" +" public function __construct(\n" +" public SignupForm $form,\n" +" ) {}\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/concept/events.md +#, no-wrap +msgid "Event listeners" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/events.md +msgid "An event listener is a [PHP callable](https://www.php.net/manual/en/language.types.callable.php) that receives an event:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/events.md +#, no-wrap +msgid "" +"static function (UserSignedUp $event): void {\n" +" // Send a welcome email.\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/events.md +msgid "You can also use an invokable class:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/events.md +#, no-wrap +msgid "" +"final readonly class WelcomeEmailSender\n" +"{\n" +" public function __invoke(UserSignedUp $event): void\n" +" {\n" +" // Send a welcome email.\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/concept/events.md +#, no-wrap +msgid "Configuring event listeners" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/events.md +msgid "In an application, configure listeners in:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/events.md +msgid "`config/events.php` for all application types." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/events.md +msgid "`config/events-web.php` for web application events." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/concept/events.md +msgid "`config/events-console.php` for console application events." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/events.md +msgid "The configuration is an array where keys are event class names and values are lists of listeners:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/events.md +#, no-wrap +msgid "" +" [\n" +" WelcomeEmailSender::class,\n" +" static fn (UserSignedUp $event, AvatarProcessor $avatarProcessor) => $avatarProcessor->resize($event->form),\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/events.md +msgid "The listener may be a closure, a callable array, an invokable object, an invokable class name, or a DI alias. For closure and callable array listeners, parameters after the first event parameter are resolved from the DI container. Invokable class names are instantiated by the container." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/events.md +msgid "Dependencies are resolved when the event is dispatched." +msgstr "" + +#. type: Title ## +#: ../src/guide/concept/events.md +#, no-wrap +msgid "Dispatching events" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/events.md +msgid "To dispatch an event, use `Psr\\EventDispatcher\\EventDispatcherInterface`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/events.md +#, no-wrap +msgid "" +"use Psr\\EventDispatcher\\EventDispatcherInterface;\n" +"\n" +"final readonly class SignupService\n" +"{\n" +" public function __construct(\n" +" private EventDispatcherInterface $eventDispatcher,\n" +" ) {}\n" +"\n" +" public function signup(SignupForm $form): void\n" +" {\n" +" // Sign up the user.\n" +"\n" +" $this->eventDispatcher->dispatch(new UserSignedUp($form));\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/events.md +msgid "The dispatcher asks a listener provider for listeners that match the event and calls them one by one." +msgstr "" + +#. type: Title ## +#: ../src/guide/concept/events.md +#, no-wrap +msgid "Event listener order" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/events.md +msgid "When several listeners are configured for the same event, they are called in the order they are listed in the config. If an event implements `Psr\\EventDispatcher\\StoppableEventInterface`, the dispatcher checks `isPropagationStopped()` before calling the next listener. When it returns `true`, the dispatcher stops processing the event." +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/events.md +msgid "Keep listeners independent where possible. Ordering is useful for technical needs, but business logic is usually easier to maintain when each listener can run on its own." +msgstr "" + +#. type: Title ## +#: ../src/guide/concept/events.md +#, no-wrap +msgid "Event hierarchy" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/events.md +msgid "Events don't have names or wildcard matching. Event class names, interfaces, and inheritance can be used when one listener should handle several related events:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/events.md +#, no-wrap +msgid "" +"interface DocumentEvent\n" +"{\n" +"}\n" +"\n" +"final readonly class BeforeDocumentProcessed implements DocumentEvent\n" +"{\n" +"}\n" +"\n" +"final readonly class AfterDocumentProcessed implements DocumentEvent\n" +"{\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/events.md +msgid "With the interface, you can listen to all document-related events:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/events.md +#, no-wrap +msgid "" +"use Yiisoft\\EventDispatcher\\Provider\\ListenerCollection;\n" +"use Yiisoft\\EventDispatcher\\Provider\\Provider;\n" +"\n" +"$listeners = (new ListenerCollection())\n" +" ->add(static function (DocumentEvent $event): void {\n" +" // Log document events.\n" +" });\n" +"\n" +"$provider = new Provider($listeners);\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/concept/events.md +#, no-wrap +msgid "Manual listener provider setup" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/events.md +msgid "In an application, use event configuration. For package-level code or tests, you can create a listener provider manually:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/events.md +#, no-wrap +msgid "" +"use Yiisoft\\EventDispatcher\\Dispatcher\\Dispatcher;\n" +"use Yiisoft\\EventDispatcher\\Provider\\ListenerCollection;\n" +"use Yiisoft\\EventDispatcher\\Provider\\Provider;\n" +"\n" +"$listeners = (new ListenerCollection())\n" +" ->add(static function (UserSignedUp $event): void {\n" +" // Send a welcome email.\n" +" });\n" +"\n" +"$provider = new Provider($listeners);\n" +"$dispatcher = new Dispatcher($provider);\n" +"\n" +"$dispatcher->dispatch(new UserSignedUp($form));\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/concept/events.md +#, no-wrap +msgid "`ListenerCollection::add()` returns a new collection instance. Assign the result when building a collection step by step:\n" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/events.md +#, no-wrap +msgid "" +"$listeners = new ListenerCollection();\n" +"$listeners = $listeners->add(\n" +" static function (UserSignedUp $event): void {\n" +" // Send a welcome email.\n" +" },\n" +" UserSignedUp::class,\n" +");\n" +msgstr "" diff --git a/_translations/po/pt-BR/guide_concept_immutability.md.po b/_translations/po/pt-BR/guide_concept_immutability.md.po new file mode 100644 index 00000000..b4c27343 --- /dev/null +++ b/_translations/po/pt-BR/guide_concept_immutability.md.po @@ -0,0 +1,224 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-12-24 08:02+0000\n" +"PO-Revision-Date: 2025-12-24 08:02+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/en/guide/concept/immutability.md ../src/en/internals/017-tags.md +#: ../src/en/internals/018-widgets.md +#, no-wrap +msgid "Immutability" +msgstr "" + +#. type: Plain text +#: ../src/en/guide/concept/immutability.md +msgid "Immutability means an object's state cannot change after it has been created. Instead of modifying an instance, you create a new instance with the desired changes. This approach is common for value objects such as Money, IDs, and DTOs. It helps to avoid accidental side effects: methods cannot silently change shared state, which makes code easier to reason about." +msgstr "" + +#. type: Title ## +#: ../src/en/guide/concept/immutability.md +#, no-wrap +msgid "Mutable pitfalls (what we avoid)" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/en/guide/concept/immutability.md +#, no-wrap +msgid "" +"// A shared base query built once and reused:\n" +"$base = Post::find()->where(['status' => Post::STATUS_PUBLISHED]);\n" +"\n" +"// Somewhere deep in the code we only need one post:\n" +"$one = $base->limit(1)->one(); // mutates the underlying builder (sticky limit!)\n" +"\n" +"// Later we reuse the same $base expecting a full list:\n" +"$list = $base->orderBy(['created_at' => SORT_DESC])->all();\n" +"// Oops: still limited to 1 because the previous limit(1) modified $base.\n" +msgstr "" + +#. type: Title ## +#: ../src/en/guide/concept/immutability.md +#, no-wrap +msgid "Creating an immutable object in PHP" +msgstr "" + +#. type: Plain text +#: ../src/en/guide/concept/immutability.md +msgid "There is no direct way to modify an instance, but you can use clone to create a new instance with the desired changes. That is what `with*` methods do." +msgstr "" + +#. type: Fenced code block (php) +#: ../src/en/guide/concept/immutability.md +#, no-wrap +msgid "" +"final class Money\n" +"{\n" +" public function __construct(\n" +" private int $amount,\n" +" private string $currency,\n" +" ) {\n" +" $this->validateAmount($amount);\n" +" $this->validateCurrency($currency);\n" +" }\n" +" \n" +" private function validateAmount(string $amount) \n" +" {\n" +" if ($amount < 0) {\n" +" throw new InvalidArgumentException('Amount must be positive.');\n" +" }\n" +" }\n" +" \n" +" private function validateCurrency(string $currency)\n" +" {\n" +" if (!in_array($currency, ['USD', 'EUR'])) {\n" +" throw new InvalidArgumentException('Invalid currency. Only USD and EUR are supported.');\n" +" }\n" +" } \n" +"\n" +" public function withAmount(int $amount): self\n" +" {\n" +" $this->validateAmount($amount);\n" +" \n" +" if ($amount === $this->amount) {\n" +" return $this;\n" +" }\n" +" \n" +" $clone = clone $this;\n" +" $clone->amount = $amount;\n" +" return $clone;\n" +" }\n" +" \n" +" public function withCurrency(string $currency): self\n" +" {\n" +" $this->validateCurrency($currency);\n" +" \n" +" if ($currency === $this->currency) {\n" +" return $this;\n" +" }\n" +" \n" +" $clone = clone $this;\n" +" $clone->currency = $currency;\n" +" return $clone;\n" +" }\n" +" \n" +" public function amount(): int \n" +" {\n" +" return $this->amount;\n" +" }\n" +" \n" +" public function currency(): string \n" +" {\n" +" return $this->currency;\n" +" }\n" +"\n" +" public function add(self $money): self\n" +" {\n" +" if ($money->currency !== $this->currency) {\n" +" throw new InvalidArgumentException('Currency mismatch. Cannot add money of different currency.');\n" +" }\n" +" return $this->withAmount($this->amount + $money->amount);\n" +" }\n" +"}\n" +"\n" +"$price = new Money(1000, 'USD');\n" +"$discounted = $price->withAmount(800);\n" +"// $price is still 1000 USD, $discounted is 800 USD\n" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/guide/concept/immutability.md +msgid "We mark the class `final` to prevent subclass mutations; alternatively, design for extension carefully." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/guide/concept/immutability.md +msgid "Validate in the constructor and `with*` methods so every instance is always valid." +msgstr "" + +#. type: Plain text +#: ../src/en/guide/concept/immutability.md +#, no-wrap +msgid "" +"> [!TIP]\n" +"> If you define a simple DTO, you can use modern PHP `readonly` and leave properties `public`. The `readonly` keyword\n" +"> would ensure that the properties cannot be modified after the object is created.\n" +msgstr "" + +#. type: Title ## +#: ../src/en/guide/concept/immutability.md +#, no-wrap +msgid "Using clone (and why it is inexpensive)" +msgstr "" + +#. type: Plain text +#: ../src/en/guide/concept/immutability.md +msgid "PHP's clone performs a shallow copy of the object. For immutable value objects that contain only scalars or other immutable objects, shallow cloning is enough and fast. In modern PHP, cloning small value objects is inexpensive in both time and memory." +msgstr "" + +#. type: Plain text +#: ../src/en/guide/concept/immutability.md +msgid "If your object holds mutable sub-objects that must also be copied, implement `__clone` to deep-clone them:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/en/guide/concept/immutability.md +#, no-wrap +msgid "" +"final class Order\n" +"{\n" +" public function __construct(\n" +" private Money $total\n" +" ) {}\n" +" \n" +" public function total(): Money \n" +" {\n" +" return $this->total;\n" +" }\n" +"\n" +" public function __clone(): void\n" +" {\n" +" // Money is immutable in our example, so a deep clone is not required.\n" +" // If it were mutable, you could do: $this->total = clone $this->total;\n" +" }\n" +"\n" +" public function withTotal(Money $total): self\n" +" {\n" +" $clone = clone $this;\n" +" $clone->total = $total;\n" +" return $clone;\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../src/en/guide/concept/immutability.md +#, no-wrap +msgid "Usage style" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/guide/concept/immutability.md +msgid "Build a value object once and pass it around. If you need a change, use a `with*` method that returns a new instance." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/guide/concept/immutability.md +msgid "Prefer scalar/immutable fields inside immutable objects; if a field can mutate, isolate it and deep-clone in `__clone` when needed." +msgstr "" + +#. type: Plain text +#: ../src/en/guide/concept/immutability.md +msgid "Immutability aligns well with Yii's preference for predictable, side-effect-free code and makes services, caching, and configuration more robust." +msgstr "" diff --git a/_translations/po/pt-BR/guide_databases_db-migrations.md.po b/_translations/po/pt-BR/guide_databases_db-migrations.md.po new file mode 100644 index 00000000..d0a1621d --- /dev/null +++ b/_translations/po/pt-BR/guide_databases_db-migrations.md.po @@ -0,0 +1,918 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-06-05 20:33+0000\n" +"PO-Revision-Date: 2026-06-05 20:33+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/guide/databases/db-migrations.md +#: ../src/guide/structure/designing-packages.md +#, no-wrap +msgid "Migrations" +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +msgid "During the course of developing and maintaining a database-driven application, the structure of the database being used evolves just like the source code does. For example, during the development of an application, a new table may be found necessary; after the application is deployed to production, it may be discovered that an index should be created to improve the query performance; and so on. Because a database structure change often requires some source code changes, Yii supports the so-called *database migration* feature that allows you to keep track of database changes in terms of *database migrations* which are version-controlled together with the source code." +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +msgid "The following steps show how database migration can be used by a team during development:" +msgstr "" + +#. type: Bullet: '1. ' +#: ../src/guide/databases/db-migrations.md +msgid "Tim creates a new migration (e.g. creates a new table, changes a column definition, etc.)." +msgstr "" + +#. type: Bullet: '2. ' +#: ../src/guide/databases/db-migrations.md +msgid "Tim commits the new migration into the source control system (e.g. Git, Mercurial)." +msgstr "" + +#. type: Bullet: '3. ' +#: ../src/guide/databases/db-migrations.md +msgid "Doug updates his repository from the source control system and receives the new migration." +msgstr "" + +#. type: Bullet: '4. ' +#: ../src/guide/databases/db-migrations.md +msgid "Doug applies the migration to his local development database, thereby synchronizing his database to reflect the changes that Tim has made." +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +msgid "And the following steps show how to deploy a new release with database migrations to production:" +msgstr "" + +#. type: Bullet: '1. ' +#: ../src/guide/databases/db-migrations.md +msgid "Scott creates a release tag for the project repository that contains some new database migrations." +msgstr "" + +#. type: Bullet: '2. ' +#: ../src/guide/databases/db-migrations.md +msgid "Scott updates the source code on the production server to the release tag." +msgstr "" + +#. type: Bullet: '3. ' +#: ../src/guide/databases/db-migrations.md +msgid "Scott applies any accumulated database migrations to the production database." +msgstr "" + +#. type: Fenced code block (mermaid) +#: ../src/guide/databases/db-migrations.md +#, no-wrap +msgid "" +"sequenceDiagram\n" +" participant Tim\n" +" participant VCS as Source control\n" +" participant Doug\n" +" participant LocalDB as Local development database\n" +" participant Scott\n" +" participant ProdServer as Production server\n" +" participant ProdDB as Production database\n" +"\n" +" Tim->>Tim: Creates a new migration\n" +" Tim->>VCS: Commits the new migration\n" +" Doug->>VCS: Updates his repository and receives the new migration\n" +" Doug->>LocalDB: Applies the migration locally\n" +"\n" +" Scott->>VCS: Creates a release tag with new migrations\n" +" Scott->>ProdServer: Updates source code to the release tag\n" +" Scott->>ProdDB: Applies accumulated migrations\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +msgid "Yii provides a set of migration command line tools that allow you to:" +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/databases/db-migrations.md +msgid "create new migrations;" +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/databases/db-migrations.md +msgid "apply migrations;" +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/databases/db-migrations.md +msgid "revert migrations;" +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/databases/db-migrations.md +msgid "re-apply migrations;" +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/databases/db-migrations.md +msgid "show migration history and status." +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +msgid "All these tools are accessible through the command `yii migrate`. In this section we will describe in detail how to accomplish various tasks using these tools." +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +#, no-wrap +msgid "" +"> [!TIP]\n" +"> Migrations could affect not only database schema but adjust existing data to fit new schema, create RBAC\n" +"hierarchy or clean up cache.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> When manipulating data using a migration you may find that using your Active Record or entity classes\n" +"> for this might be useful because some of the logic is already implemented there. Keep in mind however, that in contrast\n" +"> to code written in the migrations, whose nature is to stay constant forever, application logic is subject to change.\n" +"> So when using Active Record or entity classes in migration code, changes to the logic in the source code\n" +"> may accidentally break the existing migrations. For this reason migration code should be kept independent of other\n" +"> application logic such.\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/databases/db-migrations.md +#, no-wrap +msgid "Initial configuration" +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +msgid "To use migrations, install [yiisoft/db-migration](https://github.com/yiisoft/db-migration/) package:" +msgstr "" + +#. type: Fenced code block (sh) +#: ../src/guide/databases/db-migrations.md ../src/guide/start/databases.md +#, no-wrap +msgid "make composer require yiisoft/db-migration\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +msgid "Create a directory to store migrations `src/Migration` right in the project root." +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +msgid "Add the following configuration to `config/common/params.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/databases/db-migrations.md ../src/guide/start/databases.md +#, no-wrap +msgid "" +"'yiisoft/db-migration' => [\n" +" 'newMigrationNamespace' => 'App\\\\Migration',\n" +" 'sourceNamespaces' => ['App\\\\Migration'],\n" +"],\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +msgid "If you want to place migrations elsewhere, you can define the path in `newMigrationPath`. If your migrations to be applied are from multiple sources, such as external modules, `sourcePaths` could be used to define these." +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +msgid "You need a database connection configured as well. See [Working with databases](../start/databases.md) for an example of configuring it for PostgreSQL." +msgstr "" + +#. type: Title ## +#: ../src/guide/databases/db-migrations.md +#, no-wrap +msgid "Creating a migration" +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +msgid "To create a new empty migration, run the following command:" +msgstr "" + +#. type: Fenced code block (sh) +#: ../src/guide/databases/db-migrations.md +#, no-wrap +msgid "" +"make shell\n" +"./yii migrate:create \n" +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +msgid "The required `name` argument gives a brief description about the new migration. For example, if the migration is about creating a new table named *news*, you may use the name `create_news_table` and run the following command:" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/databases/db-migrations.md +#, no-wrap +msgid "" +"make shell\n" +"./yii migrate:create create_news_table\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> Because the `name` argument will be used as part of the generated migration class name,\n" +"> it should only contain letters, digits, and/or underscore characters.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +msgid "The above command will create a new PHP class file named `src/Migration/M251225221906CreateNewsTable.php`. The file contains the following code which mainly declares a migration class with the skeleton code:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/databases/db-migrations.md +#, no-wrap +msgid "" +"columnBuilder();\n" +"\n" +" $b->createTable('news', [\n" +" 'id' => $cb::uuidPrimaryKey(),\n" +" 'title' => $cb::string()->notNull(),\n" +" 'content' => $cb::text(),\n" +" ]);\n" +" }\n" +"\n" +" public function down(MigrationBuilder $b): void\n" +" {\n" +" $b->dropTable('news');\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +msgid "Migration builder `$b` in the above manages database schema while the column builder `$cb` manages column types. Both allow using *abstract types*. When a migration is applied to a particular database, the abstract types will be translated into the corresponding database physical types and corresponding SQL to define them." +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +msgid "Methods available in migration builder belong to the following types:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/databases/db-migrations.md +msgid "Raw queries" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "getDb — to get database connection instance." +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "execute — to execute raw SQL query." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/databases/db-migrations.md +msgid "Data" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "insert / update / delete" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "batchInsert" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "upsert" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/databases/db-migrations.md +msgid "Tables and views" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "createTable / renameTable / dropTable" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "truncateTable" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "addCommentOnTable / dropCommentFromTable" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "createView / dropView" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/databases/db-migrations.md +msgid "Columns" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "addColumn / renameColumn / alterColumn / dropColumn" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "addCommentOnColumn / dropCommentFromColumn" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/databases/db-migrations.md +msgid "Keys and indexes" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "addPrimaryKey / dropPrimaryKey" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "addForeignKey / dropForeignKey" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "createIndex / dropIndex" +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +msgid "Additionally, there's a `columnBuilder()` which is used to obtain a column builder as in example above. The builder has static methods that define various column types:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/databases/db-migrations.md +msgid "Keys" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "primaryKey" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "smallPrimaryKey" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "bigPrimaryKey" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "uuidPrimaryKey" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/databases/db-migrations.md +msgid "Boolean" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "boolean" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/databases/db-migrations.md +msgid "Numbers" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "bit" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "tinyint" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "smallint" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "integer" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "bigint" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "flat" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "double" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "decimal" +msgstr "" + +#. type: Title ## +#: ../src/guide/databases/db-migrations.md ../src/internals/010-code-style.md +#, no-wrap +msgid "Strings" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "char" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "string" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "text" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/databases/db-migrations.md +msgid "Date and time" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "timestamp" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "datetime" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "datetimeWithTimezone" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "time" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "timeWithTimezone" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "date" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/databases/db-migrations.md +msgid "Special types" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "money" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "binary" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "uuid" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "array" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "structured" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/databases/db-migrations.md +msgid "json" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/databases/db-migrations.md +msgid "enum" +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +msgid "All the above methods create a base type which could be adjusted with additional methods:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/databases/db-migrations.md +msgid "null / notNull" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/databases/db-migrations.md +msgid "defaultValue" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/databases/db-migrations.md +msgid "unique" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/databases/db-migrations.md +msgid "scale / size / unsigned" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/databases/db-migrations.md +msgid "primaryKey / autoIncrement" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/databases/db-migrations.md +msgid "check" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/databases/db-migrations.md +msgid "comment" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/databases/db-migrations.md +msgid "computed" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/databases/db-migrations.md +msgid "extra" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/databases/db-migrations.md +msgid "reference" +msgstr "" + +#. type: Title ### +#: ../src/guide/databases/db-migrations.md +#, no-wrap +msgid "Irreversible migrations" +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +msgid "Not all migrations are reversible. For example, if the `up()` method deletes a row of a table, you may not be able to recover this row in the `down()` method. Sometimes, you may be just too lazy to implement the `down()`, because it is not very common to revert database migrations. In this case, you should implement `Yiisoft\\Db\\Migration\\MigrationInterface` that has `up()` only." +msgstr "" + +#. type: Title ### +#: ../src/guide/databases/db-migrations.md +#, no-wrap +msgid "Transactional migrations" +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +msgid "While performing complex DB migrations, it is important to ensure each migration to either succeed or fail as a whole so that the database can maintain integrity and consistency. To achieve this goal, it is recommended that you may enclose the DB operations of each migration in a transaction automatically by adding `TransactionalMigrationInterface` to `implements` of your migration." +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +msgid "As a result, if any operation in the `up()` or `down()` method fails, all prior operations will be rolled back automatically." +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +#, no-wrap +msgid "" +"> Note: Not all DBMS support transactions. And some DB queries cannot be put into a transaction. For some examples,\n" +"please refer to [implicit commit](https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html).\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/databases/db-migrations.md +#, no-wrap +msgid "Generating a migration" +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +msgid "Instead of writing migrations by hand, the command provides a convenient way generate some of the code." +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/databases/db-migrations.md +#, no-wrap +msgid "" +"make shell\n" +"./yii migrate:create -- my_first_table --command=table --fields=name,example --table-comment=my_first_table\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +msgid "That would generate the following:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/databases/db-migrations.md +#, no-wrap +msgid "" +"columnBuilder();\n" +"\n" +" $b->createTable('my_first_table', [\n" +" 'id' => $columnBuilder::primaryKey(),\n" +" 'name',\n" +" 'example',\n" +" ]);\n" +"\n" +" $b->addCommentOnTable('my_first_table', 'my_first_table');\n" +" }\n" +"\n" +" public function down(MigrationBuilder $b): void\n" +" {\n" +" $b->dropTable('my_first_table');\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +msgid "Commands available are:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/databases/db-migrations.md +msgid "create - empty migration." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/databases/db-migrations.md +msgid "table - creating a table. Use `--fields` specify a list of fields to use. Types could be specified as well such as `id:primaryKey,name:string:defaultValue(\"Alex\"),user_id:integer:foreignKey,category_id2:integer:foreignKey(category id2)`." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/databases/db-migrations.md +msgid "dropTable - dropping a table." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/databases/db-migrations.md +msgid "addColumn - adding a column." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/databases/db-migrations.md +msgid "dropColumn - dropping a column." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/databases/db-migrations.md +msgid "junction - creating a junction table. Use `--and` specify a second table." +msgstr "" + +#. type: Title ## +#: ../src/guide/databases/db-migrations.md +#, no-wrap +msgid "Applying Migrations" +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +msgid "To upgrade a database to its latest structure, you should apply all available new migrations using the following command:" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/databases/db-migrations.md +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "./yii migrate:up\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +msgid "This command will list all migrations that have not been applied so far. If you confirm that you want to apply these migrations, it will run the `up()` method in every new migration class, one after another, in the order of their timestamp values. If any of the migrations fails, the command will quit without applying the rest of the migrations." +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +msgid "For each migration that has been successfully applied, the command will insert a row into a database table named `migration` to record the successful application of the migration. This will allow the migration tool to identify which migrations have been applied and which have not." +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +msgid "Sometimes, you may only want to apply one or a few new migrations, instead of all available migrations. You can do so by specifying the number of migrations that you want to apply when running the command. For example, the following command will try to apply the next three available migrations:" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/databases/db-migrations.md +#, no-wrap +msgid "./yii migrate:up --limit=3\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/databases/db-migrations.md +#, no-wrap +msgid "Reverting Migrations" +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +msgid "To revert (undo) one or multiple migrations that have been applied before, you can run the following command:" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/databases/db-migrations.md +#, no-wrap +msgid "" +"./yii migrate:down # revert the most recently applied migration\n" +"./yii migrate:down --limit=3 # revert the most 3 recently applied migrations\n" +"./yii migrate:down --all # revert all migrations\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +#, no-wrap +msgid "" +"> Note: Not all migrations are reversible. Trying to revert such migrations will cause an error and stop the\n" +"entire reverting process.\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/databases/db-migrations.md +#, no-wrap +msgid "Redoing Migrations" +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +msgid "Redoing migrations means first reverting the specified migrations and then applying again. This can be done as follows:" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/databases/db-migrations.md +#, no-wrap +msgid "" +"./yii migrate:redo # redo the last applied migration\n" +"./yii migrate:redo --limit=3 # redo the last 3 applied migrations\n" +"./yii migrate:redo --all # redo all migrations\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +#, no-wrap +msgid "> Note: If a migration is not reversible, you will not be able to redo it.\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/databases/db-migrations.md +#, no-wrap +msgid "Listing Migrations" +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +msgid "To list which migrations have been applied and which are not, you may use the following commands:" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/databases/db-migrations.md +#, no-wrap +msgid "" +"./yii migrate/history # showing the last 10 applied migrations\n" +"./yii migrate:history --limit=5 # showing the last 5 applied migrations\n" +"./yii migrate:history --all # showing all applied migrations\n" +"\n" +"./yii migrate:new # showing the first 10 new migrations\n" +"./yii migrate:new --limit=5 # showing the first 5 new migrations\n" +"./yii migrate:new --all # showing all new migrations\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/databases/db-migrations.md +#, no-wrap +msgid "Upgrading from Yii 2.0" +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +msgid "Migrations in Yii 2.0 and the [yiisoft/db-migration](https://github.com/yiisoft/db-migration/) package are not compatible, and the `migration` table is also not compatible." +msgstr "" + +#. type: Plain text +#: ../src/guide/databases/db-migrations.md +msgid "A probable solution is to use structure dumps and rename the old `migration` table. Upon the initial execution of migrations, a new `migration` table with new fields will be created. All further changes in the database schema are applied using the new `migration` component and recorded in the new migration table." +msgstr "" diff --git a/_translations/po/pt-BR/guide_glossary.md.po b/_translations/po/pt-BR/guide_glossary.md.po new file mode 100644 index 00000000..46a1927c --- /dev/null +++ b/_translations/po/pt-BR/guide_glossary.md.po @@ -0,0 +1,547 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-05-30 06:43+0000\n" +"PO-Revision-Date: 2026-05-30 06:43+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/guide/glossary.md +#, no-wrap +msgid "A" +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "action" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "Action is a callable, class, or class method that handles a matched route and returns a response. Read more in [\"Actions\"](structure/action.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "alias" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "Alias is a string used by Yii to refer to the class or directory such as `@app/vendor`. Read more in [\"Aliases\"](concept/aliases.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "application" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "Application is an object that starts up, handles a request through configured middleware, and shuts down. Read more in [\"Application\"](structure/application.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "asset" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "Asset refers to a resource file. Typically, it contains JavaScript or CSS code but can be any static content accessed via HTTP. Read more in [\"Assets\"](views/asset.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "asset bundle" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "Asset bundle is a PHP class that declares a group of CSS, JavaScript, image, or font files that should be published and registered together. Read more in [\"Asset Bundles\"](views/asset.md#asset-bundles)." +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "authentication" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "Authentication is the process of determining the identity of the current user. Read more in [\"Authentication\"](security/authentication.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "authorization" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "Authorization is the process of checking whether an authenticated or anonymous user is allowed to perform an action. Read more in [\"Authorization\"](security/authorization.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "autoloading" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "Autoloading is the process of loading PHP classes automatically when they are first used. Read more in [\"Class autoloading\"](concept/autoloading.md)." +msgstr "" + +#. type: Title # +#: ../src/guide/glossary.md +#, no-wrap +msgid "B" +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "bootstrap" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "Bootstrap is application startup code that prepares services, configuration, and runtime state before request handling. Read more in [\"Configuration\"](concept/configuration.md)." +msgstr "" + +#. type: Title # +#: ../src/guide/glossary.md +#, no-wrap +msgid "C" +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "configuration" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "Configuration may refer either to the process of setting properties of an object or to a configuration file that stores settings for an object, or a class of objects. Read more in [\"Configuration\"](concept/configuration.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "container" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "Container is an object that creates services, resolves their dependencies, and returns configured instances. Read more in [\"DI container\"](concept/di-container.md#di-container)." +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "controller" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "Controller is a class that groups action methods for related routes. Read more in [\"Actions\"](structure/action.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "cookie" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "Cookie is a small piece of data stored by a browser and sent with later requests to the same site. Read more in [\"Cookies\"](runtime/cookies.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "CSRF" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "CSRF means cross-site request forgery, an attack where another site tries to make a user's browser submit an unwanted request to your application. Read more in [\"Avoiding CSRF\"](security/best-practices.md#avoiding-csrf)." +msgstr "" + +#. type: Title # +#: ../src/guide/glossary.md +#, no-wrap +msgid "D" +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "DI" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "Dependency injection is a programming technique where an object receives its dependencies from the outside. Read more in [\"Dependency injection and container\"](concept/di-container.md)." +msgstr "" + +#. type: Title # +#: ../src/guide/glossary.md +#, no-wrap +msgid "E" +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "entry script" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "Entry script is the first PHP script executed for a web or console application. Read more in [\"Entry scripts\"](structure/entry-script.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "event" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "Event is an object that represents something that happened and can be passed to listeners. Read more in [\"Events\"](concept/events.md)." +msgstr "" + +#. type: Title # +#: ../src/guide/glossary.md +#, no-wrap +msgid "H" +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "handler" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "Handler is callable code selected by routing or middleware to process a request and produce a response. Read more in [\"Routing and URL generation\"](runtime/routing.md)." +msgstr "" + +#. type: Title # +#: ../src/guide/glossary.md +#, no-wrap +msgid "I" +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "installation" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "Installation is a process of preparing something to work either by following a readme file or by executing a specially prepared script. In the case of Yii, it's setting permissions and fulfilling software requirements." +msgstr "" + +#. type: Title # +#: ../src/guide/glossary.md +#, no-wrap +msgid "L" +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "layout" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "Layout is a view template that wraps page-specific content with shared page structure. Read more in [\"Working with layouts\"](views/view.md#working-with-layouts)." +msgstr "" + +#. type: Title # +#: ../src/guide/glossary.md +#, no-wrap +msgid "M" +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "migration" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "Migration is a versioned PHP class that applies or reverts a database schema or data change. Read more in [\"Migrations\"](databases/db-migrations.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "middleware" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "Middleware is a processor in the request processing stack. Given a request, it may either produce a response or do some action and pass processing to the next middleware. Read more in [\"Middleware\"](structure/middleware.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "model" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "Model is an object that represents application data and usually contains validation or business rules for that data. Read more in [\"Working with forms\"](start/forms.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "module" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "The module is a namespace that groups some code based on a use-case. It's typically used within the main application and may contain any source code, define additional URL handlers or console commands." +msgstr "" + +#. type: Title # +#: ../src/guide/glossary.md +#, no-wrap +msgid "N" +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "namespace" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "Namespace refers to a [PHP language feature](https://www.php.net/manual/en/language.namespaces.php) to group multiple classes under a certain name." +msgstr "" + +#. type: Title # +#: ../src/guide/glossary.md +#, no-wrap +msgid "P" +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "package" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "A package usually refers to [Composer package](https://getcomposer.org/doc/). It's code ready for reuse and redistribution installable automatically via a package manager." +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "parameter" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "Parameter is a configuration value that can be used by application or package config files. Read more in [\"Parameters\"](concept/configuration.md#parameters)." +msgstr "" + +#. type: Title # +#: ../src/guide/glossary.md +#, no-wrap +msgid "Q" +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "queue" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "A queue is a data structure that processes items in first-in, first-out order. Yii has a [yiisoft/queue](https://github.com/yiisoft/queue) package." +msgstr "" + +#. type: Title # +#: ../src/guide/glossary.md +#, no-wrap +msgid "R" +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "request" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "Request is a PSR-7 object that represents an incoming HTTP message, including method, URI, headers, body, uploaded files, and attributes. Read more in [\"Request\"](runtime/request.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "response" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "Response is a PSR-7 object that represents an outgoing HTTP message, including status code, headers, and body. Read more in [\"Response\"](runtime/response.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "route" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "Route describes which request method and URL pattern should be handled by which action or middleware. Read more in [\"Routing and URL generation\"](runtime/routing.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "rule" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "The rule usually refers to a validation rule of the [yiisoft/validator](https://github.com/yiisoft/validator) package. It holds a set of parameters for checking if a data set is valid. \"Rule handler\" does the actual processing." +msgstr "" + +#. type: Title # +#: ../src/guide/glossary.md +#, no-wrap +msgid "S" +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "service" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "Service is a focused object that performs application work or provides infrastructure behavior and is usually stored in the DI container. Read more in [\"Service components\"](structure/service.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "service provider" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "Service provider is a class that registers related service definitions for the DI container. Read more in [\"Service providers\"](concept/configuration.md#service-providers)." +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "session" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "Session is server-side storage associated with a browser across multiple requests. Read more in [\"Sessions\"](runtime/sessions.md)." +msgstr "" + +#. type: Title # +#: ../src/guide/glossary.md +#, no-wrap +msgid "T" +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "template" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "Template is a file used by a view or template engine to produce presentation output such as HTML. Read more in [\"Views\"](views/view.md)." +msgstr "" + +#. type: Title # +#: ../src/guide/glossary.md +#, no-wrap +msgid "V" +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "vendor" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "A vendor is an organization or individual developer providing code in the form of packages. It also may refer to [Composer's `vendor` directory](https://getcomposer.org/doc/)." +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "view" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "View is responsible for presenting data to end users, usually by executing a template with provided data. Read more in [\"Views\"](views/view.md)." +msgstr "" + +#. type: Title # +#: ../src/guide/glossary.md +#, no-wrap +msgid "W" +msgstr "" + +#. type: Title ## +#: ../src/guide/glossary.md +#, no-wrap +msgid "widget" +msgstr "" + +#. type: Plain text +#: ../src/guide/glossary.md +msgid "Widget is a reusable view component that renders a piece of user interface. Read more in [\"Widgets\"](views/widget.md)." +msgstr "" diff --git a/_translations/po/pt-BR/guide_index.md.po b/_translations/po/pt-BR/guide_index.md.po new file mode 100644 index 00000000..bd951fec --- /dev/null +++ b/_translations/po/pt-BR/guide_index.md.po @@ -0,0 +1,630 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-10-11 10:37+0000\n" +"PO-Revision-Date: 2026-10-11 10:37+0000\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ### +#: ../src/cookbook/making-http-requests.md ../src/guide/index.md ../src/guide/intro/upgrade-from-v2.md ../src/guide/testing/overview.md ../src/guide/tutorial/docker.md +#, no-wrap +msgid "Testing" +msgstr "Testes" + +#. type: Title ## +#: ../src/guide/caching/overview.md ../src/guide/index.md +#, no-wrap +msgid "Caching" +msgstr "Cache" + +#. type: Title # +#: ../src/guide/index.md +#, no-wrap +msgid "The definitive guide to Yii3" +msgstr "O guia definitivo do Yii3" + +#. type: Plain text +#: ../src/guide/index.md +msgid "We release this guide under the [Terms of Yii Documentation](https://www.yiiframework.com/license#docs)." +msgstr "Este guia é publicado sob os [Termos da documentação do Yii](https://www.yiiframework.com/license#docs)." + +#. type: Title ## +#: ../src/guide/index.md +#, no-wrap +msgid "Introduction" +msgstr "Introdução" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[About Yii](intro/what-is-yii.md)" +msgstr "[Sobre o Yii](intro/what-is-yii.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Upgrading from version 1.1](intro/upgrade-from-v1.md)" +msgstr "[Atualizando a partir da versão 1.1](intro/upgrade-from-v1.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Upgrading from version 2.0](intro/upgrade-from-v2.md)" +msgstr "[Atualizando a partir da versão 2.0](intro/upgrade-from-v2.md)" + +#. type: Title ## +#: ../src/guide/index.md ../src/guide/tutorial/console-applications.md +#, no-wrap +msgid "Getting started" +msgstr "Primeiros passos" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[What do you need to know?](start/prerequisites.md)" +msgstr "[O que você precisa saber?](start/prerequisites.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Creating a project](start/creating-project.md)" +msgstr "[Criando um projeto](start/creating-project.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Application Workflow](start/workflow.md)" +msgstr "[Fluxo da aplicação](start/workflow.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Saying hello](start/hello.md)" +msgstr "[Dizendo olá](start/hello.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Working with forms](start/forms.md)" +msgstr "[Trabalhando com formulários](start/forms.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Working with databases](start/databases.md)" +msgstr "[Trabalhando com bancos de dados](start/databases.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Generating code with Gii](start/gii.md) TODO" +msgstr "[Gerando código com o Gii](start/gii.md) TODO" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Looking ahead](start/looking-ahead.md)" +msgstr "[Seguindo em frente](start/looking-ahead.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Demo applications](start/demo-apps.md)" +msgstr "[Aplicações de demonstração](start/demo-apps.md)" + +#. type: Title ## +#: ../src/guide/index.md +#, no-wrap +msgid "Key concepts" +msgstr "Conceitos principais" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Aliases](concept/aliases.md)" +msgstr "[Aliases](concept/aliases.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Autoloading](concept/autoloading.md)" +msgstr "[Autoload](concept/autoloading.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Configuration](concept/configuration.md)" +msgstr "[Configuração](concept/configuration.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Dependency injection container](concept/di-container.md)" +msgstr "[Container de injeção de dependência](concept/di-container.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Events](concept/events.md)" +msgstr "[Eventos](concept/events.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Immutability](concept/immutability.md)" +msgstr "[Imutabilidade](concept/immutability.md)" + +#. type: Title ## +#: ../src/guide/index.md ../src/guide/start/workflow.md +#, no-wrap +msgid "Application structure" +msgstr "Estrutura da aplicação" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Application structure overview](structure/overview.md)" +msgstr "[Visão geral da estrutura da aplicação](structure/overview.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Entry scripts](structure/entry-script.md)" +msgstr "[Scripts de entrada](structure/entry-script.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Application](structure/application.md)" +msgstr "[Aplicação](structure/application.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Modules](structure/module.md)" +msgstr "[Módulos](structure/module.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Actions](structure/action.md)" +msgstr "[Actions](structure/action.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Middleware](structure/middleware.md)" +msgstr "[Middleware](structure/middleware.md)" + +#. type: Title ## +#: ../src/guide/index.md +#, no-wrap +msgid "Packages" +msgstr "Pacotes" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Using packages](structure/package.md)" +msgstr "[Usando pacotes](structure/package.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Designing packages](structure/designing-packages.md)" +msgstr "[Projetando pacotes](structure/designing-packages.md)" + +#. type: Title ## +#: ../src/guide/index.md +#, no-wrap +msgid "Handling requests" +msgstr "Tratando requisições" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Routing and URL generation](runtime/routing.md)" +msgstr "[Roteamento e geração de URLs](runtime/routing.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Request](runtime/request.md)" +msgstr "[Requisição](runtime/request.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Response](runtime/response.md)" +msgstr "[Resposta](runtime/response.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Sessions](runtime/sessions.md)" +msgstr "[Sessões](runtime/sessions.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Cookies](runtime/cookies.md)" +msgstr "[Cookies](runtime/cookies.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Handling errors](runtime/handling-errors.md)" +msgstr "[Tratamento de erros](runtime/handling-errors.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Logging](runtime/logging.md)" +msgstr "[Logs](runtime/logging.md)" + +#. type: Title # +#: ../src/guide/index.md ../src/guide/security/overview.md +#, no-wrap +msgid "Security" +msgstr "Segurança" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Security overview](security/overview.md)" +msgstr "[Visão geral de segurança](security/overview.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Authentication](security/authentication.md)" +msgstr "[Autenticação](security/authentication.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Authorization](security/authorization.md) TODO: verify and complete!" +msgstr "[Autorização](security/authorization.md) TODO: verify and complete!" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Working with passwords](security/passwords.md)" +msgstr "[Trabalhando com senhas](security/passwords.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Cryptography](security/cryptography.md)" +msgstr "[Criptografia](security/cryptography.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Trusted request](security/trusted-request.md)" +msgstr "[Requisição confiável](security/trusted-request.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Best practices](security/best-practices.md)" +msgstr "[Boas práticas](security/best-practices.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Caching overview](caching/overview.md)" +msgstr "[Visão geral do cache](caching/overview.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Data caching](caching/data.md)" +msgstr "[Cache de dados](caching/data.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "Fragment caching TODO" +msgstr "Cache de fragmentos TODO" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "Page caching TODO" +msgstr "Cache de páginas TODO" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "HTTP caching TODO" +msgstr "Cache HTTP TODO" + +#. type: Title # +#: ../src/guide/index.md ../src/guide/start/databases.md +#, no-wrap +msgid "Working with databases" +msgstr "Trabalhando com bancos de dados" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Yii DB](https://github.com/yiisoft/db/blob/master/docs/guide/en/README.md)" +msgstr "[Yii DB](https://github.com/yiisoft/db/blob/master/docs/guide/en/README.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Active Record](https://github.com/yiisoft/active-record/blob/master/README.md)" +msgstr "[Active Record](https://github.com/yiisoft/active-record/blob/master/README.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Migrations](databases/db-migrations.md) TODO: verify/update!" +msgstr "[Migrations](databases/db-migrations.md) TODO: verify/update!" + +#. type: Title # +#: ../src/guide/index.md ../src/guide/views/view.md +#, no-wrap +msgid "Views" +msgstr "Views" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[View](views/view.md)" +msgstr "[View](views/view.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Assets](views/asset.md) TODO: verify!" +msgstr "[Assets](views/asset.md) TODO: verify!" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Scripts, styles and metatags](views/script-style-meta.md) TODO: verify!" +msgstr "[Scripts, estilos e meta tags](views/script-style-meta.md) TODO: verify!" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Template engines](views/template-engines.md) TODO: verify!" +msgstr "[Template engines](views/template-engines.md) TODO: verify!" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[View injections](views/view-injections.md)" +msgstr "[Injeções em views](views/view-injections.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Widgets](views/widget.md) TODO: verify!" +msgstr "[Widgets](views/widget.md) TODO: verify!" + +#. type: Title ## +#: ../src/guide/index.md +#, no-wrap +msgid "Getting data from users" +msgstr "Recebendo dados dos usuários" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "Creating forms TODO" +msgstr "Criando formulários TODO" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Validating input](https://github.com/yiisoft/validator/blob/master/docs/guide/en/README.md)" +msgstr "[Validando entradas](https://github.com/yiisoft/validator/blob/master/docs/guide/en/README.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "Uploading files TODO" +msgstr "Upload de arquivos TODO" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "Collecting tabular input TODO" +msgstr "Coletando dados tabulares TODO" + +#. type: Title ## +#: ../src/guide/index.md +#, no-wrap +msgid "Displaying data" +msgstr "Exibindo dados" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "Data formatting TODO" +msgstr "Formatação de dados TODO" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "Pagination TODO" +msgstr "Paginação TODO" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "Sorting TODO" +msgstr "Ordenação TODO" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "Data providers TODO" +msgstr "Data providers TODO" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "Data widgets TODO" +msgstr "Widgets de dados TODO" + +#. type: Title ## +#: ../src/guide/index.md ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "REST APIs" +msgstr "APIs REST" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Quick start](rest/quick-start.md)" +msgstr "[Início rápido](rest/quick-start.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "Resources TODO" +msgstr "Recursos TODO" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "Controllers TODO" +msgstr "Controllers TODO" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "Routing TODO" +msgstr "Roteamento TODO" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "Authentication TODO" +msgstr "Autenticação TODO" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "Rate limiting TODO" +msgstr "Limitação de requisições TODO" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "Versioning TODO" +msgstr "Versionamento TODO" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "Error handling TODO" +msgstr "Tratamento de erros TODO" + +#. type: Title ## +#: ../src/guide/index.md +#, no-wrap +msgid "Development tools" +msgstr "Ferramentas de desenvolvimento" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "Debug toolbar and debugger" +msgstr "Barra e painel de debug" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "Generating code using Gii" +msgstr "Gerando código com o Gii" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "Generating API documentation" +msgstr "Gerando documentação da API" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Testing overview](testing/overview.md)" +msgstr "[Visão geral de testes](testing/overview.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Testing environment setup](testing/environment-setup.md)" +msgstr "[Configurando o ambiente de testes](testing/environment-setup.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Unit tests](testing/unit.md)" +msgstr "[Testes unitários](testing/unit.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Functional tests](testing/functional.md)" +msgstr "[Testes funcionais](testing/functional.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[End-to-end tests](testing/end-to-end.md)" +msgstr "[Testes end-to-end](testing/end-to-end.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Static analysis and mutation testing](testing/quality-tools.md)" +msgstr "[Análise estática e testes de mutação](testing/quality-tools.md)" + +#. type: Title ## +#: ../src/guide/index.md +#, no-wrap +msgid "Special topics" +msgstr "Tópicos especiais" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Console applications](tutorial/console-applications.md)" +msgstr "[Aplicações de console](tutorial/console-applications.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Mailing](tutorial/mailing.md)" +msgstr "[Envio de e-mails](tutorial/mailing.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Performance tuning](tutorial/performance-tuning.md)" +msgstr "[Otimização de desempenho](tutorial/performance-tuning.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Using Yii with event loop](tutorial/using-with-event-loop.md)" +msgstr "[Usando o Yii com event loop](tutorial/using-with-event-loop.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Using Yii with FrankenPHP](tutorial/using-yii-with-frankenphp.md)" +msgstr "[Usando o Yii com FrankenPHP](tutorial/using-yii-with-frankenphp.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Using Yii with Rapira](tutorial/using-yii-with-rapira.md)" +msgstr "[Usando o Yii com Rapira](tutorial/using-yii-with-rapira.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Using Yii with RoadRunner](tutorial/using-yii-with-roadrunner.md)" +msgstr "[Usando o Yii com RoadRunner](tutorial/using-yii-with-roadrunner.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Using Yii with Swoole](tutorial/using-yii-with-swoole.md)" +msgstr "[Usando o Yii com Swoole](tutorial/using-yii-with-swoole.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Docker in application templates](tutorial/docker.md)" +msgstr "[Docker nos templates de aplicação](tutorial/docker.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Internationalization](tutorial/i18n.md)" +msgstr "[Internacionalização](tutorial/i18n.md)" + +#. type: Title ## +#: ../src/guide/index.md +#, no-wrap +msgid "Helpers" +msgstr "Helpers" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Arrays](https://github.com/yiisoft/arrays/)" +msgstr "[Arrays](https://github.com/yiisoft/arrays/)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Files](https://github.com/yiisoft/files/)" +msgstr "[Arquivos](https://github.com/yiisoft/files/)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Html](https://github.com/yiisoft/html/)" +msgstr "[Html](https://github.com/yiisoft/html/)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Json](https://github.com/yiisoft/json)" +msgstr "[Json](https://github.com/yiisoft/json)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Network utilities](https://github.com/yiisoft/network-utilities/)" +msgstr "[Utilitários de rede](https://github.com/yiisoft/network-utilities/)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[VarDumper](https://github.com/yiisoft/var-dumper)" +msgstr "[VarDumper](https://github.com/yiisoft/var-dumper)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Strings](https://github.com/yiisoft/strings)" +msgstr "[Strings](https://github.com/yiisoft/strings)" + +#. type: Title ## +#: ../src/guide/index.md +#, no-wrap +msgid "Extras" +msgstr "Extras" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Cookbook](../cookbook/index.md)" +msgstr "[Cookbook](../cookbook/index.md)" + +#. type: Bullet: '- ' +#: ../src/guide/index.md +msgid "[Glossary](glossary.md)" +msgstr "[Glossário](glossary.md)" diff --git a/_translations/po/pt-BR/guide_intro_upgrade-from-v1.md.po b/_translations/po/pt-BR/guide_intro_upgrade-from-v1.md.po new file mode 100644 index 00000000..37b6f5f2 --- /dev/null +++ b/_translations/po/pt-BR/guide_intro_upgrade-from-v1.md.po @@ -0,0 +1,1189 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-09-25 14:35+0000\n" +"PO-Revision-Date: 2026-09-25 14:35+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/cookbook/deployment/angie-docker-proxy.md +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "Project structure" +msgstr "" + +#. type: Fenced code block (json) +#: ../src/guide/concept/autoloading.md ../src/guide/intro/upgrade-from-v1.md +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"{\n" +" \"autoload\": {\n" +" \"psr-4\": {\n" +" \"App\\\\\": \"src/\"\n" +" }\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title # +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "Upgrading from Version 1.1" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "" +"> If you haven't used Yii 1.1, you can skip this section and get directly to\n" +"> \"[getting started](../start/prerequisites.md)\" section.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Yii3 is not an incremental upgrade from Yii 1.1. Yii 2.0 was a full rewrite, and Yii3 changes the architecture again: Composer packages, namespaces, PHP 8, PSR interfaces, dependency injection, explicit routes, middleware, and separate packages for features that were built into the framework in Yii 1.1." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Treat this as building a new Yii3 application with the benefit of Yii 1.1 experience. Reuse the domain knowledge, database schema, user workflows, and selected code after refactoring. Do not try to reproduce the Yii 1.1 application structure in Yii3. A direct search-and-replace conversion is not realistic." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "For additional background, read the Yii 2.0 guide section [Upgrading from Version 1.1](https://www.yiiframework.com/doc/guide/2.0/en/intro-upgrade-from-v1). It explains the first major break from Yii 1.1: Composer, namespaces, object configuration, view changes, controller return values, widgets, assets, helpers, forms, query builder, Active Record, and URL management. Yii3 builds on many of those changes and makes dependencies more explicit." +msgstr "" + +#. type: Title ## +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "Recommended approach" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Choose one of these paths:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Build a new Yii3 application directly when the Yii 1.1 application is small or you are already rewriting request flows." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Move Yii 1.1 concepts to Yii 2.0 first when the team needs a smaller conceptual step." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Keep Yii 1.1 running and rebuild critical flows in Yii3 one by one." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "For most long-lived applications, the third option is the least risky. Create a Yii3 application, connect it to the same database, and build vertical slices: route, action, input validation, persistence, view, assets, and tests. Each slice should be idiomatic Yii3, even when it is based on behavior from the Yii 1.1 application." +msgstr "" + +#. type: Title ## +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "Prepare the Yii 1.1 application" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Useful preparation can happen before the Yii3 application is ready. These refactorings make old behavior easier to understand and reduce the amount of Yii 1.1 framework state that crosses into the new code:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Remove direct `Yii::app()` access from reusable code where practical. If a full refactoring is too large, keep `Yii::app()` calls near controllers, widgets, and commands, then pass values and services to lower-level code explicitly." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Introduce repositories or query services for database reads currently spread across controllers, views, `CActiveRecord` methods, and widgets. Yii3 can use Active Record, but it does not require it for every persistence task." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Separate business rules from framework infrastructure. Code that does not extend `CComponent`, read global application state, or render views is easier to reuse as a specification for Yii3 code." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Move reusable behavior out of large controllers and Active Record classes into Yii 1.1 application components or plain services. Yii3 services are configured and injected differently, but the responsibility boundary is similar." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Add tests or characterization checks around routes and workflows you plan to rebuild first. They become the executable specification for the Yii3 slice." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +msgid "For example, instead of reading post archive data directly from several controllers or widgets, create a small service that describes the application need:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "" +"class PostRepository extends CComponent\n" +"{\n" +" public function getArchive()\n" +" {\n" +" // ...\n" +" }\n" +"\n" +" public function getTopForFrontPage($limit = 10)\n" +" {\n" +" // ...\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "The Yii3 implementation may use `yiisoft/active-record`, `yiisoft/db`, or another persistence layer. The important point is that controllers and views no longer need to know that detail." +msgstr "" + +#. type: Title ## +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "Things to learn before starting" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Some Yii3 application-template choices are likely to be new in a Yii 1.1 codebase:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md +msgid "[Composer](https://getcomposer.org/). Yii3 applications and packages are installed through Composer and loaded with PSR-4 autoloading." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md +msgid "[Namespaces](https://www.php.net/manual/en/language.namespaces.php). Yii3 classes are namespaced instead of using Yii 1.1-style class prefixes and path aliases for class loading." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +msgid "[Docker](https://www.docker.com/get-started/). The default Yii3 application template includes Docker configuration. Using it gives each application its own repeatable environment and reduces differences between local development and production." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +msgid "[Environment variables](https://en.wikipedia.org/wiki/Environment_variable). Yii3 templates commonly use them for environment-specific settings and secrets, especially in Docker-based deployments. This follows the same idea as [12-factor app configuration](https://12factor.net/config)." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +msgid "[Actions](../structure/action.md). Yii3 does not require controller inheritance. A route can point to any callable, and the default template uses invokable action classes." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md +msgid "[Application structure](../structure/overview.md). Yii3's default structure is different from Yii 1.1. Start with the Yii3 template and change it only when the application needs it." +msgstr "" + +#. type: Title ## +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "PHP, Composer, and namespaces" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Yii 1.1 applications commonly rely on PHP 5-era code, class prefixes such as `CController`, and autoloading by class name. Yii3 applications require modern PHP and Composer autoloading." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Yii 1.1:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "" +"class SiteController extends CController\n" +"{\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Yii3:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "" +"namespace App\\Web\\HomePage;\n" +"\n" +"final readonly class Action\n" +"{\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +msgid "Configure your application namespace with PSR-4:" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Run:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "composer dump-autoload\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "When reusing a class, give it a namespace, add strict types, replace Yii 1.1 base classes, and inject dependencies instead of reading them from global application state. If these changes make the class awkward, use the old class as a specification and write a new Yii3 class instead." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "A Yii 1.1 application often uses:" +msgstr "" + +#. type: Fenced code block (text) +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "" +"protected/\n" +" commands/\n" +" components/\n" +" config/\n" +" controllers/\n" +" extensions/\n" +" messages/\n" +" migrations/\n" +" models/\n" +" views/\n" +"themes/\n" +"webroot/\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "The current Yii3 application template uses:" +msgstr "" + +#. type: Fenced code block (text) +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"assets/\n" +"config/\n" +"public/\n" +"runtime/\n" +"src/\n" +"tests/\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +msgid "Typical mappings to consider are:" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "" +"| Yii 1.1 | Yii3 |\n" +"|---------|------|\n" +"| `protected/controllers` | `src/Web/*/Action.php` or controller-like services |\n" +"| `protected/models` | `src/Domain`, `src/Shared`, `src/Db`, or form models by responsibility |\n" +"| `protected/views` | templates near the feature, for example `src/Web/HomePage/template.php` |\n" +"| `protected/views/layouts` | layout templates and assets under `src/Web/Shared/Layout` |\n" +"| `protected/components` | services configured in the dependency injection container |\n" +"| `protected/extensions` | Composer packages or local packages |\n" +"| `protected/commands` | `src/Console/*Command.php` |\n" +"| `protected/messages` | translator message files |\n" +"| `protected/config` | `config/common`, `config/web`, `config/console`, `config/environments` |\n" +"| `webroot` | `public` |\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Do not recreate `protected` in Yii3. Put PHP source under `src`, public files under `public`, generated/runtime files under `runtime`, and configuration under `config`." +msgstr "" + +#. type: Title ## +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "Configuration and application components" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Yii 1.1 configuration is usually one large array:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "" +"return [\n" +" 'basePath' => dirname(__DIR__),\n" +" 'components' => [\n" +" 'db' => [\n" +" 'connectionString' => 'mysql:host=localhost;dbname=app',\n" +" 'username' => 'root',\n" +" 'password' => '',\n" +" ],\n" +" 'urlManager' => [\n" +" 'urlFormat' => 'path',\n" +" 'rules' => [\n" +" 'post/' => 'post/view',\n" +" ],\n" +" ],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "In Yii3, configuration is split by purpose and services are wired through the container:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md +msgid "aliases in `config/common/aliases.php`;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md +msgid "parameters in `config/common/params.php` and environment files;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md +msgid "shared service definitions in `config/common/di/*.php`;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md +msgid "web-only service definitions in `config/web/di/*.php`;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md +msgid "routes in `config/common/routes.php`;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md +msgid "console commands in `config/console/*.php`." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "The default template's console DI group reuses shared definitions from `config/common/di/*.php`. If you need console-only container definitions, add files for them to the `di-console` group in `config/configuration.php` and rebuild the merge plan." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "Replace `Yii::app()->componentName` with constructor-injected services:\n" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "" +"use Yiisoft\\Db\\Connection\\ConnectionInterface;\n" +"use Yiisoft\\Router\\UrlGeneratorInterface;\n" +"\n" +"final readonly class PostRepository\n" +"{\n" +" public function __construct(\n" +" private ConnectionInterface $db,\n" +" private UrlGeneratorInterface $urlGenerator,\n" +" ) {\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +msgid "See [Configuration](../concept/configuration.md), [Aliases](../concept/aliases.md), and [Dependency injection container](../concept/di-container.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "Entry script" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Yii 1.1 entry scripts commonly load `yii.php` and create a web application:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "" +"require_once __DIR__ . '/../framework/yii.php';\n" +"\n" +"Yii::createWebApplication($config)->run();\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Yii3 entry scripts load Composer and bootstrap the configured application. Start with the `public/index.php` file from `yiisoft/app` and adjust configuration instead of building the application manually in the entry script." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +msgid "See [Entry scripts](../structure/entry-script.md) and [Application workflow](../start/workflow.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "Controllers, actions, and routes" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Yii 1.1 controllers extend `CController`, and actions are methods named `actionName`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "" +"class PostController extends CController\n" +"{\n" +" public function actionView($id)\n" +" {\n" +" $post = Post::model()->findByPk($id);\n" +"\n" +" if ($post === null) {\n" +" throw new CHttpException(404);\n" +" }\n" +"\n" +" $this->render('view', ['post' => $post]);\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Yii3 does not require controller inheritance. The current template uses invokable action classes:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "" +"namespace App\\Web\\Post\\View;\n" +"\n" +"use App\\Post\\PostRepository;\n" +"use Psr\\Http\\Message\\ResponseInterface;\n" +"use Yiisoft\\Router\\CurrentRoute;\n" +"use Yiisoft\\Yii\\View\\Renderer\\WebViewRenderer;\n" +"\n" +"final readonly class Action\n" +"{\n" +" public function __construct(\n" +" private CurrentRoute $currentRoute,\n" +" private PostRepository $posts,\n" +" private WebViewRenderer $viewRenderer,\n" +" ) {\n" +" }\n" +"\n" +" public function __invoke(): ResponseInterface\n" +" {\n" +" $post = $this->posts->findById((int) $this->currentRoute->getArgument('id'));\n" +"\n" +" return $this->viewRenderer->render(__DIR__ . '/template', [\n" +" 'post' => $post,\n" +" ]);\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "The route is explicit:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "" +"use App\\Web\\Post\\View;\n" +"use Yiisoft\\Router\\Route;\n" +"\n" +"return [\n" +" Route::get('/post/{id:\\d+}')\n" +" ->action(View\\Action::class)\n" +" ->name('post/view'),\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Define routes before action bodies. It gives you a checklist of request flows you decided to keep in the Yii3 application." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +msgid "See [Actions](../structure/action.md), [Middleware](../structure/middleware.md), and [Routing and URL generation](../runtime/routing.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "Requests, responses, redirects, sessions, and cookies" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Yii 1.1 code often reads and writes through `Yii::app()`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "" +"$id = Yii::app()->request->getParam('id');\n" +"Yii::app()->user->setFlash('success', 'Saved.');\n" +"$this->redirect(['post/view', 'id' => $id]);\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Yii3 uses PSR-7 request and response objects and injectable services. Request input is available from `ServerRequestInterface`; redirects, sessions, cookies, and responses are explicit dependencies." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +msgid "See [Request](../runtime/request.md), [Response](../runtime/response.md), [Sessions](../runtime/sessions.md), and [Cookies](../runtime/cookies.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "Views and layouts" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Yii 1.1 views use `$this` as the controller or widget context. Layouts and partials are rendered through controller methods:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "" +"\n" +"\n" +"

title); ?>

\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "In Yii3 templates, `$this` is a `Yiisoft\\View\\WebView` instance:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "" +"use Yiisoft\\Html\\Html;\n" +"use Yiisoft\\View\\WebView;\n" +"\n" +"/**\n" +" * @var WebView $this\n" +" * @var Post $post\n" +" */\n" +"\n" +"$this->setTitle($post->getTitle());\n" +"?>\n" +"\n" +"

getTitle()) ?>

\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Move controller-specific view logic to the action or to a presenter. Pass only the data a template needs." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "See [View](../views/view.md), [View injections](../views/view-injections.md), and [Template engines](../views/template-engines.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "Assets and client scripts" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Yii 1.1 applications often use `CClientScript`, themes, and extension-specific asset publishing:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "" +"Yii::app()->clientScript->registerCssFile('/css/site.css');\n" +"Yii::app()->clientScript->registerScriptFile('/js/site.js');\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Yii3 uses asset bundles from `yiisoft/assets`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "" +"namespace App\\Web\\Shared\\Layout\\Main;\n" +"\n" +"use Yiisoft\\Assets\\AssetBundle;\n" +"\n" +"final class MainAsset extends AssetBundle\n" +"{\n" +" public ?string $basePath = '@assets/main';\n" +" public ?string $baseUrl = '@assetsUrl/main';\n" +" public ?string $sourcePath = '@assetsSource/main';\n" +"\n" +" public array $css = ['site.css'];\n" +" public array $js = ['site.js'];\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Register bundles through the asset manager in layouts or views." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "See [Assets](../views/asset.md) and [Scripts, styles and metatags](../views/script-style-meta.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "Models, forms, and validation" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Yii 1.1 has `CModel`, `CFormModel`, and `CActiveRecord`. It is common for one model class to contain input data, labels, validation rules, database persistence, and business logic." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Yii3 works better when these responsibilities are split:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md +msgid "form data and labels: `yiisoft/form-model`;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md +msgid "validation rules: `yiisoft/validator`;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md +msgid "form rendering: `yiisoft/form`;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md +msgid "persistence: repositories, `yiisoft/db`, or `yiisoft/active-record`;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md +msgid "business workflows: application services." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Yii 1.1 form model:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "" +"class ContactForm extends CFormModel\n" +"{\n" +" public $name;\n" +" public $email;\n" +"\n" +" public function rules()\n" +" {\n" +" return [\n" +" ['name, email', 'required'],\n" +" ['email', 'email'],\n" +" ];\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Yii3 form model:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"use Yiisoft\\FormModel\\FormModel;\n" +"use Yiisoft\\Validator\\Rule\\Email;\n" +"use Yiisoft\\Validator\\Rule\\Required;\n" +"\n" +"final class ContactForm extends FormModel\n" +"{\n" +" #[Required]\n" +" public ?string $name = null;\n" +"\n" +" #[Required]\n" +" #[Email]\n" +" public ?string $email = null;\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +msgid "See [Working with forms](../start/forms.md), [Validating input](https://github.com/yiisoft/validator/blob/master/docs/guide/en/README.md), [yiisoft/form](https://github.com/yiisoft/form), and [yiisoft/form-model](https://github.com/yiisoft/form-model)." +msgstr "" + +#. type: Title ## +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "Active Record" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Yii 1.1 Active Record uses `CActiveRecord::model()` and dynamic attributes:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "" +"class Post extends CActiveRecord\n" +"{\n" +" public static function model($className = __CLASS__)\n" +" {\n" +" return parent::model($className);\n" +" }\n" +"\n" +" public function tableName()\n" +" {\n" +" return '{{post}}';\n" +" }\n" +"\n" +" public function rules()\n" +" {\n" +" return [\n" +" ['title, body', 'required'],\n" +" ['title', 'length', 'max' => 255],\n" +" ];\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "The incremental Yii3 option is [yiisoft/active-record](https://github.com/yiisoft/active-record):" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "" +"use Yiisoft\\ActiveRecord\\ActiveRecord;\n" +"\n" +"final class Post extends ActiveRecord\n" +"{\n" +" protected int $id;\n" +" protected string $title;\n" +" protected string $body;\n" +"\n" +" public function tableName(): string\n" +" {\n" +" return '{{%post}}';\n" +" }\n" +"\n" +" public function getTitle(): ?string\n" +" {\n" +" return $this->title ?? null;\n" +" }\n" +"\n" +" public function setTitle(string $title): void\n" +" {\n" +" $this->title = $title;\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Move Yii 1.1 `rules()` to a form model, validator rules, or a service. Keep Active Record focused on persistence: table mapping, properties, relations, and database operations." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "For more complex applications, consider replacing Active Record-heavy code with repositories and domain objects. That is more work initially, but it avoids carrying Yii 1.1 form and persistence coupling into the new application." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +msgid "See [Working with databases](../start/databases.md), [Migrations](../databases/db-migrations.md), and [yiisoft/active-record](https://github.com/yiisoft/active-record)." +msgstr "" + +#. type: Title ## +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "Database queries and migrations" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Yii 1.1 code may use `CDbCriteria`, `CDbCommand`, `CActiveDataProvider`, and `CGridView` data providers. In Yii3, use `yiisoft/db` for database access and query building, and `yiisoft/data` / `yiisoft/yii-dataview` for data readers and widgets." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Migrations are not compatible across Yii 1.1 and Yii3. For an existing application, create a baseline from the current schema and use Yii3 migrations for new changes." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "See [Working with databases](../start/databases.md) and [Migrations](../databases/db-migrations.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "GridView and data widgets" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Yii 1.1 `CGridView` is often configured with `CActiveDataProvider`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "" +"$this->widget('zii.widgets.grid.CGridView', [\n" +" 'dataProvider' => $dataProvider,\n" +" 'columns' => [\n" +" 'id',\n" +" 'title',\n" +" [\n" +" 'class' => 'CButtonColumn',\n" +" ],\n" +" ],\n" +"]);\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Yii3 uses [yiisoft/yii-dataview](https://github.com/yiisoft/yii-dataview):" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "" +"use Yiisoft\\Data\\Reader\\ReadableDataInterface;\n" +"use Yiisoft\\Yii\\DataView\\Column\\DataColumn;\n" +"use Yiisoft\\Yii\\DataView\\GridView\\Column\\ActionColumn;\n" +"use Yiisoft\\Yii\\DataView\\GridView\\GridView;\n" +"\n" +"/**\n" +" * @var ReadableDataInterface $dataReader\n" +" */\n" +"\n" +"echo GridView::widget()\n" +" ->dataReader($dataReader)\n" +" ->columns(\n" +" new DataColumn('id'),\n" +" new DataColumn('title'),\n" +" new ActionColumn(),\n" +" );\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Replace the old data provider with a query service that returns a data reader. Model filters as validator rules and route or query parameters." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "See [Using htmx for partial reloads](../../cookbook/using-htmx-for-partial-reloads.md) and [yii-dataview GridView docs](https://github.com/yiisoft/yii-dataview/blob/master/docs/en/guide/gridview.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "URL management" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "" +"echo CHtml::link('View', ['post/view', 'id' => $post->id]);\n" +"$url = Yii::app()->createUrl('post/view', ['id' => $post->id]);\n" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "" +"use Yiisoft\\Html\\Html;\n" +"use Yiisoft\\Router\\UrlGeneratorInterface;\n" +"\n" +"$url = $urlGenerator->generate('post/view', ['id' => $post->getId()]);\n" +"\n" +"echo Html::a('View', $url)->render();\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Prefer named routes. They make views and GridView action columns easier to design and maintain." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "See [Routing and URL generation](../runtime/routing.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "Filters, access control, and authentication" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Yii 1.1 controller filters are controller methods or filter classes:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "" +"public function filters()\n" +"{\n" +" return [\n" +" 'accessControl',\n" +" ];\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Yii3 uses middleware and focused packages. Move authentication, authorization, CSRF, locale detection, and request body parsing out of controllers and into middleware or services." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +msgid "See [Middleware](../structure/middleware.md), [Authentication](../security/authentication.md), and [Authorization](../security/authorization.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "Widgets, helpers, and extensions" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Yii 1.1 widgets and helpers usually depend on Yii-specific base classes such as `CWidget`, `CHtml`, and extension autoloading. In Yii3:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md +msgid "replace helper calls with `yiisoft/html`, `yiisoft/arrays`, `yiisoft/strings`, or application helpers;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md +msgid "replace extensions with Composer packages;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md +msgid "rebuild custom widgets with `yiisoft/widget` or plain services/templates;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md +msgid "replace jQuery UI and Bootstrap widgets with current frontend packages or Yii3 widget packages where available." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "See [Widgets](../views/widget.md)." +msgstr "" + +#. type: Title # +#: ../src/guide/intro/upgrade-from-v1.md +#: ../src/guide/tutorial/console-applications.md +#, no-wrap +msgid "Console applications" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Yii 1.1 console commands extend `CConsoleCommand`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "" +"class ReportCommand extends CConsoleCommand\n" +"{\n" +" public function actionSend()\n" +" {\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Yii3 console commands are Symfony Console commands configured as services:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "" +"namespace App\\Console;\n" +"\n" +"use Symfony\\Component\\Console\\Attribute\\AsCommand;\n" +"use Symfony\\Component\\Console\\Command\\Command;\n" +"use Symfony\\Component\\Console\\Input\\InputInterface;\n" +"use Symfony\\Component\\Console\\Output\\OutputInterface;\n" +"\n" +"#[AsCommand(name: 'report/send')]\n" +"final class SendReportCommand extends Command\n" +"{\n" +" protected function execute(InputInterface $input, OutputInterface $output): int\n" +" {\n" +" return Command::SUCCESS;\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +msgid "See [Console applications](../tutorial/console-applications.md)." +msgstr "" + +#. type: Title # +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "Internationalization" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "Yii 1.1 message files under `protected/messages` can usually be kept conceptually, but configuration changes. Yii3 uses translator packages and explicit message sources. Move message files into the structure expected by the selected translator message package and inject translation services where needed." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "See [Internationalization](../tutorial/i18n.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/intro/upgrade-from-v1.md +#, no-wrap +msgid "What to refactor before reusing" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "These Yii 1.1 refactorings make the old behavior easier to understand and reuse:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md +msgid "isolate database queries from controllers;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md +msgid "remove direct `Yii::app()` access from domain code;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md +msgid "move validation out of Active Record when it describes request input rather than database invariants;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md +msgid "replace large controller actions with services;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md +msgid "document all routes and URL rules;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md +msgid "add tests around the flows you plan to rebuild first;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md +msgid "upgrade PHP syntax gradually if the old runtime allows it." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md +msgid "The goal is not to make Yii 1.1 look like Yii3. The goal is to reduce hidden coupling before the code crosses the framework boundary." +msgstr "" diff --git a/_translations/po/pt-BR/guide_intro_upgrade-from-v2.md.po b/_translations/po/pt-BR/guide_intro_upgrade-from-v2.md.po new file mode 100644 index 00000000..e4ede143 --- /dev/null +++ b/_translations/po/pt-BR/guide_intro_upgrade-from-v2.md.po @@ -0,0 +1,1410 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-09-25 14:35+0000\n" +"PO-Revision-Date: 2026-09-25 14:35+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/cookbook/deployment/angie-docker-proxy.md +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "Project structure" +msgstr "" + +#. type: Title ### +#: ../src/cookbook/making-http-requests.md ../src/guide/index.md +#: ../src/guide/intro/upgrade-from-v2.md ../src/guide/testing/overview.md +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "Testing" +msgstr "Testes" + +#. type: Fenced code block (json) +#: ../src/guide/concept/autoloading.md ../src/guide/intro/upgrade-from-v1.md +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"{\n" +" \"autoload\": {\n" +" \"psr-4\": {\n" +" \"App\\\\\": \"src/\"\n" +" }\n" +" }\n" +"}\n" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/concept/configuration.md ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"use App\\Web;\n" +"use Yiisoft\\Router\\Group;\n" +"use Yiisoft\\Router\\Route;\n" +"\n" +"return [\n" +" Group::create()\n" +" ->routes(\n" +" Route::get('/')\n" +" ->action(Web\\HomePage\\Action::class)\n" +" ->name('home'),\n" +" ),\n" +"];\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/index.md ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "REST APIs" +msgstr "APIs REST" + +#. type: Title ## +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "Recommended approach" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +msgid "For example, instead of reading post archive data directly from several controllers or widgets, create a small service that describes the application need:" +msgstr "" + +#. type: Title ## +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "Things to learn before starting" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +msgid "[Docker](https://www.docker.com/get-started/). The default Yii3 application template includes Docker configuration. Using it gives each application its own repeatable environment and reduces differences between local development and production." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +msgid "[Environment variables](https://en.wikipedia.org/wiki/Environment_variable). Yii3 templates commonly use them for environment-specific settings and secrets, especially in Docker-based deployments. This follows the same idea as [12-factor app configuration](https://12factor.net/config)." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +msgid "[Actions](../structure/action.md). Yii3 does not require controller inheritance. A route can point to any callable, and the default template uses invokable action classes." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +msgid "Configure your application namespace with PSR-4:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "composer dump-autoload\n" +msgstr "" + +#. type: Fenced code block (text) +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"assets/\n" +"config/\n" +"public/\n" +"runtime/\n" +"src/\n" +"tests/\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +msgid "Typical mappings to consider are:" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +msgid "See [Configuration](../concept/configuration.md), [Aliases](../concept/aliases.md), and [Dependency injection container](../concept/di-container.md)." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +msgid "See [Entry scripts](../structure/entry-script.md) and [Application workflow](../start/workflow.md)." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +msgid "See [Actions](../structure/action.md), [Middleware](../structure/middleware.md), and [Routing and URL generation](../runtime/routing.md)." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +msgid "See [Request](../runtime/request.md), [Response](../runtime/response.md), [Sessions](../runtime/sessions.md), and [Cookies](../runtime/cookies.md)." +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"use Yiisoft\\FormModel\\FormModel;\n" +"use Yiisoft\\Validator\\Rule\\Email;\n" +"use Yiisoft\\Validator\\Rule\\Required;\n" +"\n" +"final class ContactForm extends FormModel\n" +"{\n" +" #[Required]\n" +" public ?string $name = null;\n" +"\n" +" #[Required]\n" +" #[Email]\n" +" public ?string $email = null;\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +msgid "See [Working with forms](../start/forms.md), [Validating input](https://github.com/yiisoft/validator/blob/master/docs/guide/en/README.md), [yiisoft/form](https://github.com/yiisoft/form), and [yiisoft/form-model](https://github.com/yiisoft/form-model)." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +msgid "See [Working with databases](../start/databases.md), [Migrations](../databases/db-migrations.md), and [yiisoft/active-record](https://github.com/yiisoft/active-record)." +msgstr "" + +#. type: Title ## +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "GridView and data widgets" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +msgid "See [Middleware](../structure/middleware.md), [Authentication](../security/authentication.md), and [Authorization](../security/authorization.md)." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +msgid "See [Console applications](../tutorial/console-applications.md)." +msgstr "" + +#. type: Title # +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "Upgrading from Version 2.0" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"> If you haven't used Yii 2.0, you can skip this section and get directly to \"[getting started](../start/prerequisites.md)\"\n" +"> section.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Yii3 keeps many Yii ideas, but it is not a drop-in replacement for Yii 2.0. It uses PHP 8 features, PSR interfaces, dependency injection, explicit package composition, and a different application template. Use your Yii 2.0 experience to design a new Yii3 application deliberately instead of trying to reproduce the old application structure." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "For source applications, compare against:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "[yiisoft/yii2-app-basic](https://github.com/yiisoft/yii2-app-basic)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "[yiisoft/yii2-app-advanced](https://github.com/yiisoft/yii2-app-advanced)" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "For the target structure, compare against:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "[yiisoft/app](https://github.com/yiisoft/app)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "[Yii3 guide](../index.md)" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Before starting, [check maintenance policy and end-of-life dates for Yii 2.0](https://www.yiiframework.com/release-cycle). Keeping a mature Yii 2.0 application on Yii 2.0 can be a valid choice. A Yii3 project is most useful when you want the new package ecosystem, stricter typing, PSR middleware, and a more explicit architecture." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Think of the work as building a Yii3 application that is informed by the old one. The old project tells you which routes, forms, database tables, business rules, and user workflows matter. The Yii3 project should decide again where these responsibilities belong." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Build it in vertical slices:" +msgstr "" + +#. type: Bullet: '1. ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Create a new Yii3 application with `yiisoft/app`." +msgstr "" + +#. type: Bullet: '2. ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Configure Composer autoloading and add only the code needed for the slice you are building." +msgstr "" + +#. type: Bullet: '3. ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Define configuration and routes before writing actions." +msgstr "" + +#. type: Bullet: '4. ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Build one request flow at a time: route, action, input model, service, persistence, view, assets, tests." +msgstr "" + +#. type: Bullet: '5. ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Keep the Yii 2.0 application running until each flow is verified in Yii3." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Avoid moving the whole directory tree first. Yii3's defaults are intentionally different, and a mechanical copy tends to preserve Yii 2.0 service-locator assumptions. Prefer small, reviewed decisions over carrying old structure forward because it is familiar." +msgstr "" + +#. type: Title ## +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "Prepare the Yii 2.0 application" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Useful preparation can happen before the Yii3 application is ready. These refactorings improve the Yii 2.0 project itself and make the later rewrite less dependent on hidden framework state:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Replace `Yii::$app` access in reusable code with constructor arguments where practical. If a full dependency injection refactoring is too large, keep `Yii::$app` calls near controllers and widgets, then pass values and services to lower-level code explicitly." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Introduce repositories or query services for database reads that are currently scattered across controllers, views, widgets, and Active Record methods. Yii3 does not require Active Record for persistence, so a repository boundary gives you a natural place to change the implementation later." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Separate business rules from framework infrastructure. Domain code that does not extend Yii classes, read global application state, or render views is much easier to reuse or rewrite." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Move reusable behavior into Yii 2.0 components or services instead of keeping it inside large controllers and Active Record classes. Yii3 services are configured and injected differently, but the responsibility boundary is similar." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Add tests around routes and workflows you plan to rebuild first. They become the executable specification for the Yii3 slice." +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"final class PostRepository\n" +"{\n" +" public function getArchive(): array\n" +" {\n" +" // ...\n" +" }\n" +"\n" +" public function getTopForFrontPage(int $limit = 10): array\n" +" {\n" +" // ...\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "The Yii3 implementation may still use Active Record, or it may use `yiisoft/db` queries. The important point is that controllers and views no longer need to know that detail." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Some Yii3 application-template choices are worth learning before you start moving features:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "[Application structure](../structure/overview.md). Yii3's default structure is different from Yii 2.0. The structure is flexible, but start with the Yii3 template and change it only when the application needs it." +msgstr "" + +#. type: Title ## +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "PHP requirements" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Yii3 application templates require PHP 8.2 or above. As a result, application code can use language features that were not common in Yii 2.0 applications:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "[Type declarations](https://www.php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "[Return type declarations](https://www.php.net/manual/en/functions.returning-values.php#functions.returning-values.type-declaration)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "[Class constant visibility](https://www.php.net/manual/en/language.oop5.constants.php)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "[Named arguments](https://www.php.net/manual/en/functions.arguments.php#functions.named-arguments)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "[Anonymous classes](https://www.php.net/manual/en/language.oop5.anonymous.php)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "[::class](https://www.php.net/manual/en/language.oop5.basic.php#language.oop5.basic.class.class)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "[Generators](https://www.php.net/manual/en/language.generators.php)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "[Variadic functions](https://www.php.net/manual/en/functions.arguments.php#functions.variable-arg-list)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "[Readonly properties](https://www.php.net/manual/en/language.oop5.properties.php#language.oop5.properties.readonly-properties)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "[Readonly classes](https://www.php.net/manual/en/language.oop5.basic.php#language.oop5.basic.class.readonly)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "[Constructor property promotion](https://www.php.net/manual/en/language.oop5.decon.php#language.oop5.decon.constructor.promotion)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "[Attributes](https://www.php.net/manual/en/language.attributes.php)" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Run static analysis and tests on Yii 2.0 before reusing code in Yii3. Code with explicit types, small services, and few implicit `Yii::$app` dependencies is easier to understand and easier to place in the new application." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Yii 2.0 applications commonly keep framework roles in top-level directories:" +msgstr "" + +#. type: Fenced code block (text) +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"assets/\n" +"commands/\n" +"config/\n" +"controllers/\n" +"models/\n" +"runtime/\n" +"views/\n" +"web/\n" +"widgets/\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "The Yii 2.0 advanced template splits the same roles by application:" +msgstr "" + +#. type: Fenced code block (text) +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"backend/\n" +"common/\n" +"console/\n" +"frontend/\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "The current Yii3 application template is organized around source code, configuration, public files, and runtime files:" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"| Yii 2.0 basic | Yii 2.0 advanced | Yii3 |\n" +"|---------------|------------------|------|\n" +"| `controllers/` | `frontend/controllers/`, `backend/controllers/` | `src/Web/*/Action.php` or controller-like classes |\n" +"| `models/` | `common/models/`, app-specific models | `src/Domain`, `src/Shared`, `src/Web/*`, or `src/Db` by responsibility |\n" +"| `views/` | `frontend/views/`, `backend/views/` | templates near the feature, for example `src/Web/HomePage/template.php` |\n" +"| `views/layouts/` | app layout directories | layout classes/templates, for example `src/Web/Shared/Layout/Main` |\n" +"| `assets/` | app asset bundles | `assets/` for source files and `src/Web/.../*Asset.php` for bundles |\n" +"| `web/` | `frontend/web/`, `backend/web/` | `public/` |\n" +"| `commands/` | `console/controllers/` | `src/Console/*Command.php` |\n" +"| `config/*.php` | app and common config files | `config/common`, `config/web`, `config/console`, `config/environments` |\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "There is no single required layout. The important change is that Yii3 applications should group code by responsibility and make dependencies explicit. If you are coming from the advanced template, treat `frontend` and `backend` as separate web contexts. Shared domain code can live in `src/Shared` or in application-specific packages." +msgstr "" + +#. type: Title ## +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "Composer and autoloading" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Yii 2.0 applications usually require `vendor/autoload.php` and `vendor/yiisoft/yii2/Yii.php` in `web/index.php`. Yii3 applications require only Composer's autoloader and application bootstrap code." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Then rebuild Composer autoload files:" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Install Yii3 packages intentionally. Yii3 is split into focused packages, so features such as database access, forms, validation, assets, data widgets, authentication, and caching are separate Composer dependencies." +msgstr "" + +#. type: Title ## +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "Configuration and services" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "In Yii 2.0, many services are configured as application components and accessed through the service locator:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"$cache = Yii::$app->cache;\n" +"$db = Yii::$app->db;\n" +"$url = Yii::$app->urlManager->createUrl(['post/view', 'id' => $id]);\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "In Yii3, services are configured for the container and injected where they are needed:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"use Psr\\SimpleCache\\CacheInterface;\n" +"use Yiisoft\\Db\\Connection\\ConnectionInterface;\n" +"use Yiisoft\\Router\\UrlGeneratorInterface;\n" +"\n" +"final readonly class PostService\n" +"{\n" +" public function __construct(\n" +" private ConnectionInterface $db,\n" +" private CacheInterface $cache,\n" +" private UrlGeneratorInterface $urlGenerator,\n" +" ) {\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Move configuration in groups:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "aliases to `config/common/aliases.php`;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "route definitions to `config/common/routes.php`;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "shared service definitions to `config/common/di/*.php`;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "web-only service definitions to `config/web/di/*.php`;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "console parameters and commands to `config/console/*.php`;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "shared parameters to `config/common/params.php`;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "environment overrides to `config/environments`." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "The default template's `di-console` group reuses shared definitions from `config/common/di/*.php`. If you need console-only container definitions, add the corresponding files to the `di-console` group in `config/configuration.php` and rebuild the merge plan." +msgstr "" + +#. type: Title ## +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "Entry script and bootstrap" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "A Yii 2.0 basic entry script commonly creates the application directly:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"defined('YII_DEBUG') or define('YII_DEBUG', true);\n" +"defined('YII_ENV') or define('YII_ENV', 'dev');\n" +"\n" +"require __DIR__ . '/../vendor/autoload.php';\n" +"require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php';\n" +"\n" +"$config = require __DIR__ . '/../config/web.php';\n" +"\n" +"(new yii\\web\\Application($config))->run();\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "In Yii3, use the application template entry script as the source of truth. It loads Composer and bootstraps the configured application runner. Avoid recreating the old `yii\\web\\Application` pattern in `public/index.php`; put configuration in config files and dependencies in the container." +msgstr "" + +#. type: Title ## +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "Controllers, actions, and routing" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Yii 2.0 routes usually point to controller action methods:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"namespace app\\controllers;\n" +"\n" +"use yii\\web\\Controller;\n" +"\n" +"final class SiteController extends Controller\n" +"{\n" +" public function actionIndex(): string\n" +" {\n" +" return $this->render('index');\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Yii3 does not require controller base classes. The current application template uses invokable action classes:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"namespace App\\Web\\HomePage;\n" +"\n" +"use Psr\\Http\\Message\\ResponseInterface;\n" +"use Yiisoft\\Yii\\View\\Renderer\\WebViewRenderer;\n" +"\n" +"final readonly class Action\n" +"{\n" +" public function __construct(\n" +" private WebViewRenderer $viewRenderer,\n" +" ) {\n" +" }\n" +"\n" +" public function __invoke(): ResponseInterface\n" +" {\n" +" return $this->viewRenderer->render(__DIR__ . '/template');\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Routes are explicit:" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "When redesigning a controller flow, list all Yii 2.0 actions and create named routes for the flows you still need. Then implement each flow as an invokable class or a controller-like service. Constructor injection replaces calls to `Yii::$app` and controller properties." +msgstr "" + +#. type: Title ## +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "Requests, responses, sessions, and cookies" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Yii 2.0 actions often read request data and write response data through application components:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"$id = Yii::$app->request->get('id');\n" +"Yii::$app->session->setFlash('success', 'Saved.');\n" +"\n" +"return $this->redirect(['post/view', 'id' => $id]);\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Yii3 uses PSR-7 request and response objects and injectable services:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"use Psr\\Http\\Message\\ResponseInterface;\n" +"use Psr\\Http\\Message\\ResponseFactoryInterface;\n" +"use Psr\\Http\\Message\\ServerRequestInterface;\n" +"use Yiisoft\\Http\\Status;\n" +"use Yiisoft\\Router\\UrlGeneratorInterface;\n" +"\n" +"final readonly class SavePostAction\n" +"{\n" +" public function __construct(\n" +" private ResponseFactoryInterface $responseFactory,\n" +" private UrlGeneratorInterface $urlGenerator,\n" +" ) {\n" +" }\n" +"\n" +" public function __invoke(ServerRequestInterface $request): ResponseInterface\n" +" {\n" +" $id = (int) ($request->getQueryParams()['id'] ?? 0);\n" +" $url = $this->urlGenerator->generate('post/view', ['id' => $id]);\n" +"\n" +" return $this->responseFactory\n" +" ->createResponse(Status::SEE_OTHER)\n" +" ->withHeader('Location', $url);\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Design request handling early because it affects forms, filters, REST endpoints, redirects, and tests." +msgstr "" + +#. type: Title ## +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "Views, layouts, assets, and URLs" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "In Yii 2.0, controller rendering finds files under `views/{controller}` and layouts under `views/layouts`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"return $this->render('view', [\n" +" 'model' => $model,\n" +"]);\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "In Yii3, the template path is explicit in the action:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"return $this->viewRenderer->render(__DIR__ . '/view', [\n" +" 'post' => $post,\n" +"]);\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "A Yii3 template receives a `Yiisoft\\View\\WebView` instance as `$this`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"use App\\Shared\\ApplicationParams;\n" +"use Yiisoft\\Html\\Html;\n" +"use Yiisoft\\View\\WebView;\n" +"\n" +"/**\n" +" * @var WebView $this\n" +" * @var ApplicationParams $applicationParams\n" +" * @var string $title\n" +" */\n" +"\n" +"$this->setTitle($title . ' - ' . $applicationParams->name);\n" +"?>\n" +"\n" +"

\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Asset bundles move from `yii\\web\\AssetBundle` to `Yiisoft\\Assets\\AssetBundle`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"namespace App\\Web\\Shared\\Layout\\Main;\n" +"\n" +"use Yiisoft\\Assets\\AssetBundle;\n" +"\n" +"final class MainAsset extends AssetBundle\n" +"{\n" +" public ?string $basePath = '@assets/main';\n" +" public ?string $baseUrl = '@assetsUrl/main';\n" +" public ?string $sourcePath = '@assetsSource/main';\n" +"\n" +" public array $css = [\n" +" 'site.css',\n" +" ];\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Register assets in a layout or view via the asset manager:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"$assetManager->register(MainAsset::class);\n" +"\n" +"$this->addCssFiles($assetManager->getCssFiles());\n" +"$this->addJsFiles($assetManager->getJsFiles());\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"Replace `yii\\helpers\\Url` and `Yii::$app->urlManager` usage with named routes and\n" +"`Yiisoft\\Router\\UrlGeneratorInterface`:\n" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "$url = $urlGenerator->generate('post/view', ['id' => $post->getId()]);\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "See [View](../views/view.md), [Assets](../views/asset.md), [Scripts, styles and metatags](../views/script-style-meta.md), and [Template engines](../views/template-engines.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "Forms and validation" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Yii 2.0 frequently combines form data, labels, validation, and sometimes persistence in a `yii\\base\\Model` or `yii\\db\\ActiveRecord` class:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"final class ContactForm extends \\yii\\base\\Model\n" +"{\n" +" public $name;\n" +" public $email;\n" +"\n" +" public function rules(): array\n" +" {\n" +" return [\n" +" [['name', 'email'], 'required'],\n" +" ['email', 'email'],\n" +" ];\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Yii3 separates these concerns. Use `yiisoft/form-model` for form data and metadata, and `yiisoft/validator` for rules:" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "For form rendering, replace `yii\\widgets\\ActiveForm` with `yiisoft/form` fields and form model integration. For input hydration, prefer the form-model and hydrator packages instead of mass-assigning arbitrary request data to persistence objects." +msgstr "" + +#. type: Title ## +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "Active Record and persistence" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "There are two common Yii3 choices for code that used Yii 2.0 Active Record classes." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "The first path is architectural: move business logic to services and domain objects, then use repositories for persistence. This is recommended when the Yii 2.0 model contains validation, form scenarios, authorization checks, mailing, file uploads, and database access in the same class." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "The second path is incremental: represent the database model with [yiisoft/active-record](https://github.com/yiisoft/active-record). This is closer to Yii 2.0 and can be significantly faster when your Active Record classes mostly describe tables and relations." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Yii 2.0:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"final class Post extends \\yii\\db\\ActiveRecord\n" +"{\n" +" public static function tableName(): string\n" +" {\n" +" return '{{%post}}';\n" +" }\n" +"\n" +" public function rules(): array\n" +" {\n" +" return [\n" +" [['title', 'body'], 'required'],\n" +" ['title', 'string', 'max' => 255],\n" +" ];\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Yii3 Active Record:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"use Yiisoft\\ActiveRecord\\ActiveRecord;\n" +"\n" +"final class Post extends ActiveRecord\n" +"{\n" +" protected int $id;\n" +" protected string $title;\n" +" protected string $body;\n" +"\n" +" public function tableName(): string\n" +" {\n" +" return '{{%post}}';\n" +" }\n" +"\n" +" public function getId(): ?int\n" +" {\n" +" return $this->id ?? null;\n" +" }\n" +"\n" +" public function getTitle(): ?string\n" +" {\n" +" return $this->title ?? null;\n" +" }\n" +"\n" +" public function setTitle(string $title): void\n" +" {\n" +" $this->title = $title;\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Do not move Yii 2.0 `rules()` directly into the Active Record class. In Yii3, validation belongs to validator rules, form models, command objects, or services:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"use Yiisoft\\FormModel\\FormModel;\n" +"use Yiisoft\\Validator\\Rule\\Length;\n" +"use Yiisoft\\Validator\\Rule\\Required;\n" +"\n" +"final class PostInput extends FormModel\n" +"{\n" +" #[Required]\n" +" #[Length(max: 255)]\n" +" public ?string $title = null;\n" +"\n" +" #[Required]\n" +" public ?string $body = null;\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Then copy validated data into the record or pass it to an application service:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"$post = new Post();\n" +"$post->setTitle($input->title);\n" +"$post->save();\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "When deciding what to reuse, check each Active Record method:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "table mapping and relations can usually move to `yiisoft/active-record`;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "validation should move to `yiisoft/validator`;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "form labels and hints should move to `yiisoft/form-model`;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "search models should become query/data-reader services;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "business workflows should become services;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "events should use PSR-14 events or package-specific events;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "direct `Yii::$app->db` usage should become injected database dependencies." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Yii 2.0 migrations and Yii3 `yiisoft/db-migration` migrations are not compatible. Start a new migration history or create structure dumps for the current schema, then use Yii3 migrations for future schema changes." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Yii 2.0 `GridView` is commonly used with `ActiveDataProvider`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"use yii\\grid\\GridView;\n" +"\n" +"echo GridView::widget([\n" +" 'dataProvider' => $dataProvider,\n" +" 'filterModel' => $searchModel,\n" +" 'columns' => [\n" +" 'id',\n" +" 'title',\n" +" 'created_at:datetime',\n" +" ['class' => 'yii\\grid\\ActionColumn'],\n" +" ],\n" +"]);\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Yii3 uses [yiisoft/yii-dataview](https://github.com/yiisoft/yii-dataview). It renders data from a data reader and uses fluent widget configuration:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"use Yiisoft\\Data\\Reader\\ReadableDataInterface;\n" +"use Yiisoft\\Yii\\DataView\\Column\\DataColumn;\n" +"use Yiisoft\\Yii\\DataView\\GridView\\Column\\ActionColumn;\n" +"use Yiisoft\\Yii\\DataView\\GridView\\GridView;\n" +"\n" +"/**\n" +" * @var ReadableDataInterface $dataReader\n" +" */\n" +"\n" +"echo GridView::widget()\n" +" ->dataReader($dataReader)\n" +" ->columns(\n" +" new DataColumn('id'),\n" +" new DataColumn('title', header: 'Title'),\n" +" new DataColumn('created_at', header: 'Created'),\n" +" new ActionColumn(),\n" +" );\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "For sorting, pagination, filtering, and action URLs, wire the widget to Yii Router:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"use Yiisoft\\Yii\\DataView\\YiiRouter\\ActionColumnUrlConfig;\n" +"use Yiisoft\\Yii\\DataView\\YiiRouter\\ActionColumnUrlCreator;\n" +"use Yiisoft\\Yii\\DataView\\YiiRouter\\UrlCreator;\n" +"use Yiisoft\\Yii\\DataView\\YiiRouter\\UrlParameterProvider;\n" +"\n" +"echo GridView::widget()\n" +" ->dataReader($dataReader)\n" +" ->urlParameterProvider(new UrlParameterProvider($currentRoute))\n" +" ->urlCreator(new UrlCreator($urlGenerator))\n" +" ->columns(\n" +" new DataColumn('id'),\n" +" new DataColumn('title'),\n" +" new ActionColumn(\n" +" urlCreator: new ActionColumnUrlCreator($urlGenerator, $currentRoute),\n" +" urlConfig: new ActionColumnUrlConfig(baseRouteName: 'post'),\n" +" ),\n" +" );\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "A Yii 2.0 search model usually becomes a query service that:" +msgstr "" + +#. type: Bullet: '1. ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "reads filter and sort parameters from the request;" +msgstr "" + +#. type: Bullet: '2. ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "validates them with `yiisoft/validator`;" +msgstr "" + +#. type: Bullet: '3. ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "builds a database query or repository query;" +msgstr "" + +#. type: Bullet: '4. ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "exposes a data reader to GridView." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "See [Using htmx for partial reloads](../../cookbook/using-htmx-for-partial-reloads.md) for a complete Yii3 GridView workflow and [yii-dataview GridView docs](https://github.com/yiisoft/yii-dataview/blob/master/docs/en/guide/gridview.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "Filters, middleware, and access control" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Yii 2.0 controller filters and behaviors usually look like this:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"public function behaviors(): array\n" +"{\n" +" return [\n" +" 'access' => [\n" +" 'class' => \\yii\\filters\\AccessControl::class,\n" +" 'rules' => [\n" +" ['allow' => true, 'roles' => ['@']],\n" +" ],\n" +" ],\n" +" ];\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "In Yii3, request processing is middleware-based. Move cross-cutting concerns such as authentication, authorization, body parsing, locale negotiation, CSRF checks, and error handling to middleware or dedicated services. Keep actions focused on the request flow they implement." +msgstr "" + +#. type: Title ## +#: ../src/guide/intro/upgrade-from-v2.md +#: ../src/guide/structure/designing-packages.md +#, no-wrap +msgid "Console commands" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Yii 2.0 console commands extend `yii\\console\\Controller`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"final class ReportController extends \\yii\\console\\Controller\n" +"{\n" +" public function actionSend(): int\n" +" {\n" +" // ...\n" +" return self::EXIT_CODE_NORMAL;\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Yii3 console commands are services in `src/Console`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"namespace App\\Console;\n" +"\n" +"use Symfony\\Component\\Console\\Attribute\\AsCommand;\n" +"use Symfony\\Component\\Console\\Command\\Command;\n" +"use Symfony\\Component\\Console\\Input\\InputInterface;\n" +"use Symfony\\Component\\Console\\Output\\OutputInterface;\n" +"\n" +"#[AsCommand(name: 'report/send')]\n" +"final class SendReportCommand extends Command\n" +"{\n" +" protected function execute(InputInterface $input, OutputInterface $output): int\n" +" {\n" +" // ...\n" +" return Command::SUCCESS;\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Move command dependencies to constructor injection and register commands in console configuration." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Yii 2.0 REST controllers, serializers, and response formatters do not move directly to Yii3. Start from PSR-7 responses and explicit routing. Build one resource at a time:" +msgstr "" + +#. type: Bullet: '1. ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "define routes for collection and item operations;" +msgstr "" + +#. type: Bullet: '2. ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "inject request, persistence, serializer, and response factory dependencies;" +msgstr "" + +#. type: Bullet: '3. ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "validate input with `yiisoft/validator`;" +msgstr "" + +#. type: Bullet: '4. ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "return JSON responses through Yii3 response helpers or PSR-7 factories;" +msgstr "" + +#. type: Bullet: '5. ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "move authentication and rate limiting to middleware." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "See [Response](../runtime/response.md), [Authentication](../security/authentication.md), and [Authorization](../security/authorization.md)." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Do not postpone tests until the whole Yii3 application is done. For each new request flow, add:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "unit tests for services and validators;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "functional tests for actions and middleware;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "end-to-end tests for critical browser flows;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "static analysis for stricter type checks." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Yii3 code is more explicit, so tests should assert services directly instead of constructing large application component arrays." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "See [Testing overview](../testing/overview.md), [Unit tests](../testing/unit.md), [Functional tests](../testing/functional.md), and [End-to-end tests](../testing/end-to-end.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/intro/upgrade-from-v2.md +#, no-wrap +msgid "Refactoring Yii 2.0 code before reusing it" +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "These changes are useful even if the old application stays on Yii 2.0 for a while:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Replace `Yii::$app` access in domain code with constructor arguments." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Move queries out of controllers and views into repositories or query services." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Move business workflows out of Active Record classes." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Separate form models from persistence models." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Add return types and parameter types." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Replace route arrays scattered in views with named route constants or helper methods." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/intro/upgrade-from-v2.md +msgid "Add tests around each flow before rebuilding it in Yii3." +msgstr "" + +#. type: Plain text +#: ../src/guide/intro/upgrade-from-v2.md +msgid "The less framework state your Yii 2.0 code assumes, the easier it is to understand what should be reused and what should be redesigned for Yii3." +msgstr "" diff --git a/_translations/po/pt-BR/guide_intro_what-is-yii.md.po b/_translations/po/pt-BR/guide_intro_what-is-yii.md.po new file mode 100644 index 00000000..c299478e --- /dev/null +++ b/_translations/po/pt-BR/guide_intro_what-is-yii.md.po @@ -0,0 +1,153 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-01-08 08:54+0000\n" +"PO-Revision-Date: 2026-01-08 08:54+0000\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Plain text +#: ../src/cookbook/preface.md ../src/guide/intro/what-is-yii.md +msgid "Yii is a high-performance, package-based PHP framework for developing modern applications. The name Yii (pronounced `Yee` or `[ji:]`) means \"simple and evolutionary\" in Chinese. You can also think about it as an acronym for **Yes It Is**!" +msgstr "O Yii é um framework PHP de alto desempenho, baseado em pacotes, para desenvolver aplicações modernas. O nome Yii (pronuncia-se `Yee` ou `[ji:]`) significa \"simples e evolutivo\" em chinês. Você também pode pensar nele como um acrônimo de **Yes It Is**!" + +#. type: Plain text +#: ../src/cookbook/preface.md ../src/guide/intro/what-is-yii.md +msgid "Yii is a generic Web programming framework. You can use it for developing all kinds of Web applications using PHP. Because of its architecture and sophisticated caching support, it's especially suitable for developing large-scale applications such as portals, content management systems, e-commerce, REST APIs, etc." +msgstr "O Yii é um framework genérico de programação web. Você pode usá-lo para desenvolver todo tipo de aplicação web com PHP. Por causa da sua arquitetura e do suporte sofisticado a cache, ele é especialmente indicado para aplicações de grande porte, como portais, sistemas de gerenciamento de conteúdo, e-commerce, APIs REST etc." + +#. type: Title # +#: ../src/guide/intro/what-is-yii.md +#, no-wrap +msgid "What is Yii" +msgstr "O que é o Yii" + +#. type: Title ## +#: ../src/guide/intro/what-is-yii.md +#, no-wrap +msgid "What's Yii best for" +msgstr "Para que o Yii é mais indicado" + +#. type: Title ## +#: ../src/guide/intro/what-is-yii.md +#, no-wrap +msgid "How does Yii compare with other frameworks?" +msgstr "Como o Yii se compara a outros frameworks?" + +#. type: Plain text +#: ../src/guide/intro/what-is-yii.md +msgid "If you're already familiar with another framework, you may appreciate knowing how Yii compares:" +msgstr "Se você já conhece outro framework, talvez queira saber como o Yii se compara a ele:" + +#. type: Bullet: '- ' +#: ../src/guide/intro/what-is-yii.md +msgid "Yii takes the [philosophy of being practical and helpful](../../internals/001-yii-values.md) achieving:" +msgstr "O Yii segue a [filosofia de ser prático e útil](../../internals/001-yii-values.md), buscando:" + +#. type: Bullet: ' - ' +#: ../src/guide/intro/what-is-yii.md +msgid "Performance in both development and execution." +msgstr "Desempenho tanto no desenvolvimento quanto na execução." + +#. type: Bullet: ' - ' +#: ../src/guide/intro/what-is-yii.md +msgid "Convenient customizable defaults." +msgstr "Padrões convenientes e personalizáveis." + +#. type: Bullet: ' - ' +#: ../src/guide/intro/what-is-yii.md +msgid "Practice-orientation." +msgstr "Foco na prática." + +#. type: Bullet: ' - ' +#: ../src/guide/intro/what-is-yii.md +msgid "Simplicity." +msgstr "Simplicidade." + +#. type: Bullet: ' - ' +#: ../src/guide/intro/what-is-yii.md +msgid "Explicitness." +msgstr "Clareza." + +#. type: Bullet: ' - ' +#: ../src/guide/intro/what-is-yii.md +msgid "Consistency." +msgstr "Consistência." + +#. type: Plain text +#: ../src/guide/intro/what-is-yii.md +#, no-wrap +msgid "" +" Yii will never try to over-design things mainly to follow some design patterns.\n" +"- Yii extensively uses PSR interfaces with the ability to reuse what PHP community created and even\n" +" replace core implementations if needed.\n" +"- Yii is both a set of libraries and a full-stack framework providing many proven and ready-to-use features:\n" +" caching, logging, template engine, data abstraction, development tools, code generation, and more.\n" +"- Yii is extensible. You can customize or replace every piece of the core's code. You can also\n" +" take advantage of Yii's solid architecture to use or develop redistributable packages.\n" +"- High performance is always a primary goal of Yii.\n" +msgstr "" +" O Yii nunca tenta complicar o design só para seguir algum padrão de projeto.\n" +"- O Yii usa amplamente as interfaces PSR, o que permite reaproveitar o que a comunidade PHP criou e até\n" +" substituir implementações do core quando necessário.\n" +"- O Yii é ao mesmo tempo um conjunto de bibliotecas e um framework full-stack com muitos recursos testados e prontos para uso:\n" +" cache, logs, template engine, abstração de dados, ferramentas de desenvolvimento, geração de código e mais.\n" +"- O Yii é extensível. Você pode personalizar ou substituir qualquer parte do código do core. Também pode\n" +" aproveitar a arquitetura sólida do Yii para usar ou desenvolver pacotes redistribuíveis.\n" +"- Alto desempenho é sempre um objetivo principal do Yii.\n" + +#. type: Plain text +#: ../src/guide/intro/what-is-yii.md +msgid "Yii is backed up by a [strong core developer team](https://www.yiiframework.com/team/) financially backed from an [OpenCollective foundation](https://opencollective.com/yiisoft), as well as a large community of professionals constantly contributing to Yii's development. The Yii developer team keeps a close eye on the latest Web development trends and on the best practices and features found in other frameworks and projects. The most relevant best practices and features found elsewhere are incorporated into the core framework and exposed via simple and elegant interfaces." +msgstr "O Yii conta com um [time principal de desenvolvedores sólido](https://www.yiiframework.com/team/), apoiado financeiramente pela [fundação no OpenCollective](https://opencollective.com/yiisoft), e com uma grande comunidade de profissionais que contribuem constantemente para o desenvolvimento do Yii. O time do Yii acompanha de perto as tendências mais recentes do desenvolvimento web e as boas práticas e recursos de outros frameworks e projetos. As boas práticas e os recursos mais relevantes encontrados em outros lugares são incorporados ao core do framework e expostos por meio de interfaces simples e elegantes." + +#. type: Title ## +#: ../src/guide/intro/what-is-yii.md +#, no-wrap +msgid "Yii versions" +msgstr "Versões do Yii" + +#. type: Plain text +#: ../src/guide/intro/what-is-yii.md +msgid "Yii currently has three major versions available: 1.1, 2.0, and 3.0." +msgstr "Atualmente o Yii tem três versões principais disponíveis: 1.1, 2.0 e 3.0." + +#. type: Bullet: '- ' +#: ../src/guide/intro/what-is-yii.md +msgid "Version 1.1 is the old generation and is now in the feature freeze bugfix mode." +msgstr "A versão 1.1 é a geração antiga e está congelada, recebendo apenas correções de bugs." + +#. type: Bullet: '- ' +#: ../src/guide/intro/what-is-yii.md +msgid "Version 2.0 is a current stable version in the feature freeze bugfix mode." +msgstr "A versão 2.0 é a versão estável atual e está congelada, recebendo apenas correções de bugs." + +#. type: Bullet: '- ' +#: ../src/guide/intro/what-is-yii.md +msgid "Version 3.0 is the current version in development. This guide is mainly about version 3." +msgstr "A versão 3.0 é a versão atual em desenvolvimento. Este guia trata principalmente da versão 3." + +#. type: Title ## +#: ../src/guide/intro/what-is-yii.md +#, no-wrap +msgid "Requirements and prerequisites" +msgstr "Requisitos e pré-requisitos" + +#. type: Plain text +#: ../src/guide/intro/what-is-yii.md +msgid "Yii3 requires PHP 8.2 or above, but some packages work with older PHP, such as PHP 7.4." +msgstr "O Yii3 exige PHP 8.2 ou superior, mas alguns pacotes funcionam com versões mais antigas, como o PHP 7.4." + +#. type: Plain text +#: ../src/guide/intro/what-is-yii.md +msgid "Using Yii requires basic knowledge of object-oriented programming (OOP), as Yii is a pure OOP-based framework. Yii3 also makes use of the latest PHP features, such as type declarations and generators. Understanding these concepts will help you pick up Yii3 faster." +msgstr "Usar o Yii exige conhecimento básico de programação orientada a objetos (POO), já que o Yii é um framework totalmente orientado a objetos. O Yii3 também usa recursos recentes do PHP, como declarações de tipo e generators. Entender esses conceitos vai ajudar você a aprender o Yii3 mais rápido." diff --git a/_translations/po/pt-BR/guide_rest_quick-start.md.po b/_translations/po/pt-BR/guide_rest_quick-start.md.po new file mode 100644 index 00000000..2175f1c0 --- /dev/null +++ b/_translations/po/pt-BR/guide_rest_quick-start.md.po @@ -0,0 +1,500 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-05-29 09:35+0000\n" +"PO-Revision-Date: 2026-05-29 09:35+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/guide/rest/quick-start.md +#, no-wrap +msgid "Quick start" +msgstr "" + +#. type: Plain text +#: ../src/guide/rest/quick-start.md +msgid "Yii works with JSON APIs through the same PSR-7 request and response objects used by web pages. For API endpoints, the usual flow is:" +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/rest/quick-start.md +msgid "Parse the request body when the client sends JSON." +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/rest/quick-start.md +msgid "Map request data to a typed input object." +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/rest/quick-start.md +msgid "Validate the input object." +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/rest/quick-start.md +msgid "Return a response whose data is formatted as JSON." +msgstr "" + +#. type: Plain text +#: ../src/guide/rest/quick-start.md +msgid "This guide assumes that you use the [API application template](https://github.com/yiisoft/app-api). It already includes request body parsing, request input resolving, JSON data responses, and presenter examples. For complete applications with different structures, see [Demo applications](../start/demo-apps.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/rest/quick-start.md +#, no-wrap +msgid "Creating request input" +msgstr "" + +#. type: Plain text +#: ../src/guide/rest/quick-start.md +msgid "Use [yiisoft/input-http](https://github.com/yiisoft/input-http) to describe request data as a typed input object. Attach `#[FromBody]` when all values should come from the parsed request body." +msgstr "" + +#. type: Plain text +#: ../src/guide/rest/quick-start.md +msgid "Create `src/Api/Post/CreatePostInput.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/rest/quick-start.md +#, no-wrap +msgid "" +"getValidationResult();\n" +"\n" +" if (!$result->isValid()) {\n" +" return $responseFactory->failValidation($result);\n" +" }\n" +"\n" +" return $responseFactory\n" +" ->success([\n" +" 'title' => $input->title,\n" +" 'content' => $input->content,\n" +" ])\n" +" ->withStatus(Status::CREATED);\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/rest/quick-start.md +msgid "You can validate the input in the action as shown above. Alternatively, configure `RequestInputParametersResolver` to throw `Yiisoft\\Input\\Http\\InputValidationException` and convert that exception to a JSON response in one error handler. The API application template uses this centralized approach." +msgstr "" + +#. type: Title ## +#: ../src/guide/rest/quick-start.md +#, no-wrap +msgid "Returning JSON responses" +msgstr "" + +#. type: Plain text +#: ../src/guide/rest/quick-start.md +msgid "For small endpoints, you can write JSON to a PSR-7 response manually as shown in [Responding with JSON](../runtime/response.md#responding-with-json). For APIs, prefer [yiisoft/data-response](https://github.com/yiisoft/data-response), which formats response data and sets the `Content-Type` header." +msgstr "" + +#. type: Plain text +#: ../src/guide/rest/quick-start.md +msgid "The API application template keeps response formatting in `src/Api/Shared/ResponseFactory.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/rest/quick-start.md +#, no-wrap +msgid "" +"dataResponseFactory->createResponse([\n" +" 'status' => 'success',\n" +" 'data' => $presenter->present($data),\n" +" ]);\n" +" }\n" +"\n" +" public function failValidation(Result $result): ResponseInterface\n" +" {\n" +" return $this->dataResponseFactory\n" +" ->createResponse([\n" +" 'status' => 'failed',\n" +" 'error_message' => 'Validation failed.',\n" +" 'error_data' => (new ValidationResultPresenter())->present($result),\n" +" ])\n" +" ->withStatus(Status::UNPROCESSABLE_ENTITY);\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/rest/quick-start.md +msgid "Presenters are application-level abstractions that transform application objects to API output arrays. Keep them separate from domain entities so changing an API response doesn't force changes in business objects." +msgstr "" + +#. type: Plain text +#: ../src/guide/rest/quick-start.md +msgid "Create `src/Api/Post/PostPresenter.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/rest/quick-start.md +#, no-wrap +msgid "" +"\n" +" */\n" +"final readonly class PostPresenter implements PresenterInterface\n" +"{\n" +" public function present(mixed $value): array\n" +" {\n" +" return [\n" +" 'id' => $value->id,\n" +" 'title' => $value->title,\n" +" 'content' => $value->content,\n" +" ];\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/rest/quick-start.md +msgid "The API template contains a fuller implementation of [response factory](https://github.com/yiisoft/app-api/blob/master/src/Api/Shared/ResponseFactory.php) and [presenters](https://github.com/yiisoft/app-api/tree/master/src/Api/Shared/Presenter)." +msgstr "" + +#. type: Title ## +#: ../src/guide/rest/quick-start.md +#, no-wrap +msgid "Routing an endpoint" +msgstr "" + +#. type: Plain text +#: ../src/guide/rest/quick-start.md +msgid "Register API routes in `config/common/routes.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/rest/quick-start.md +#, no-wrap +msgid "" +"use App\\Api\\Post\\CreatePostAction;\n" +"use Yiisoft\\Http\\Method;\n" +"use Yiisoft\\Router\\Route;\n" +"\n" +"return [\n" +" Route::methods([Method::POST], '/posts')\n" +" ->action(CreatePostAction::class)\n" +" ->name('api/posts/create'),\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/rest/quick-start.md +msgid "Send JSON by setting `Content-Type: application/json`. Ask for JSON responses with `Accept: application/json`." +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/rest/quick-start.md +#, no-wrap +msgid "" +"curl -X POST http://localhost:8080/posts \\\n" +" -H 'Content-Type: application/json' \\\n" +" -H 'Accept: application/json' \\\n" +" -d '{\"title\":\"First post\",\"content\":\"Text\"}'\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/rest/quick-start.md +msgid "Validation errors are returned as JSON with HTTP status `422 Unprocessable Entity`. Successful creation usually returns `201 Created`." +msgstr "" + +#. type: Title ## +#: ../src/guide/rest/quick-start.md +#, no-wrap +msgid "Existing applications" +msgstr "" + +#. type: Plain text +#: ../src/guide/rest/quick-start.md +msgid "If you add JSON API endpoints to an existing web application, install the API packages first:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/rest/quick-start.md +#, no-wrap +msgid "composer require yiisoft/input-http yiisoft/request-body-parser yiisoft/data-response\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/rest/quick-start.md +msgid "If you use Docker:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/rest/quick-start.md +#, no-wrap +msgid "make composer require yiisoft/input-http yiisoft/request-body-parser yiisoft/data-response\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/rest/quick-start.md +msgid "In `config/web/di/application.php`, add `RequestBodyParser` before `Router` so JSON requests are parsed before actions run:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/rest/quick-start.md +#, no-wrap +msgid "" +"use Yiisoft\\Request\\Body\\RequestBodyParser;\n" +"use Yiisoft\\Router\\Middleware\\Router;\n" +"\n" +"return [\n" +" RequestBodyParser::class,\n" +" Router::class,\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/rest/quick-start.md +msgid "In the same file, add JSON data response middleware before error handling and routing:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/rest/quick-start.md +#, no-wrap +msgid "" +"use Yiisoft\\DataResponse\\Formatter\\JsonFormatter;\n" +"use Yiisoft\\DataResponse\\Middleware\\ContentNegotiatorDataResponseMiddleware;\n" +"\n" +"return [\n" +" static fn() => new ContentNegotiatorDataResponseMiddleware(\n" +" formatters: [\n" +" 'application/json' => new JsonFormatter(),\n" +" ],\n" +" fallback: new JsonFormatter(),\n" +" ),\n" +" // error handling, request body parser, router, and not-found middleware\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/rest/quick-start.md +msgid "Also in `config/web/di/application.php`, configure action parameter resolvers:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/rest/quick-start.md +#, no-wrap +msgid "" +"use Yiisoft\\Definitions\\Reference;\n" +"use Yiisoft\\Input\\Http\\HydratorAttributeParametersResolver;\n" +"use Yiisoft\\Input\\Http\\RequestInputParametersResolver;\n" +"use Yiisoft\\Middleware\\Dispatcher\\CompositeParametersResolver;\n" +"use Yiisoft\\Middleware\\Dispatcher\\ParametersResolverInterface;\n" +"\n" +"return [\n" +" ParametersResolverInterface::class => [\n" +" 'class' => CompositeParametersResolver::class,\n" +" '__construct()' => [\n" +" Reference::to(HydratorAttributeParametersResolver::class),\n" +" Reference::to(RequestInputParametersResolver::class),\n" +" ],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/rest/quick-start.md +msgid "Use the [API application template configuration](https://github.com/yiisoft/app-api/blob/master/config/web/di/application.php) as the complete reference for middleware order and resolver setup." +msgstr "" diff --git a/_translations/po/pt-BR/guide_runtime_cookies.md.po b/_translations/po/pt-BR/guide_runtime_cookies.md.po new file mode 100644 index 00000000..e72bb7a3 --- /dev/null +++ b/_translations/po/pt-BR/guide_runtime_cookies.md.po @@ -0,0 +1,311 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-04 11:19+0500\n" +"PO-Revision-Date: 2025-09-04 11:19+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: en/runtime/cookies.md +#, no-wrap +msgid "Cookies" +msgstr "" + +#. type: Plain text +#: en/runtime/cookies.md +msgid "Cookies are for persisting data between requests by sending it to the client browser using HTTP headers. The client sends data back to the server in request headers. Thus, cookies are handy to store small amounts of data, such as tokens or flags." +msgstr "" + +#. type: Title ## +#: en/runtime/cookies.md +#, no-wrap +msgid "Reading cookies" +msgstr "" + +#. type: Plain text +#: en/runtime/cookies.md +msgid "You could obtain Cookie values from server request that's available as route handler (such as controller action) argument:" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/cookies.md +#, no-wrap +msgid "" +"private function actionProfile(\\Psr\\Http\\Message\\ServerRequestInterface $request)\n" +"{\n" +" $cookieValues = $request->getCookieParams();\n" +" $cookieValue = $cookieValues['cookieName'] ?? null;\n" +" // ...\n" +"}\n" +msgstr "" + +#. type: Plain text +#: en/runtime/cookies.md +msgid "In addition to getting cookie values directly from the server request, you can also use the [yiisoft/request-provider](https://github.com/yiisoft/request-provider) package, which provides a more structured way to handle cookies through the `\\Yiisoft\\RequestProvider\\RequestCookieProvider`. This approach can simplify your code and improve readability." +msgstr "" + +#. type: Plain text +#: en/runtime/cookies.md +msgid "Here’s an example of how to work with cookies using the `\\Yiisoft\\RequestProvider\\RequestCookieProvider`:" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/cookies.md +#, no-wrap +msgid "" +"final readonly class MyService\n" +"{\n" +" public function __construct(\n" +" private \\Yiisoft\\RequestProvider\\RequestCookieProvider $cookies\n" +" ) {}\n" +"\n" +" public function go(): void\n" +" {\n" +" // Check if a specific cookie exists\n" +" if ($this->cookies->has('foo')) {\n" +" // Retrieve the value of the cookie\n" +" $fooValue = $this->cookies->get('foo');\n" +" // Do something with the cookie value\n" +" }\n" +"\n" +" // Retrieve another cookie value\n" +" $barValue = $this->cookies->get('bar');\n" +" // Do something with the bar cookie value\n" +" }\n" +"}\n" +"\n" +"## Sending cookies\n" +"\n" +"Since sending cookies is, in fact, sending a header but since forming the header isn't trivial, there is\n" +"`\\Yiisoft\\Cookies\\Cookie` class to help with it:\n" +"\n" +"```php\n" +"$cookie = (new \\Yiisoft\\Cookies\\Cookie('cookieName', 'value'))\n" +" ->withPath('/')\n" +" ->withDomain('yiiframework.com')\n" +" ->withHttpOnly(true)\n" +" ->withSecure(true)\n" +" ->withSameSite(\\Yiisoft\\Cookies\\Cookie::SAME_SITE_STRICT)\n" +" ->withMaxAge(new \\DateInterval('P7D'));\n" +"\n" +"return $cookie->addToResponse($response);\n" +msgstr "" + +#. type: Plain text +#: en/runtime/cookies.md +msgid "After forming a cookie call `addToResponse()` passing an instance of `\\Psr\\Http\\Message\\ResponseInterface` to add corresponding HTTP headers to it." +msgstr "" + +#. type: Title ## +#: en/runtime/cookies.md +#, no-wrap +msgid "Signing and encrypting cookies" +msgstr "" + +#. type: Plain text +#: en/runtime/cookies.md +msgid "To prevent the substitution of the cookie value, the package provides two implementations:" +msgstr "" + +#. type: Plain text +#: en/runtime/cookies.md +msgid "`Yiisoft\\Cookies\\CookieSigner` - signs each cookie with a unique prefix hash based on the value of the cookie and a secret key. `Yiisoft\\Cookies\\CookieEncryptor` - encrypts each cookie with a secret key." +msgstr "" + +#. type: Plain text +#: en/runtime/cookies.md +msgid "Encryption is more secure than signing but has lower performance." +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/cookies.md +#, no-wrap +msgid "" +"$cookie = new \\Yiisoft\\Cookies\\Cookie('identity', 'identityValue');\n" +"\n" +"// The secret key used to sign and validate cookies.\n" +"$key = '0my1xVkjCJnD_q1yr6lUxcAdpDlTMwiU';\n" +"\n" +"$signer = new \\Yiisoft\\Cookies\\CookieSigner($key);\n" +"$encryptor = new \\Yiisoft\\Cookies\\CookieEncryptor($key);\n" +"\n" +"$signedCookie = $signer->sign($cookie);\n" +"$encryptedCookie = $encryptor->encrypt($cookie);\n" +msgstr "" + +#. type: Plain text +#: en/runtime/cookies.md +msgid "To validate and get back the pure value, use the `validate()` and `decrypt()` method." +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/cookies.md +#, no-wrap +msgid "" +"$cookie = $signer->validate($signedCookie);\n" +"$cookie = $encryptor->decrypt($encryptedCookie);\n" +msgstr "" + +#. type: Plain text +#: en/runtime/cookies.md +msgid "If the cookie value is tampered with or hasn't been signed/encrypted before, a `\\RuntimeException` will be thrown. Therefore, if you aren't sure that the cookie value was signed/encrypted earlier, first use the `isSigned()` and `isEncrypted()` methods, respectively." +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/cookies.md +#, no-wrap +msgid "" +"if ($signer->isSigned($cookie)) {\n" +" $cookie = $signer->validate($cookie);\n" +"}\n" +"\n" +"if ($encryptor->isEncrypted($cookie)) {\n" +" $cookie = $encryptor->decrypt($cookie);\n" +"}\n" +msgstr "" + +#. type: Plain text +#: en/runtime/cookies.md +msgid "It makes sense to sign or encrypt the value of a cookie if you store important data that a user shouldn't change." +msgstr "" + +#. type: Title ### +#: en/runtime/cookies.md +#, no-wrap +msgid "Automating encryption and signing" +msgstr "" + +#. type: Plain text +#: en/runtime/cookies.md +msgid "To automate the encryption/signing and decryption/validation of cookie values, use an instance of `Yiisoft\\Cookies\\CookieMiddleware`, which is [PSR-15](https://www.php-fig.org/psr/psr-15/) middleware." +msgstr "" + +#. type: Plain text +#: en/runtime/cookies.md +msgid "This middleware provides the following features:" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/cookies.md +msgid "Validates and decrypts the cookie parameter values from the request." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/cookies.md +msgid "Excludes the cookie parameter from the request if it was tampered with and logs information about it." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/cookies.md +msgid "Encrypts/signs cookie values and replaces their clean values in the `Set-Cookie` headers in the response." +msgstr "" + +#. type: Plain text +#: en/runtime/cookies.md +msgid "In order for the middleware to know which values of which cookies need to be encrypted/signed, an array of settings must be passed to its constructor. The array keys are cookie name patterns and values are constant values of `CookieMiddleware::ENCRYPT` or `CookieMiddleware::SIGN`." +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/cookies.md +#, no-wrap +msgid "" +"use Yiisoft\\Cookies\\CookieMiddleware;\n" +"\n" +"$cookiesSettings = [\n" +" // Exact match with the name `identity`.\n" +" 'identity' => CookieMiddleware::ENCRYPT,\n" +" // Matches any number from 1 to 9 after the underscore.\n" +" 'name_[1-9]' => CookieMiddleware::SIGN,\n" +" // Matches any string after the prefix, including an\n" +" // empty string, except for the delimiters \"/\" and \"\\\".\n" +" 'prefix*' => CookieMiddleware::SIGN,\n" +"];\n" +msgstr "" + +#. type: Plain text +#: en/runtime/cookies.md +msgid "For more information on using the wildcard pattern, see the [yiisoft/strings](https://github.com/yiisoft/strings#wildcardpattern-usage) package." +msgstr "" + +#. type: Plain text +#: en/runtime/cookies.md +msgid "Creating and using middleware:" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/cookies.md +#, no-wrap +msgid "" +"/**\n" +" * @var \\Psr\\Http\\Message\\ServerRequestInterface $request\n" +" * @var \\Psr\\Http\\Server\\RequestHandlerInterface $handler\n" +" * @var \\Psr\\Log\\LoggerInterface $logger\n" +" */\n" +"\n" +"// The secret key used to sign and validate cookies.\n" +"$key = '0my1xVkjCJnD_q1yr6lUxcAdpDlTMwiU';\n" +"$signer = new \\Yiisoft\\Cookies\\CookieSigner($key);\n" +"$encryptor = new \\Yiisoft\\Cookies\\CookieEncryptor($key);\n" +"\n" +"$cookiesSettings = [\n" +" 'identity' => \\Yiisoft\\Cookies\\CookieMiddleware::ENCRYPT,\n" +" 'session' => \\Yiisoft\\Cookies\\CookieMiddleware::SIGN,\n" +"];\n" +"\n" +"$middleware = new \\Yiisoft\\Cookies\\CookieMiddleware(\n" +" $logger\n" +" $encryptor,\n" +" $signer,\n" +" $cookiesSettings,\n" +");\n" +"\n" +"// The cookie parameter values from the request are decrypted/validated.\n" +"// The cookie values are encrypted/signed and appended to the response.\n" +"$response = $middleware->process($request, $handler);\n" +msgstr "" + +#. type: Plain text +#: en/runtime/cookies.md +msgid "If the `$cookiesSettings` array is empty, no cookies will be encrypted and signed." +msgstr "" + +#. type: Title ## +#: en/runtime/cookies.md +#, no-wrap +msgid "Cookies security" +msgstr "" + +#. type: Plain text +#: en/runtime/cookies.md +msgid "You should configure each cookie to be secure. Important security settings are:" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/cookies.md +msgid "`httpOnly`. Setting it to `true` would prevent JavaScript to access cookie value." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/cookies.md +msgid "`secure`. Setting it to `true` would prevent sending cookie via `HTTP`. It will be sent via `HTTPS` only." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/cookies.md +msgid "`sameSite`, if set to either `SAME_SITE_LAX` or `SAME_SITE_STRICT` would prevent sending a cookie in cross-site browsing context. `SAME_SITE_LAX` would prevent cookie sending during CSRF-prone request methods (e.g., POST, PUT, PATCH, etc.). `SAME_SITE_STRICT` would prevent cookies sending for all methods." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/cookies.md +msgid "Sign or encrypt the value of the cookie to prevent spoofing of values if the data in the value shouldn't be tampered with." +msgstr "" diff --git a/_translations/po/pt-BR/guide_runtime_handling-errors.md.po b/_translations/po/pt-BR/guide_runtime_handling-errors.md.po new file mode 100644 index 00000000..565f9fdd --- /dev/null +++ b/_translations/po/pt-BR/guide_runtime_handling-errors.md.po @@ -0,0 +1,472 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-05-05 22:01+0000\n" +"PO-Revision-Date: 2026-05-05 22:01+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/guide/runtime/handling-errors.md +#, no-wrap +msgid "Handling errors" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/handling-errors.md +msgid "Yii has a [yiisoft/error-handler](https://github.com/yiisoft/error-handler) package that makes error handling a much more pleasant experience than before. In particular, the Yii error handler provides the following:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/handling-errors.md +msgid "[PSR-15](https://www.php-fig.org/psr/psr-15/) middleware for catching unhandled errors." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/handling-errors.md +msgid "PSR-15 middleware for mapping certain exceptions to custom responses." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/handling-errors.md +msgid "Production and debug modes." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/handling-errors.md +msgid "Debug mode displays details, stacktrace, has dark and light themes and handy buttons to search for error without typing." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/handling-errors.md +msgid "Takes PHP settings into account." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/handling-errors.md +msgid "Handles out of memory errors, fatal errors, warnings, notices, and exceptions." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/handling-errors.md +msgid "Can use any [PSR-3](https://www.php-fig.org/psr/psr-3/) compatible logger for error logging." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/handling-errors.md +msgid "Detects a response format based on a mime type of the request." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/handling-errors.md +msgid "Supports responding with HTML, plain text, JSON, XML, and headers out of the box." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/handling-errors.md +msgid "You can implement your own error rendering for extra types." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/handling-errors.md +msgid "This guide describes how to use the error handler in the [Yii framework](https://www.yiiframework.com/), for information about using it separate from Yii, see the [package description](https://github.com/yiisoft/error-handler)." +msgstr "" + +#. type: Title ## +#: ../src/guide/runtime/handling-errors.md +#, no-wrap +msgid "Using error handler" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/handling-errors.md +msgid "The error handler consists of two parts. One part is `Yiisoft\\ErrorHandler\\Middleware\\ErrorCatcher` middleware that, when registered, catches exceptions that may appear during middleware stack execution and passes them to the handler. Another part is the error handler itself, `Yiisoft\\ErrorHandler\\ErrorHandler`, that's catching exceptions occurring outside the middleware stack and fatal errors. The handler also converts warnings and notices to exceptions and does more handy things." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/handling-errors.md +msgid "Error handler is registered in the application itself. Usually it happens in `ApplicationRunner`. By default, the handler configuration comes from the container. You may configure it in the application configuration, `config/web.php` like the following:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/handling-errors.md +#, no-wrap +msgid "" +"use Psr\\Log\\LoggerInterface;\n" +"use Yiisoft\\ErrorHandler\\ErrorHandler;\n" +"use Yiisoft\\ErrorHandler\\Renderer\\HtmlRenderer;\n" +"use Yiisoft\\ErrorHandler\\ThrowableRendererInterface;\n" +"\n" +"return [\n" +" // ...\n" +" ErrorHandler::class => static function (LoggerInterface $logger, ThrowableRendererInterface $renderer) {\n" +" $errorHandler = new ErrorHandler($logger, $renderer);\n" +" // Set the size of the reserved memory to 512 KB. Defaults to 256KB.\n" +" $errorHandler->memoryReserveSize(524_288);\n" +" return $errorHandler;\n" +" },\n" +" \n" +" ThrowableRendererInterface::class => static fn () => new HtmlRenderer([\n" +" // Defaults to the package file \"templates/production.php\".\n" +" 'template' => '/full/path/to/production/template/file',\n" +" // Defaults to package file \"templates/development.php\".\n" +" 'verboseTemplate' => '/full/path/to/development/template/file',\n" +" // Maximum number of source code lines to be displayed. Defaults to 19.\n" +" 'maxSourceLines' => 20,\n" +" // Maximum number of trace source code lines to be displayed. Defaults to 13.\n" +" 'maxTraceLines' => 5,\n" +" // Trace the header line with placeholders (file, line, icon) to be substituted. Defaults to `null`.\n" +" 'traceHeaderLine' => '{icon}',\n" +" ]),\n" +" // ...\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/handling-errors.md +msgid "As aforementioned, the error handler turns all non-fatal PHP errors into catchable exceptions (`Yiisoft\\ErrorHandler\\Exception\\ErrorException`). This means you can use the following code to deal with PHP errors:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/handling-errors.md +#, no-wrap +msgid "" +"try {\n" +" 10 / 0;\n" +"} catch (\\Yiisoft\\ErrorHandler\\Exception\\ErrorException $e) {\n" +" // Write a log or something else.\n" +"}\n" +"// execution continues...\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/handling-errors.md +msgid "The package has another middleware, `Yiisoft\\ErrorHandler\\Middleware\\ExceptionResponder`. This middleware maps certain exceptions to custom responses. Configure it in the application configuration as follows:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/handling-errors.md +#, no-wrap +msgid "" +"use Psr\\Http\\Message\\ResponseFactoryInterface;\n" +"use Yiisoft\\ErrorHandler\\Middleware\\ExceptionResponder;\n" +"use Yiisoft\\Injector\\Injector;\n" +"\n" +"return [\n" +" // ...\n" +" ExceptionResponder::class => static function (ResponseFactoryInterface $responseFactory, Injector $injector) {\n" +" $exceptionMap = [\n" +" // Status code with which the factory creates the response.\n" +" MyNotFoundException::class => 404,\n" +" // PHP callable that must return a `Psr\\Http\\Message\\ResponseInterface`.\n" +" MyHttpException::class => static fn (MyHttpException $exception) => new MyResponse($exception),\n" +" // ...\n" +" ];\n" +" \n" +" return new ExceptionResponder($exceptionMap, $responseFactory, $injector);\n" +" },\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/handling-errors.md +msgid "Note that when configuring application middleware stack, you must place `Yiisoft\\ErrorHandler\\Middleware\\ExceptionResponder` before `Yiisoft\\ErrorHandler\\Middleware\\ErrorCatcher`." +msgstr "" + +#. type: Title ## +#: ../src/guide/runtime/handling-errors.md +#, no-wrap +msgid "Rendering error data" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/handling-errors.md +msgid "One of the renderers could render error data into a certain format. The following renderers are available out of the box:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/handling-errors.md +msgid "`Yiisoft\\ErrorHandler\\Renderer\\HeaderRenderer` - Renders error into HTTP headers. It's used for `HEAD` request." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/handling-errors.md +msgid "`Yiisoft\\ErrorHandler\\Renderer\\HtmlRenderer` - Renders error into HTML." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/handling-errors.md +msgid "`Yiisoft\\ErrorHandler\\Renderer\\JsonRenderer` - Renders error into JSON." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/handling-errors.md +msgid "`Yiisoft\\ErrorHandler\\Renderer\\PlainTextRenderer` - Renders error into plain text." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/handling-errors.md +msgid "`Yiisoft\\ErrorHandler\\Renderer\\XmlRenderer` - Renders error into XML." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/handling-errors.md +msgid "The renderer produces detailed error data depending on whether debug mode is enabled or disabled." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/handling-errors.md +msgid "An Example of header rendering with a debugging mode turned off:" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/runtime/handling-errors.md +#, no-wrap +msgid "" +"...\n" +"X-Error-Message: An internal server error occurred.\n" +"...\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/handling-errors.md +msgid "An Example of header rendering with a debugging mode turned on:" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/runtime/handling-errors.md +#, no-wrap +msgid "" +"...\n" +"X-Error-Type: Error\n" +"X-Error-Message: Call to undefined function App\\Controller\\myFunc()\n" +"X-Error-Code: 0\n" +"X-Error-File: /var/www/yii/app/src/Controller/SiteController.php\n" +"X-Error-Line: 21\n" +"...\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/handling-errors.md +msgid "Example of JSON rendering output with a debugging mode turned off:" +msgstr "" + +#. type: Fenced code block (json) +#: ../src/guide/runtime/handling-errors.md +#, no-wrap +msgid "{\"message\":\"An internal server error occurred.\"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/handling-errors.md +msgid "An Example of JSON rendering output with debugging mode turned on:" +msgstr "" + +#. type: Fenced code block (json) +#: ../src/guide/runtime/handling-errors.md +#, no-wrap +msgid "" +"{\n" +" \"type\": \"Error\",\n" +" \"message\": \"Call to undefined function App\\\\Controller\\\\myFunc()\",\n" +" \"code\": 0,\n" +" \"file\": \"/var/www/yii/app/src/Controller/SiteController.php\",\n" +" \"line\": 21,\n" +" \"trace\": [\n" +" {\n" +" \"function\": \"index\",\n" +" \"class\": \"App\\\\Controller\\\\SiteController\",\n" +" \"type\": \"->\"\n" +" },\n" +" {\n" +" \"file\": \"/var/www/yii/app/vendor/yiisoft/injector/src/Injector.php\",\n" +" \"line\": 63,\n" +" \"function\": \"invokeArgs\",\n" +" \"class\": \"ReflectionFunction\",\n" +" \"type\": \"->\"\n" +" },\n" +" ...\n" +" ]\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/handling-errors.md +msgid "Example of HTML rendering with debugging mode turned off:" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/handling-errors.md +msgid "![View production](/images/guide/runtime/view-production.png)" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/handling-errors.md +msgid "Example of HTML rendering with debugging mode on and a light theme:" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/handling-errors.md +msgid "![View development with light theme](/images/guide/runtime/view-development-light.png)" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/handling-errors.md +msgid "Example of HTML rendering with debugging mode on and a dark theme:" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/handling-errors.md +msgid "![View development with dark theme](/images/guide/runtime/view-development-dark.png)" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/handling-errors.md +msgid "The error catcher chooses how to render an exception based on `accept` HTTP header. If it's `text/html` or any unknown content type, it will use the error or exception HTML template to display errors. For other mime types, the error handler will choose different renderers registered in a renderer provider. By default, it supports JSON, XML, and plain text." +msgstr "" + +#. type: Title ### +#: ../src/guide/runtime/handling-errors.md +#, no-wrap +msgid "Implementing your own renderer" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/handling-errors.md +msgid "You may customize the error response format by implementing `Yiisoft\\ErrorHandler\\ThrowableRendererInterface`. The renderer converts a throwable into `Yiisoft\\ErrorHandler\\ErrorData`, which contains the response body and headers." +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/handling-errors.md +#, no-wrap +msgid "" +"use Psr\\Http\\Message\\ServerRequestInterface;\n" +"use Throwable;\n" +"use Yiisoft\\ErrorHandler\\ErrorData;\n" +"use Yiisoft\\ErrorHandler\\ThrowableRendererInterface;\n" +"use Yiisoft\\Http\\Header;\n" +"\n" +"final readonly class MyRenderer implements ThrowableRendererInterface\n" +"{\n" +" public function render(Throwable $t, ?ServerRequestInterface $request = null): ErrorData\n" +" {\n" +" return new ErrorData(\n" +" '{\"message\":\"An internal server error occurred.\"}',\n" +" [Header::CONTENT_TYPE => 'application/problem+json'],\n" +" );\n" +" }\n" +"\n" +" public function renderVerbose(Throwable $t, ?ServerRequestInterface $request = null): ErrorData\n" +" {\n" +" return new ErrorData(\n" +" json_encode(\n" +" [\n" +" 'type' => $t::class,\n" +" 'message' => $t->getMessage(),\n" +" 'file' => $t->getFile(),\n" +" 'line' => $t->getLine(),\n" +" ],\n" +" JSON_THROW_ON_ERROR | JSON_UNESCAPED_SLASHES,\n" +" ),\n" +" [Header::CONTENT_TYPE => 'application/problem+json'],\n" +" );\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/handling-errors.md +msgid "Register the renderer in `config/common/di/error-handler.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/handling-errors.md +#, no-wrap +msgid "" +"use Psr\\Container\\ContainerInterface;\n" +"use App\\Error\\MyRenderer;\n" +"use Yiisoft\\Definitions\\DynamicReference;\n" +"use Yiisoft\\ErrorHandler\\Renderer\\HtmlRenderer;\n" +"use Yiisoft\\ErrorHandler\\Renderer\\JsonRenderer;\n" +"use Yiisoft\\ErrorHandler\\Renderer\\PlainTextRenderer;\n" +"use Yiisoft\\ErrorHandler\\Renderer\\XmlRenderer;\n" +"use Yiisoft\\ErrorHandler\\RendererProvider\\CompositeRendererProvider;\n" +"use Yiisoft\\ErrorHandler\\RendererProvider\\ContentTypeRendererProvider;\n" +"use Yiisoft\\ErrorHandler\\RendererProvider\\HeadRendererProvider;\n" +"use Yiisoft\\ErrorHandler\\ThrowableResponseFactory;\n" +"use Yiisoft\\ErrorHandler\\ThrowableResponseFactoryInterface;\n" +"\n" +"return [\n" +" ThrowableResponseFactoryInterface::class => [\n" +" 'class' => ThrowableResponseFactory::class,\n" +" '__construct()' => [\n" +" 'rendererProvider' => DynamicReference::to(\n" +" static fn (ContainerInterface $container) => new CompositeRendererProvider(\n" +" new HeadRendererProvider(),\n" +" new ContentTypeRendererProvider($container, [\n" +" 'application/problem+json' => MyRenderer::class,\n" +" 'application/json' => JsonRenderer::class,\n" +" 'application/xml' => XmlRenderer::class,\n" +" 'text/xml' => XmlRenderer::class,\n" +" 'text/plain' => PlainTextRenderer::class,\n" +" 'text/html' => HtmlRenderer::class,\n" +" '*/*' => HtmlRenderer::class,\n" +" ]),\n" +" ),\n" +" ),\n" +" ],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/handling-errors.md +msgid "The `renderers` array maps `Accept` header content types to renderer class names. When you provide this array, it replaces the default map, so include the default renderer classes you still need." +msgstr "" + +#. type: Title ## +#: ../src/guide/runtime/handling-errors.md +#, no-wrap +msgid "Friendly exceptions" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/handling-errors.md +msgid "Yii error renderer supports [friendly exceptions](https://github.com/yiisoft/friendly-exception) that make error handling an even more pleasant experience for your team. The idea is to offer a readable name and possible solutions to the problem:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/handling-errors.md +#, no-wrap +msgid "" +"use Yiisoft\\FriendlyException\\FriendlyExceptionInterface;\n" +"\n" +"final readonly class RequestTimeoutException extends \\RuntimeException implements FriendlyExceptionInterface\n" +"{\n" +" public function getName(): string\n" +" {\n" +" return 'Request timed out';\n" +" }\n" +" \n" +" public function getSolution(): ?string\n" +" {\n" +" return <<<'SOLUTION'\n" +"Likely it is a result of resource request is not responding in a timely fashion. Try increasing timeout.\n" +"SOLUTION;\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/handling-errors.md +msgid "When the application throws such an exception, the error renderer would display the name and the solution if the debug mode is on." +msgstr "" diff --git a/_translations/po/pt-BR/guide_runtime_logging.md.po b/_translations/po/pt-BR/guide_runtime_logging.md.po new file mode 100644 index 00000000..55153f4d --- /dev/null +++ b/_translations/po/pt-BR/guide_runtime_logging.md.po @@ -0,0 +1,743 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-10-15 10:10+0000\n" +"PO-Revision-Date: 2026-10-15 10:10+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "Logging" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "Yii relies on [PSR-3 interfaces](https://www.php-fig.org/psr/psr-3/) for logging, so you could configure any PSR-3 compatible logging library to do the actual job." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "Yii provides its own logger that's highly customizable and extensible. Using it, you can log various types of messages, filter them, and gather them at different targets, such as files or emails." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "Using the Yii logging framework involves the following steps:" +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/runtime/logging.md +msgid "Record [log messages](#log-messages) at various places in your code;" +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/runtime/logging.md +msgid "Configure [log targets](#log-targets) in the application configuration to filter and export log messages;" +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/runtime/logging.md +msgid "Examine the filtered logged messages exported by different targets (e.g. the Yii debugger)." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "In this section, the focus in on the first two steps." +msgstr "" + +#. type: Title ## +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "Default log destination" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "Yii3 application templates ([web](https://github.com/yiisoft/app/blob/master/config/common/di/logger.php) and [API](https://github.com/yiisoft/app-api/blob/master/config/common/di/logger.php)) configure `Yiisoft\\Log\\StreamTarget`, which writes to standard output (`stdout`, or `php://stdout`) by default. They don't create application log files, such as `runtime/logs/app.log`. `StreamTarget` also supports standard error (`stderr`, or `php://stderr`), but you must configure it explicitly." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "" +"This works well with Docker, which [collects container output](https://docs.docker.com/engine/logging/).\n" +"Use `docker logs ` to read it when the container's logging driver supports that command.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "Without containers, the destination depends on how you start PHP and capture its output. For example, PHP-FPM discards worker output by default unless you enable `catch_workers_output`. See [web server logging configuration](../../cookbook/configuring-webservers/general.md#application-logs). To have Yii write application log files directly, configure a [file target](#logging-to-files)." +msgstr "" + +#. type: Title ## +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "Log Messages" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "To record log messages, you need an instance of PSR-3 logger. A class that writes log messages should receive it as a dependency:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "" +"class MyService\n" +"{\n" +" private $logger;\n" +" \n" +" public function __construct(\\Psr\\Log\\LoggerInterface $logger)\n" +" {\n" +" $this->logger = $logger; \n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "Recording a log message is as simple as calling one of the following logging methods that correspond to log levels:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/logging.md +msgid "`emergency` - System is unusable." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/logging.md +msgid "`alert` - Action must be taken immediately. Example: Entire website down, database unavailable, etc. This should trigger the SMS alerts and wake you up." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/logging.md +msgid "`critical` - Critical conditions. Example: Application component unavailable, unexpected exception." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/logging.md +msgid "`error` - Runtime errors that don't require immediate action but should typically be logged and monitored." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/logging.md +msgid "`warning` - Exceptional occurrences that aren't errors. Example: Use of deprecated APIs, poor use of an API, undesirable things that aren't necessarily wrong." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/logging.md +msgid "`notice` - Normal but significant events." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/logging.md +msgid "`info` - Interesting events. Example: User logs in, SQL logs." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/logging.md +msgid "`debug` - Detailed debug information." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "Each method has two arguments. The first is a message. The Second is a context array that typically has structured data that doesn't fit a message well but still does offer important information. In case you provide an exception as context, you should pass the \"exception\" key. Another special key is \"category.\" Categories are handy to better organize and filter log messages." +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "" +"use \\Psr\\Log\\LoggerInterface;\n" +"\n" +"final readonly class MyService\n" +"{\n" +" public function __construct(\n" +" private LoggerInterface $logger\n" +" )\n" +" { \n" +" }\n" +"\n" +" public function serve(): void\n" +" {\n" +" $this->logger->info('MyService is serving', ['context' => __METHOD__]); \n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "When deciding on a category for a message, you may choose a hierarchical naming scheme, which will make it easier for [log targets](#log-targets) to filter messages based on their categories. A simple yet effective naming scheme is to use the PHP magic constant `__METHOD__` for the category names. This is also the approach used in the core Yii framework code." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "The `__METHOD__` constant evaluates as the name of the method (prefixed with the fully qualified class name) where the constant appears. For example, it's equal to the string `'App\\\\Service\\\\MyService::serve'` if the above line of code is called within this method." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "" +"> [!IMPORTANT]\n" +"> The logging methods described above are actually shortcuts to the [[\\Psr\\Log\\LoggerInterface::log()]].\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "Note that PSR-3 package provides `\\Psr\\Log\\NullLogger` class that provides the same set of methods but doesn't log anything. That means that you don't have to check if logger is configured with `if ($logger !== null)` and, instead, can assume that logger is always present." +msgstr "" + +#. type: Title ## +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "Log targets" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "A log target is an instance of a class that extends the [[\\Yiisoft\\Log\\Target]]. It filters the log messages by their severity levels and categories and then exports them to some medium. For example, a [[\\Yiisoft\\Log\\Target\\File\\FileTarget|file target]]exports the filtered log messages to a file, while a [[Yiisoft\\Log\\Target\\Email\\EmailTarget|email target]] exports the log messages to specified email addresses." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "You can register many log targets in an application by configuring them through the `\\Yiisoft\\Log\\Logger` constructor:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "" +"use \\Psr\\Log\\LogLevel;\n" +"\n" +"$fileTarget = new \\Yiisoft\\Log\\Target\\File\\FileTarget('/path/to/app.log');\n" +"$fileTarget->setLevels([LogLevel::ERROR, LogLevel::WARNING]);\n" +"\n" +"$emailTarget = new \\Yiisoft\\Log\\Target\\Email\\EmailTarget($mailer, ['to' => 'log@example.com']);\n" +"$emailTarget->setLevels([LogLevel::EMERGENCY, LogLevel::ALERT, LogLevel::CRITICAL]);\n" +"$emailTarget->setCategories(['Yiisoft\\Cache\\*']); \n" +"\n" +"$logger = new \\Yiisoft\\Log\\Logger([\n" +" $fileTarget,\n" +" $emailTarget\n" +"]);\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "In the above code, two log targets are registered:" +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/runtime/logging.md +msgid "the first target selects error and warning messages and writes them to `/path/to/app.log` file;" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "" +"* the second target selects emergency, alert, and critical messages under the categories whose names start with\n" +"`Yiisoft\\Cache\\`, and sends them in an email to both `admin@example.com` and `developer@example.com`.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "Yii comes with the following built-in log targets. Please refer to the API documentation about these classes to learn how to configure and use them." +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/runtime/logging.md +msgid "[[\\Yiisoft\\Log\\PsrTarget]]: passes log messages to another PSR-3 compatible logger." +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/runtime/logging.md +msgid "[[\\Yiisoft\\Log\\StreamTarget]]: writes log messages into a specified output stream." +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/runtime/logging.md +msgid "[[\\Yiisoft\\Log\\Target\\Db\\DbTarget]]: saves log messages in database." +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/runtime/logging.md +msgid "[[\\Yiisoft\\Log\\Target\\Email\\EmailTarget]]: sends log messages to pre-specified email addresses." +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/runtime/logging.md +msgid "[[\\Yiisoft\\Log\\Target\\File\\FileTarget]]: saves log messages in files." +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/runtime/logging.md +msgid "[[\\Yiisoft\\Log\\Target\\Syslog\\SyslogTarget]]: saves log messages to syslog by calling the PHP function `syslog()`." +msgstr "" + +#. type: Title ### +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "Logging to files" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "To write application logs to a file, install the file target package:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "composer require yiisoft/log-target-file\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "In your application's `config/common/di/logger.php`, replace the `StreamTarget` reference with `FileTarget`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "" +"use Psr\\Log\\LoggerInterface;\n" +"use Yiisoft\\Definitions\\ReferencesArray;\n" +"use Yiisoft\\Log\\Logger;\n" +"use Yiisoft\\Log\\Target\\File\\FileTarget;\n" +"\n" +"return [\n" +" LoggerInterface::class => [\n" +" 'class' => Logger::class,\n" +" '__construct()' => [\n" +" 'targets' => ReferencesArray::from([\n" +" FileTarget::class,\n" +" ]),\n" +" ],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "The package's default configuration writes to `@runtime/logs/app.log` and enables log rotation. To change the path, set `$params['yiisoft/log-target-file']['fileTarget']['file']` in `config/common/params.php`. Ensure that the PHP process can write to the log directory, and keep it outside the web server's document root." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "The file target package's default configuration also filters out `alert`, `critical`, and `notice` messages. The templates' `StreamTarget` accepts all eight log levels. To keep that behavior, add the following entry to the array that `config/common/params.php` returns:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "" +"use Psr\\Log\\LogLevel;\n" +"\n" +"return [\n" +" // Other application parameters...\n" +" 'yiisoft/log-target-file' => [\n" +" 'fileTarget' => [\n" +" 'levels' => [\n" +" LogLevel::EMERGENCY,\n" +" LogLevel::ALERT,\n" +" LogLevel::CRITICAL,\n" +" LogLevel::ERROR,\n" +" LogLevel::WARNING,\n" +" LogLevel::NOTICE,\n" +" LogLevel::INFO,\n" +" LogLevel::DEBUG,\n" +" ],\n" +" ],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "In the following, we will describe the features common to all log targets." +msgstr "" + +#. type: Title ### +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "Message Filtering" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "For each log target, you can configure its levels and categories to specify which severity levels and categories of the messages the target should process." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "The target `setLevels()` method takes an array consisting of one or several of `\\Psr\\Log\\LogLevel` constants." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "By default, the target will process messages of *any* severity level." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "The target `setCategories()` method takes an array consisting of message category names or patterns. A target will only process messages whose category can be found or match one of the patterns in this array. A category pattern is a category name prefix with an asterisk `*` at its end. A category name matches a category pattern if it starts with the same prefix of the pattern. For example, `Yiisoft\\Cache\\Cache::set` and `Yiisoft\\Cache\\Cache::get` both match the pattern `Yiisoft\\Cache\\*`." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "By default, the target will process messages of *any* category." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "Besides allowing the categories by the `setCategories()` method, you may also deny certain categories by the `setExcept()` method. If the category of a message is found or matches one of the patterns in this property, the target will NOT process it." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "The following target configuration specifies that the target should only process error and warning messages under the categories whose names match either `Yiisoft\\Cache\\*` or `App\\Exceptions\\HttpException:*`, but not `App\\Exceptions\\HttpException:404`." +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "" +"$fileTarget = new \\Yiisoft\\Log\\Target\\File\\FileTarget('/path/to/app.log');\n" +"$fileTarget->setLevels([LogLevel::ERROR, LogLevel::WARNING]);\n" +"$fileTarget->setCategories(['Yiisoft\\Cache\\*', 'App\\Exceptions\\HttpException:*']);\n" +"$fileTarget->setExcept(['App\\Exceptions\\HttpException:404']);\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "Message Formatting" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "Log targets export the filtered log messages in a certain format. For example, if you install a log target of the class [[\\Yiisoft\\Log\\Target\\File\\FileTarget]], you may find a log message similar to the following in the log file:" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "" +"2020-12-05 09:27:52.223800 [info][application] Some message\n" +"\n" +"Message context:\n" +"\n" +"time: 1607160472.2238\n" +"memory: 4398536\n" +"category: 'application'\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "By default, log messages have the following format:" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "Timestamp Prefix[Level][Category] Message Context\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "You may customize this format by calling [[\\Yiisoft\\Log\\Target::setFormat()|setFormat()]] method, which takes a PHP callable returning a custom-formatted message." +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "" +"$fileTarget = new \\Yiisoft\\Log\\Target\\File\\FileTarget('/path/to/app.log');\n" +"\n" +"$fileTarget->setFormat(static function (\\Yiisoft\\Log\\Message $message) {\n" +" $category = strtoupper($message->context('category'));\n" +" return \"({$category}) [{$message->level()}] {$message->message()}\";\n" +"});\n" +"\n" +"$logger = new \\Yiisoft\\Log\\Logger([$fileTarget]);\n" +"$logger->info('Text message', ['category' => 'app']);\n" +"\n" +"// Result:\n" +"// (APP) [info] Text message\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "In addition, if you're comfortable with the default message format but need to change the timestamp format or add custom data to the message, you can call the [[\\Yiisoft\\Log\\Target::setTimestampFormat()|setTimestampFormat()]] and [[\\Yiisoft\\Log\\Target::setPrefix()|setPrefix()]] methods. For example, the following code changes the timestamp format and configures a log target to prefix each log message with the current user ID (IP address and Session ID are removed for privacy reasons)." +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "" +"$fileTarget = new \\Yiisoft\\Log\\Target\\File\\FileTarget('/path/to/app.log');\n" +"$userId = '123e4567-e89b-12d3-a456-426655440000';\n" +"\n" +"// Default: 'Y-m-d H: i: s.u'\n" +"$fileTarget->setTimestampFormat('D d F Y');\n" +"// Default: ''\n" +"$fileTarget->setPrefix(static fn () => \"[{$userId}]\");\n" +"\n" +"$logger = new \\Yiisoft\\Log\\Logger([$fileTarget]);\n" +"$logger->info('Text', ['category' => 'user']);\n" +"\n" +"// Result:\n" +"// Fri 04 December 2020 [123e4567-e89b-12d3-a456-426655440000][info][user] Text\n" +"// Message context: ...\n" +"// Common context: ...\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "The PHP callable that's passed to the [[\\Yiisoft\\Log\\Target::setFormat()|setFormat()]] and [[\\Yiisoft\\Log\\Target::setPrefix()|setPrefix()]] methods has the following signature:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "function (\\Yiisoft\\Log\\Message $message, array $commonContext): string;\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "" +"Besides message prefixes, log targets also append some common context information to each of the log messages.\n" +"You may adjust this behavior by calling target [[\\Yiisoft\\Log\\Target::setCommonContext()|setCommonContext()]]\n" +"method, passing an array of data in the `key => value` format that you want to include.\n" +"For example, the following log target configuration specifies that only the\n" +"value of the `$_SERVER` variable will be appended to the log messages.\n" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "" +"$fileTarget = new \\Yiisoft\\Log\\Target\\File\\FileTarget('/path/to/app.log');\n" +"$fileTarget->setCommonContext(['server' => $_SERVER]);\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "Message Trace Level" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "During development, it's often desirable to see where each log message is coming from. You can achieve this by calling the [[\\Yiisoft\\Log\\Logger::setTraceLevel()|setTraceLevel()]] method like the following:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "" +"$logger = new \\Yiisoft\\Log\\Logger($targets);\n" +"$logger->setTraceLevel(3);\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "This application configuration sets the trace level to be 3, so each log message will be appended with at most three levels of the call stack at which the log message is recorded. You can also set a list of paths to exclude from the trace by calling the [[\\Yiisoft\\Log\\Logger::setExcludedTracePaths()|setExcludedTracePaths()]] method." +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "" +"$logger = new \\Yiisoft\\Log\\Logger($targets);\n" +"$logger->setExcludedTracePaths(['/path/to/file', '/path/to/folder']);\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "" +"> [!IMPORTANT]\n" +"> Getting call stack information isn't trivial. Therefore, you should only use this feature during development\n" +"or when debugging an application.\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "Message flushing and exporting" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "As aforementioned, log messages are maintained in an array by [[\\Yiisoft\\Log\\Logger|logger object]]. To limit the memory consumption by this array, the logger will flush the recorded messages to the [log targets](#log-targets) each time the array accumulates a certain number of log messages. You can customize this number by calling the [[\\Yiisoft\\Log\\Logger::setFlushInterval()]] method:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "" +"$logger = new \\Yiisoft\\Log\\Logger($targets);\n" +"$logger->setFlushInterval(100); // default is 1000\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "" +"> [!IMPORTANT]\n" +"> Message flushing also occurs when the application ends,\n" +"which ensures log targets can receive complete log messages.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "" +"When the [[\\Yiisoft\\Log\\Logger|logger object]] flushes log messages to [log targets](#log-targets),\n" +"they don't get exported immediately. Instead, the message exporting only occurs when a log target\n" +" accumulates a certain number of the filtered messages. You can customize this number by calling the\n" +"[[\\Yiisoft\\Log\\Target::setExportInterval()|setExportInterval()]] method of individual\n" +"[log targets](#log-targets), like the following:\n" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "" +"$fileTarget = new \\Yiisoft\\Log\\Target\\File\\FileTarget('/path/to/app.log');\n" +"$fileTarget->setExportInterval(100); // default is 1000\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "Because of the flushing and exporting level setting, by default when you call any logging method, you will NOT see the log message immediately in the log targets. This could be a problem for some long-running console applications. To make each log message appear immediately in the log targets, you should set both flush interval and export interval to be 1, as shown below:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "" +"$fileTarget = new \\Yiisoft\\Log\\Target\\File\\FileTarget('/path/to/app.log');\n" +"$fileTarget->setExportInterval(1);\n" +"\n" +"$logger = new \\Yiisoft\\Log\\Logger([$fileTarget]);\n" +"$logger->setFlushInterval(1);\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> Frequent message flushing and exporting will degrade the performance of your application.\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "Toggling log targets" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "You can enable or disable a log target by calling its [[\\Yiisoft\\Log\\Target::enable()|enable()] ] and [[\\Yiisoft\\Log\\Target::disable()|disable()]] methods. You may do so via the log target configuration or by the following PHP statement in your code:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "" +"$fileTarget = new \\Yiisoft\\Log\\Target\\File\\FileTarget('/path/to/app.log');\n" +"$logger = new \\Yiisoft\\Log\\Logger([$fileTarget, /*Other targets*/]);\n" +"\n" +"foreach ($logger->getTargets() as $target) {\n" +" if ($target instanceof \\Yiisoft\\Log\\Target\\File\\FileTarget) {\n" +" $target->disable();\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "To check whether the log target is enabled, call the `isEnabled()` method. You also may pass callable to [[\\Yiisoft\\Log\\Target::setEnabled()|setEnabled()]] to define a dynamic condition for whether the log target should be enabled or not." +msgstr "" + +#. type: Title ### +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "Creating new targets" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "Creating a new log target class is straightforward. You mainly need to implement the [[\\Yii\\Log\\Target::export()]] abstract method that sends all accumulated log messages to a designated medium." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "The following protected methods will also be available for child targets:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/logging.md +msgid "`getMessages` - Get a list of log messages ([[\\Yii\\Log\\Message]] instances)." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/logging.md +msgid "`getFormattedMessages` - Get a list of log messages formatted as strings." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/logging.md +msgid "`formatMessages` - Get all log messages formatted as a string." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/logging.md +msgid "`getCommonContext` - Get an array with common context data in the `key => value` format." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +msgid "For more details, you may refer to any of the log target classes included in the package." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "" +"> [!TIP]\n" +"> Instead of creating your own loggers, you may try any PSR-3 compatible logger such\n" +"as [Monolog](https://github.com/Seldaek/monolog) by using [[\\Yii\\Log\\PsrTarget]].\n" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/logging.md +#, no-wrap +msgid "" +"/**\n" +" * @var \\Psr\\Log\\LoggerInterface $psrLogger\n" +" */\n" +"\n" +"$psrTarget = new \\Yiisoft\\Log\\PsrTarget($psrLogger);\n" +"$logger = new \\Yiisoft\\Log\\Logger([$psrTarget]);\n" +"\n" +"$logger->info('Text message');\n" +msgstr "" diff --git a/_translations/po/pt-BR/guide_runtime_request.md.po b/_translations/po/pt-BR/guide_runtime_request.md.po new file mode 100644 index 00000000..fbbc4714 --- /dev/null +++ b/_translations/po/pt-BR/guide_runtime_request.md.po @@ -0,0 +1,554 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-06-02 21:36+0000\n" +"PO-Revision-Date: 2026-06-02 21:36+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/guide/runtime/request.md +#, no-wrap +msgid "Request" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/request.md +msgid "HTTP request has a method, URI, a set of headers and a body:" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/runtime/request.md +#, no-wrap +msgid "" +"POST /contact HTTP/1.1\n" +"Host: example.org\n" +"Accept-Language: en-us\n" +"Accept-Encoding: gzip, deflate\n" +"\n" +"{\n" +" \"subject\": \"Hello\",\n" +" \"body\": \"Hello there, we need to build Yii application together!\"\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/request.md +msgid "The method is `POST`, URI is `/contact`. Extra headers are specifying host, preferred language and encoding. The body could be anything. In this case, it's a JSON payload." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/request.md +msgid "Yii uses [PSR-7 `ServerRequest`](https://www.php-fig.org/psr/psr-7/) as request representation. The object is available in controller actions and other types of middleware:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/request.md +#, no-wrap +msgid "" +"public function view(ServerRequestInterface $request): ResponseInterface\n" +"{\n" +" // ...\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/runtime/request.md +#, no-wrap +msgid "Method" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/request.md +msgid "The method could be obtained from a request object:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/request.md +#, no-wrap +msgid "$method = $request->getMethod();\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/request.md +msgid "Usually it's one of the:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/request.md +msgid "GET" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/request.md +msgid "POST" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/request.md +msgid "PUT" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/request.md +msgid "DELETE" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/request.md +msgid "HEAD" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/request.md +msgid "PATCH" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/request.md +msgid "OPTIONS" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/request.md +msgid "In case you want to make sure the request method is of a certain type, there is a special class with method names:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/request.md +#, no-wrap +msgid "" +"use Yiisoft\\Http\\Method;\n" +"\n" +"if ($request->getMethod() === Method::POST) {\n" +" // method is POST\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/runtime/request.md +#, no-wrap +msgid "URI" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/request.md +msgid "A URI has:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/request.md +msgid "Scheme (`http`, `https`)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/request.md +msgid "Host (`yiiframework.com`)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/request.md +msgid "Port (`80`, `443`)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/request.md +msgid "Path (`/posts/1`)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/request.md +msgid "Query string (`page=1&sort=+id`)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/request.md +msgid "Fragment (`#anchor`)" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/request.md +msgid "You can obtain `UriInterface` from request like the following:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/request.md +#, no-wrap +msgid "$uri = $request->getUri();\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/request.md +msgid "Then you can get various details from its methods:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/request.md +msgid "`getScheme()`" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/request.md +msgid "`getAuthority()`" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/request.md +msgid "`getUserInfo()`" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/request.md +msgid "`getHost()`" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/request.md +msgid "`getPort()`" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/request.md +msgid "`getPath()`" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/request.md +msgid "`getQuery()`" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/request.md +msgid "`getFragment()`" +msgstr "" + +#. type: Title ## +#: ../src/guide/runtime/request.md ../src/guide/runtime/response.md +#, no-wrap +msgid "Headers" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/request.md +msgid "There are various methods to inspect request headers. To get all headers as an array:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/request.md +#, no-wrap +msgid "" +"$headers = $request->getHeaders();\n" +"foreach ($headers as $name => $values) {\n" +" // ...\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/request.md +msgid "To get a single header:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/request.md +#, no-wrap +msgid "$values = $request->getHeader('Accept-Encoding');\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/request.md +msgid "Also, you could get value as a comma-separated string instead of an array. That's especially handy if a header has a single value:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/request.md +#, no-wrap +msgid "" +"if ($request->getHeaderLine('X-Requested-With') === 'XMLHttpRequest') {\n" +" // This is an AJAX request made with jQuery.\n" +" // Note that header presence and name may vary depending on the library used. \n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/request.md +msgid "To check if a header is present in the request:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/request.md +#, no-wrap +msgid "" +"if ($request->hasHeader('Accept-Encoding')) {\n" +" // ...\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/runtime/request.md ../src/guide/runtime/response.md +#: ../src/internals/006-git-commit-messages.md +#, no-wrap +msgid "Body" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/request.md +msgid "There are two methods to get body contents. The first is getting the body as it is without parsing:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/request.md +#, no-wrap +msgid "$body = $request->getBody();\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/request.md +msgid "The `$body` would be an instance of `Psr\\Http\\Message\\StreamInterface`." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/request.md +msgid "Also, you could get a parsed body:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/request.md +#, no-wrap +msgid "$bodyParameters = $request->getParsedBody();\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/request.md +msgid "Parsing depends on PSR-7 implementation and may require middleware for custom body formats." +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/request.md +#, no-wrap +msgid "" +"getHeaderLine('Content-Type');\n" +"\n" +" if (strpos($contentType, 'application/json') !== false) {\n" +" $body = $request->getBody();\n" +" $parsedBody = $this->parse($body);\n" +" $request = $request->withParsedBody($parsedBody);\n" +" \n" +" }\n" +"\n" +" return $next->handle($request);\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/runtime/request.md +#, no-wrap +msgid "File uploads" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/request.md +msgid "Uploaded files that user submitted from a form with `enctype` attribute equals to `multipart/form-data` are handled via special request method:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/request.md +#, no-wrap +msgid "" +"$files = $request->getUploadedFiles();\n" +"foreach ($files as $file) {\n" +" if ($file->getError() === UPLOAD_ERR_OK) {\n" +" $file->moveTo('path/to/uploads/new_filename.ext');\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/request.md +msgid "Always validate the upload before reading the stream or moving the file. The file may be missing, too large for PHP configuration, only partially uploaded, rejected by a PHP extension, or not match the file type and size your application expects. Yii Validator provides the `Yiisoft\\Validator\\Rule\\File` rule for this. It accepts PSR-7 `UploadedFileInterface` values and validates upload error codes, extension, MIME type, and size. Use `Yiisoft\\Validator\\Rule\\Each` when a field contains several files." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/request.md +msgid "The following example handles a single `avatar` upload. It validates the uploaded file with Yii Validator, stores the file outside the public directory, and generates its own file name instead of trusting the client-provided name." +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/request.md +#, no-wrap +msgid "" +"\n" +" */\n" +" private const EXTENSIONS = [\n" +" 'image/jpeg' => 'jpg',\n" +" 'image/png' => 'png',\n" +" 'image/webp' => 'webp',\n" +" ];\n" +"\n" +" public function __construct(\n" +" private Aliases $aliases,\n" +" private ResponseFactoryInterface $responseFactory,\n" +" ) {\n" +" }\n" +"\n" +" public function __invoke(ServerRequestInterface $request): ResponseInterface\n" +" {\n" +" $file = $request->getUploadedFiles()['avatar'] ?? null;\n" +"\n" +" $result = (new Validator())->validate(\n" +" ['avatar' => $file],\n" +" [\n" +" 'avatar' => [\n" +" new File(\n" +" extensions: ['jpg', 'jpeg', 'png', 'webp'],\n" +" mimeTypes: array_keys(self::EXTENSIONS),\n" +" maxSize: self::MAX_SIZE,\n" +" ),\n" +" new Image(skipOnError: true),\n" +" ],\n" +" ],\n" +" );\n" +"\n" +" if (!$result->isValid() || !$file instanceof UploadedFileInterface) {\n" +" $messages = $result->getPropertyErrorMessages('avatar');\n" +" return $this->badRequest(\n" +" $messages === [] ? 'Upload a file in the \"avatar\" field.' : implode(' ', $messages),\n" +" );\n" +" }\n" +"\n" +" $uploadDirectory = $this->aliases->get('@runtime/uploads/avatars');\n" +" $this->ensureDirectory($uploadDirectory);\n" +"\n" +" $temporaryPath = $uploadDirectory . DIRECTORY_SEPARATOR . bin2hex(random_bytes(16)) . '.upload';\n" +" $file->moveTo($temporaryPath);\n" +"\n" +" $mediaType = (new finfo(FILEINFO_MIME_TYPE))->file($temporaryPath);\n" +"\n" +" if (!is_string($mediaType) || !isset(self::EXTENSIONS[$mediaType])) {\n" +" unlink($temporaryPath);\n" +" return $this->badRequest('Only JPEG, PNG, and WebP images are allowed.');\n" +" }\n" +"\n" +" $fileName = bin2hex(random_bytes(16)) . '.' . self::EXTENSIONS[$mediaType];\n" +" $targetPath = $uploadDirectory . DIRECTORY_SEPARATOR . $fileName;\n" +"\n" +" if (!rename($temporaryPath, $targetPath)) {\n" +" unlink($temporaryPath);\n" +" throw new RuntimeException('Unable to store uploaded file.');\n" +" }\n" +"\n" +" $response = $this->responseFactory->createResponse(Status::CREATED);\n" +" $response->getBody()->write('Stored as ' . $fileName);\n" +"\n" +" return $response;\n" +" }\n" +"\n" +" private function badRequest(string $message): ResponseInterface\n" +" {\n" +" $response = $this->responseFactory->createResponse(Status::BAD_REQUEST);\n" +" $response->getBody()->write($message);\n" +"\n" +" return $response;\n" +" }\n" +"\n" +" private function ensureDirectory(string $directory): void\n" +" {\n" +" if (!is_dir($directory) && !mkdir($directory, 0775, true) && !is_dir($directory)) {\n" +" throw new RuntimeException(sprintf('Directory \"%s\" was not created.', $directory));\n" +" }\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/request.md +msgid "Notes:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/request.md +msgid "Store uploads under `@runtime` or another non-public directory unless the files are intentionally public." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/request.md +msgid "Do not use `getClientFilename()` as a storage path. A browser controls it, so it may contain unsafe characters, path-like values, or duplicate names." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/request.md +msgid "Do not rely on `getClientMediaType()` alone. It comes from the client. Use `File` MIME type validation, `Image` for image validation and dimension checks, or another server-side parser appropriate for the file format." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/request.md +msgid "Check PHP limits such as `upload_max_filesize`, `post_max_size`, and `max_file_uploads` when expected files are rejected before the action runs." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/request.md +msgid "When a form uploads several files, the array returned by `getUploadedFiles()` has the same shape as the file input names. Validate them with `Each(new File(...))` and move each `UploadedFileInterface` separately." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/request.md +msgid "`File` can also validate string file paths and `SplFileInfo` instances. Do not pass user-submitted paths directly: use PSR-7 uploaded file objects from the request, or perform upload provenance checks before validating filesystem paths." +msgstr "" + +#. type: Title ## +#: ../src/guide/runtime/request.md +#, no-wrap +msgid "Attributes" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/request.md +msgid "Application middleware may set custom request attributes using `withAttribute()` method. You can get these attributes with `getAttribute()`." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/request.md +msgid "Route arguments, such as `id` from a `/posts/{id}` route pattern, aren't request attributes. Use `#[RouteArgument]` in an action parameter or inject `Yiisoft\\Router\\CurrentRoute` when you need route arguments or route metadata." +msgstr "" diff --git a/_translations/po/pt-BR/guide_runtime_response.md.po b/_translations/po/pt-BR/guide_runtime_response.md.po new file mode 100644 index 00000000..e73575db --- /dev/null +++ b/_translations/po/pt-BR/guide_runtime_response.md.po @@ -0,0 +1,236 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-05-09 20:32+0000\n" +"PO-Revision-Date: 2026-05-09 20:32+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/guide/runtime/request.md ../src/guide/runtime/response.md +#, no-wrap +msgid "Headers" +msgstr "" + +#. type: Title ## +#: ../src/guide/runtime/request.md ../src/guide/runtime/response.md +#: ../src/internals/006-git-commit-messages.md +#, no-wrap +msgid "Body" +msgstr "" + +#. type: Title # +#: ../src/guide/runtime/response.md +#, no-wrap +msgid "Response" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/response.md +msgid "HTTP response has status code and message, a set of headers and a body:" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/runtime/response.md +#, no-wrap +msgid "" +"HTTP/1.1 200 OK\n" +"Date: Mon, 27 Jul 2009 12:28:53 GMT\n" +"Server: Apache/2.2.14 (Win32)\n" +"Last-Modified: Wed, 22 Jul 2009 19:15:56 GMT\n" +"Content-Length: 6 \n" +"Content-Type: text/html\n" +"Connection: Closed\n" +"\n" +"Hello!\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/response.md +msgid "Yii uses [PSR-7 `Response`](https://www.php-fig.org/psr/psr-7/) in the web application to represent response." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/response.md +msgid "The object should be constructed and returned as a result of the execution of controller actions or other middleware. Usually, the middleware has a response factory injected into its constructor." +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/response.md +#, no-wrap +msgid "" +"use Psr\\Http\\Message\\ResponseFactoryInterface;\n" +"use Psr\\Http\\Message\\ResponseInterface;\n" +"use Psr\\Http\\Message\\ServerRequestInterface;\n" +"\n" +"final readonly class PostAction\n" +"{\n" +" public function __construct(\n" +" private ResponseFactoryInterface $responseFactory\n" +" )\n" +" {\n" +" }\n" +"\n" +" public function view(ServerRequestInterface $request): ResponseInterface\n" +" {\n" +" $response = $this->responseFactory->createResponse();\n" +" $response->getBody()->write('Hello!');\n" +" return $response;\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/runtime/response.md +#, no-wrap +msgid "Status code" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/response.md +msgid "You can set a status code like the following:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/response.md +#, no-wrap +msgid "" +"use Yiisoft\\Http\\Status;\n" +"\n" +"$response = $response->withStatus(Status::NOT_FOUND);\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/response.md +msgid "Majority of status codes are available from `Status` class for convenience and readability." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/response.md +msgid "Router may return a response before an action runs. For example, an `OPTIONS` request to a known route path gets an automatic `204 No Content` response with an `Allow` header that lists supported methods. See [Automatic OPTIONS responses](routing.md#automatic-options-responses) for routing details." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/response.md +msgid "You can set headers like this:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/response.md +#, no-wrap +msgid "$response = $response->withHeader('Content-type', 'application/json');\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/response.md +msgid "If there is a need to append a header value to the existing header:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/response.md +#, no-wrap +msgid "$response = $response->withAddedHeader('Set-Cookie', 'qwerty=219ffwef9w0f; Domain=somecompany.co.uk; Path=/; Expires=Wed, 30 Aug 2019 00:00:00 GMT');\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/response.md +msgid "And, if needed, headers could be removed:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/response.md +#, no-wrap +msgid "$response = $response->withoutHeader('Set-Cookie');\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/response.md +msgid "Response body is an object implementing `Psr\\Http\\Message\\StreamInterface`." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/response.md +msgid "You can write to it via the interface itself:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/response.md +#, no-wrap +msgid "" +"$body = $response->getBody();\n" +"$body->write('Hello');\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/runtime/response.md +#, no-wrap +msgid "Examples" +msgstr "" + +#. type: Title ### +#: ../src/guide/runtime/response.md +#, no-wrap +msgid "Redirecting" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/response.md +#, no-wrap +msgid "" +"use Yiisoft\\Http\\Status;\n" +"\n" +"return $response\n" +" ->withStatus(Status::PERMANENT_REDIRECT)\n" +" ->withHeader('Location', 'https://www.example.com'); \n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/response.md +msgid "Note that there are different statuses used for redirection:" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/response.md +#, no-wrap +msgid "" +"| Code | Usage | What is it for |\n" +"|------|------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n" +"| 301 | `Status::MOVED_PERMANENTLY` | Permanently changed a URL structure. Search engines update their indexes, and browsers cache it. |\n" +"| 308 | `Status::PERMANENT_REDIRECT` | Like 301, but guarantees the HTTP method won't change. |\n" +"| 302 | `Status::FOUND` | Temporary changes like maintenance pages. Original URL should still be used for future requests. Search engines typically don't update their indexes. |\n" +"| 307 | `Status::TEMPORARY_REDIRECT` | Like 302, but guarantees the HTTP method won't change. |\n" +"| 303 | `Status::SEE_OTHER` | After form submissions to prevent duplicate submissions if the user refreshes. Explicitly tells to use `GET` for the redirect, even if the original request was `POST`. |\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/runtime/response.md +#, no-wrap +msgid "Responding with JSON" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/response.md +#, no-wrap +msgid "" +"use Yiisoft\\Http\\Status;\n" +"use Yiisoft\\Json\\Json;\n" +"\n" +"$data = [\n" +" 'account' => 'samdark',\n" +" 'value' => 42\n" +"];\n" +"\n" +"$response->getBody()->write(Json::encode($data));\n" +"return $response\n" +" ->withStatus(Status::OK)\n" +" ->withHeader('Content-Type', 'application/json');\n" +msgstr "" diff --git a/_translations/po/pt-BR/guide_runtime_routing.md.po b/_translations/po/pt-BR/guide_runtime_routing.md.po new file mode 100644 index 00000000..37ed53d5 --- /dev/null +++ b/_translations/po/pt-BR/guide_runtime_routing.md.po @@ -0,0 +1,861 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-06-05 20:33+0000\n" +"PO-Revision-Date: 2026-06-05 20:33+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/guide/runtime/routing.md +#, no-wrap +msgid "Routing and URL generation" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "Usually, a Yii application processes certain requests with certain handlers. It selects a handler based on the request URL. The part of the application that does the job is a router, and the process of selecting a handler, instantiating it and running a handler method is *routing*." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "The reverse process of routing is *URL generation*, which creates a URL from a given named route, route arguments, and query parameters. When you later request the created URL, the routing process can resolve it back into the original route arguments and query parameters." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "Routing and URL generation are separate services, but they use a common set of routes for both URL matching and URL generation." +msgstr "" + +#. type: Title ## +#: ../src/guide/runtime/routing.md +#, no-wrap +msgid "Configuring routes" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "By configuring routes, you can let your application recognize arbitrary URL formats without modifying your existing application code. You can configure routes in `/config/routes.php`. The structure of the file is the following:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/routing.md +#, no-wrap +msgid "" +"action([SiteController::class, 'index'])\n" +" ->name('site/index')\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "The file returns an array of routes. When defining a route, you start with a method corresponding to a certain HTTP request type:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/routing.md +msgid "get" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/routing.md +msgid "post" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/routing.md +msgid "put" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/routing.md +msgid "delete" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/routing.md +msgid "patch" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/routing.md +msgid "head" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/routing.md +msgid "options" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "If you need many methods, you can use `methods()`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/routing.md +#, no-wrap +msgid "" +"action([SiteController::class, 'user'])\n" +" ->name('site/user')\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "All these methods accept a route pattern. The route pattern defines how the router matches the URL when routing and how it generates URL based on route name and parameters. You will learn about the actual syntax later in this guide. Specify a handler with `action()` as:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/routing.md +msgid "[Middleware](../structure/middleware.md) class name." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/routing.md +msgid "Handler action (an array of [HandlerClass, handlerMethod])." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/routing.md +msgid "A callable." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "In case of a handler action, a class of type `HandlerClass` is instantiated and its `handlerMethod` is called:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/routing.md +#, no-wrap +msgid "" +"use Psr\\Http\\Message\\ServerRequestInterface;\n" +"use Psr\\Http\\Message\\ResponseInterface;\n" +"\n" +"final readonly class HandlerClass\n" +"{\n" +" public function handle(ServerRequestInterface $request): ResponseInterface\n" +" {\n" +" // ...\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "The callable is called as is:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/routing.md +#, no-wrap +msgid "" +"static function (ServerRequestInterface $request, RequestHandlerInterface $next) use ($responseFactory) {\n" +" $response = $responseFactory->createResponse();\n" +" $response->getBody()->write('You are at homepage.');\n" +" return $response;\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "For handler action and callable typed parameters are automatically injected using the dependency injection container passed to the route." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "Get current request and handler by type-hinting for `ServerRequestInterface` and `RequestHandlerInterface`." +msgstr "" + +#. type: Title ### +#: ../src/guide/runtime/routing.md +#, no-wrap +msgid "Route arguments in actions" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "Named route parameters are stored in `CurrentRoute`. To pass a route parameter to an action method parameter, use the `RouteArgument` attribute:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/routing.md +#, no-wrap +msgid "" +"action([PostController::class, 'view'])\n" +" ->name('post/view')\n" +"];\n" +"\n" +"final readonly class PostController\n" +"{\n" +" public function view(#[RouteArgument('id')] int $id): ResponseInterface\n" +" {\n" +" // $id contains the value from the {id} route parameter.\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "If a parameter has the same name as the action parameter, you can omit the attribute name:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/routing.md +#, no-wrap +msgid "" +"public function view(#[RouteArgument] int $id): ResponseInterface\n" +"{\n" +" // ...\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "You can also inject `CurrentRoute` into an action or a service when you need several arguments or route metadata:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/routing.md +#, no-wrap +msgid "" +"getArgument('id');\n" +" $routeName = $currentRoute->getName();\n" +"\n" +" // ...\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "Route arguments aren't request attributes. Read them from `CurrentRoute` or action parameters marked with `RouteArgument`." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "For optional route parameters, provide a default value either in the route with `defaults()` or in the action method signature." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "You could add extra handlers to wrap primary one with `middleware()` method:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/routing.md +#, no-wrap +msgid "" +"action([DownloadController::class, 'download'])\n" +" ->name('download/id')\n" +" ->middleware(LimitDownloadRate::class)\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "Check [\"the middleware\"](../structure/middleware.md) guide to learn more about how to implement middleware." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "This is especially useful when grouping routes:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/routing.md +#, no-wrap +msgid "" +"middleware(ApiDataWrapper::class)\n" +" ->routes(\n" +" Route::get('/info/v2')\n" +" ->action(ApiInfo::class)\n" +" ->name('api/info/v2')\n" +" ->middleware(JsonDataResponseMiddleware::class),\n" +" Route::get('/user')\n" +" ->action([ApiUserController::class, 'index'])\n" +" ->name('api/user/index'),\n" +" Route::get('/user/{login}')\n" +" ->action([ApiUserController::class, 'profile'])\n" +" ->middleware(JsonDataResponseMiddleware::class)\n" +" ->name('api/user/profile'),\n" +" )\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "Router executes `ApiDataWrapper` before handling any URL starting with `/api`." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "You could name a route with a `name()` method. It's a good idea to choose a route name based on the handler's name." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "You can set a default value for a route parameter. For example:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/routing.md +#, no-wrap +msgid "" +"action([SiteController::class, 'user'])\n" +" ->name('site/user')\n" +" ->defaults(['id' => '42'])\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "This configuration would result in a match with both `/user` and `/user/123`. In both cases `CurrentRoute` service will contain `id` argument filled. In the first case it will be default `42` and in the second case it will be `123`." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "In cause URL should be valid for a single host, you can specify it with `host()`." +msgstr "" + +#. type: Title ### +#: ../src/guide/runtime/routing.md ../src/guide/start/databases.md +#, no-wrap +msgid "Routing" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "Yii routing is flexible, and internally it may use different routing implementations. The actual matching algorithm may vary, but the basic idea stays the same." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "Router matches routes defined in config from top to bottom. If there is a match, further matching isn't performed and the router executes the route handler to get the response. If there is no match at all, router passes handling to the next middleware in the [application middleware set](../structure/middleware.md)." +msgstr "" + +#. type: Title ### +#: ../src/guide/runtime/routing.md +#, no-wrap +msgid "Automatic OPTIONS responses" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "When the request path matches a route but the HTTP method doesn't, router returns a `405 Method Not Allowed` response with an `Allow` header:" +msgstr "" + +#. type: Fenced code block (http) +#: ../src/guide/runtime/routing.md +#, no-wrap +msgid "" +"HTTP/1.1 405 Method Not Allowed\n" +"Allow: GET\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "For an `OPTIONS` request to the same path, router returns an empty `204 No Content` response with the same `Allow` header:" +msgstr "" + +#. type: Fenced code block (http) +#: ../src/guide/runtime/routing.md +#, no-wrap +msgid "" +"HTTP/1.1 204 No Content\n" +"Allow: GET\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "This response is generated from the configured routes before the route action runs. If an API endpoint needs CORS headers, attach CORS middleware to a route group:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/routing.md +#, no-wrap +msgid "" +"withCors(CorsMiddleware::class)\n" +" ->routes(\n" +" Route::methods([Method::GET, Method::POST], '/posts')\n" +" ->action([PostController::class, 'index'])\n" +" ->name('api/posts')\n" +" )\n" +"];\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/runtime/routing.md +#, no-wrap +msgid "Generating URLs" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "To generate URL based on a route, a route should have a name:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/routing.md +#, no-wrap +msgid "" +"action([TestController::class, 'index'])\n" +" ->name('test/index'),\n" +" Route::post('/test/submit/{id}')\n" +" ->action([TestController::class, 'submit'])\n" +" ->name('test/submit')\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "The generation looks like the following:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/routing.md +#, no-wrap +msgid "" +"generate('test/submit', ['id' => '42']);\n" +" // ...\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "In the above code, we get a generator instance with the help of [automatic dependency injection](../concept/di-container.md) that works with action handlers. In another service, you can get the instance with similar constructor injection. In views URL generator is available as `$url`." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "Then we use `generate()` method to get the actual URL. It accepts a route name, route arguments, query parameters, and a hash fragment. The code will return `/test/submit/42`." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "Route arguments are used to fill placeholders in the route pattern. Arguments that aren't used in the pattern are added to the query string when the query parameters array doesn't already contain the same name:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/routing.md +#, no-wrap +msgid "" +"$url = $urlGenerator->generate(\n" +" 'test/submit',\n" +" ['id' => '42', 'utm' => 'newsletter'],\n" +" ['page' => '1']\n" +");\n" +"// $url is \"/test/submit/42?page=1&utm=newsletter\".\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "If you need absolute URL, use `generateAbsolute()` instead." +msgstr "" + +#. type: Title ### +#: ../src/guide/runtime/routing.md +#, no-wrap +msgid "Generating URL from the current route" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "Use `generateFromCurrent()` when a link should keep the current route and most of its arguments. For example, a detail page can link to another page number while keeping the current route name and `id` argument:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/routing.md +#, no-wrap +msgid "$url = $urlGenerator->generateFromCurrent(['page' => '2']);\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "The method also keeps query parameters from the current request. Pass explicit query parameters when a link should replace or add query string values." +msgstr "" + +#. type: Title ### +#: ../src/guide/runtime/routing.md +#, no-wrap +msgid "Locale-based URLs" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "When the locale is part of the URL path, define it as a route argument. For a Yii application with routes in `config/common/routes.php`, wrap localized routes in a group with a locale parameter:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/routing.md +#, no-wrap +msgid "" +"routes(\n" +" Route::get('/')\n" +" ->action(HomePageAction::class)\n" +" ->name('home'),\n" +" Route::get('/posts/{slug}')\n" +" ->action(PostViewAction::class)\n" +" ->name('post/view')\n" +" )\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "The route `/de/posts/welcome` matches the `post/view` route and stores `_locale` as a route argument with the `de` value." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "In middleware that chooses the request locale, read this argument from `CurrentRoute`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/routing.md +#, no-wrap +msgid "" +"currentRoute->getArgument('_locale', self::DEFAULT_LOCALE);\n" +"\n" +" $this->translator->setLocale($locale);\n" +" $this->view->setLocale($locale);\n" +" $this->urlGenerator->setDefaultArgument('_locale', $locale);\n" +"\n" +" return $handler->handle($request);\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "Register this middleware in the localized route group before the route action:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/routing.md +#, no-wrap +msgid "" +"use App\\Web\\HomePage\\Action as HomePageAction;\n" +"use App\\Web\\Middleware\\LocaleMiddleware;\n" +"use Yiisoft\\Router\\Group;\n" +"use Yiisoft\\Router\\Route;\n" +"\n" +"return [\n" +" Group::create('/{_locale:en-US|de}')\n" +" ->middleware(LocaleMiddleware::class)\n" +" ->routes(\n" +" Route::get('/')\n" +" ->action(HomePageAction::class)\n" +" ->name('home')\n" +" )\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "After the middleware sets the default `_locale` argument, URL generation can omit it:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/routing.md +#, no-wrap +msgid "" +"$url = $urlGenerator->generate('post/view', ['slug' => 'welcome']);\n" +"// On a German page, $url is \"/de/posts/welcome\".\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "For a language switcher, use `generateFromCurrent()` and replace only the locale argument:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/routing.md +#, no-wrap +msgid "" +"$url = $urlGenerator->generateFromCurrent(\n" +" ['_locale' => 'en-US'],\n" +" fallbackRouteName: 'home'\n" +");\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/runtime/routing.md +#, no-wrap +msgid "Route patterns" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "Route patterns used depend on the underlying implementation used. The default implementation is [nikic/FastRoute](https://github.com/nikic/FastRoute)." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "Basic patterns are static like `/test`. That means they must match exactly in order for a route match." +msgstr "" + +#. type: Title ### +#: ../src/guide/runtime/routing.md +#, no-wrap +msgid "Named Parameters" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "A pattern can include one or more named parameters which are specified in the pattern in the format of `{ParamName:RegExp}`, where `ParamName` specifies the parameter name and `RegExp` is an optional regular expression used to match parameter values. If `RegExp` isn't specified, it means the parameter value should be a string without any slash." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> You can only use regular expressions inside parameters. The rest of the pattern is considered plain text.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "You can't use capturing groups. For example `{lang:(en|de)}` isn't a valid placeholder, because `()` is a capturing group. Instead, you can use either `{lang:en|de}` or `{lang:(?:en|de)}`." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "On a route match router fills `CurrentRoute` arguments with values matching the corresponding parts of the URL. When you use the rule to create a URL, it will take the values of the provided parameters and insert them at the places where the parameters are declared." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "Let's use some examples to illustrate how named parameters work. Assume you've declared the following three patterns:" +msgstr "" + +#. type: Bullet: '1. ' +#: ../src/guide/runtime/routing.md +msgid "`'posts/{year:\\d{4}}/{category}`" +msgstr "" + +#. type: Bullet: '2. ' +#: ../src/guide/runtime/routing.md +msgid "`'posts'`" +msgstr "" + +#. type: Bullet: '3. ' +#: ../src/guide/runtime/routing.md +msgid "`'post/{id:\\d+}'`" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/routing.md +msgid "`/posts` match the second pattern;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/routing.md +msgid "`/posts/2014/php` match a first pattern. Parameters are the `year` whose value is 2014 and the `category` whose value is `php`;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/routing.md +msgid "`/post/100` match a third pattern. The `id` parameter value is 100;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/runtime/routing.md +msgid "`/posts/php` doesn't match." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "When generating URLs, you should use the following parameters:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/routing.md +#, no-wrap +msgid "" +"echo $url->generate('first', ['year' => '2020', 'category' => 'Virology']);\n" +"echo $url->generate('second');\n" +"echo $url->generate('third', ['id' => '42']);\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/runtime/routing.md +#, no-wrap +msgid "Optional parts" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "You should wrap optional pattern parts with `[` and `]`. For example, `/posts[/{id}]` pattern would match both `http://example.com/posts` and `http://example.com/posts/42`. Router would fill `id` argument of `CurrentRoute` service in the second case only. In this case, you could specify the default value:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/routing.md +#, no-wrap +msgid "" +"use \\Yiisoft\\Router\\Route;\n" +"\n" +"Route::get('/posts[/{id}]')->defaults(['id' => '1']);\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/routing.md +msgid "Optional parts are only supported in a trailing position, not in the middle of a route." +msgstr "" diff --git a/_translations/po/pt-BR/guide_runtime_sessions.md.po b/_translations/po/pt-BR/guide_runtime_sessions.md.po new file mode 100644 index 00000000..ebb628d7 --- /dev/null +++ b/_translations/po/pt-BR/guide_runtime_sessions.md.po @@ -0,0 +1,251 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-09-29 22:50+0000\n" +"PO-Revision-Date: 2026-09-29 22:50+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/guide/runtime/sessions.md +#: ../src/guide/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "Sessions" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/sessions.md +msgid "Sessions persist data between requests without passing them to the client and back. Yii has [a session package](https://github.com/yiisoft/session) to work with session data." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/sessions.md +msgid "To add it to your application, use composer:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/runtime/sessions.md +#, no-wrap +msgid "composer require yiisoft/session\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/runtime/sessions.md +#, no-wrap +msgid "Configuring middleware" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/sessions.md +msgid "To keep a session between requests, you need to add `SessionMiddleware` to your route group or application middlewares. You should prefer a route group when you have both API with token-based authentication and regular web routes in the same application. Having it this way avoids starting the session for API endpoints." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/sessions.md +msgid "To add a session for a certain group of routes, edit `config/routes.php` like the following:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/sessions.md +#, no-wrap +msgid "" +"middleware(SessionMiddleware::class)\n" +" ->routes(\n" +" // ...\n" +" )\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/sessions.md +msgid "To add a session to the whole application, edit `config/application.php` like the following:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/sessions.md +#, no-wrap +msgid "" +"return [\n" +" Yiisoft\\Yii\\Web\\Application::class => [\n" +" '__construct()' => [\n" +" 'dispatcher' => DynamicReference::to(static function (Injector $injector) {\n" +" return ($injector->make(MiddlewareDispatcher::class))\n" +" ->withMiddlewares(\n" +" [\n" +" Router::class,\n" +" CsrfTokenMiddleware::class,\n" +" SessionMiddleware::class, // <-- add this\n" +" ErrorCatcher::class,\n" +" ]\n" +" );\n" +" }),\n" +" ],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/runtime/sessions.md +#, no-wrap +msgid "Opening and closing session" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/sessions.md +#, no-wrap +msgid "" +"public function actionProfile(\\Yiisoft\\Session\\SessionInterface $session)\n" +"{\n" +" // start a session if it's not yet started\n" +" $session->open();\n" +"\n" +" // work with session\n" +"\n" +" // write session values and then close it\n" +" $session->close();\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/sessions.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> Closing session as early as possible is a good practice since many session implementations are blocking other\n" +"> requests while the session is open.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/sessions.md +msgid "There are two more ways to close a session:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/sessions.md +#, no-wrap +msgid "" +"public function actionProfile(\\Yiisoft\\Session\\SessionInterface $session)\n" +"{\n" +" // discard changes and close the session\n" +" $session->discard();\n" +"\n" +" // destroy the session completely\n" +" $session->destroy(); \n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/runtime/sessions.md +#, no-wrap +msgid "Working with session data" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/sessions.md +msgid "Usually you will use the following methods to work with session data:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/sessions.md +#, no-wrap +msgid "" +"public function actionProfile(\\Yiisoft\\Session\\SessionInterface $session)\n" +"{\n" +" // get a value\n" +" $lastAccessTime = $session->get('lastAccessTime');\n" +"\n" +" // get all values\n" +" $sessionData = $session->all();\n" +" \n" +" // set a value\n" +" $session->set('lastAccessTime', time());\n" +"\n" +" // check if the value exists\n" +" if ($session->has('lastAccessTime')) {\n" +" // ... \n" +" }\n" +" \n" +" // remove value\n" +" $session->remove('lastAccessTime');\n" +"\n" +" // get value and then remove it\n" +" $sessionData = $session->pull('lastAccessTime');\n" +"\n" +" // clear session data from runtime\n" +" $session->clear();\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/runtime/sessions.md +#, no-wrap +msgid "Flash messages" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/sessions.md +msgid "In case you need some data to remain in session until read, such as in case of displaying a message on the next page, \"flash\" messages are what you need. A flash message is a special type of data that's available only in the current request and the next request. After that, it will be deleted automatically." +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/sessions.md +msgid "`FlashInteface` usage is the following:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/sessions.md +#, no-wrap +msgid "" +"/** @var Yiisoft\\Session\\Flash\\FlashInterface $flash */\n" +"\n" +"// request 1\n" +"$flash->set('warning', 'Oh no, not again.');\n" +"\n" +"// request 2\n" +"$warning = $flash->get('warning');\n" +"if ($warning !== null) {\n" +" // do something with it\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/runtime/sessions.md +#, no-wrap +msgid "Custom session storage" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/sessions.md +msgid "When using `Yiisoft\\Session\\Session`, you can use your own storage implementation:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/runtime/sessions.md +#, no-wrap +msgid "" +"$handler = new MySessionHandler();\n" +"$session = new \\Yiisoft\\Session\\Session([], $handler);\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/runtime/sessions.md +msgid "Custom storage must implement `\\SessionHandlerInterface`." +msgstr "" diff --git a/_translations/po/pt-BR/guide_security_authentication.md.po b/_translations/po/pt-BR/guide_security_authentication.md.po new file mode 100644 index 00000000..89533f7a --- /dev/null +++ b/_translations/po/pt-BR/guide_security_authentication.md.po @@ -0,0 +1,391 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-06-05 20:33+0000\n" +"PO-Revision-Date: 2026-06-05 20:33+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/guide/security/authentication.md +#, no-wrap +msgid "Authentication" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authentication.md +msgid "Authentication is the process of verifying the identity of a user. It usually uses an identifier (for example, a username or an email address) and a secret token (such as a password or an access token) to judge if the user is the one whom he claims as. Authentication is the basis of the login feature." +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authentication.md +msgid "Yii provides an authentication framework which wires up various components to support login. To use this framework, you mainly need to do the following work:" +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/security/authentication.md +msgid "Configure the `Yiisoft\\User\\CurrentUser` service;" +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/security/authentication.md +msgid "Create a class implementing the `\\Yiisoft\\Auth\\IdentityInterface` interface;" +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/security/authentication.md +msgid "Create a class implementing the `\\Yiisoft\\Auth\\IdentityRepositoryInterface` interface;" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authentication.md +msgid "To use the `Yiisoft\\User\\CurrentUser` service, install [yiisoft/user](https://github.com/yiisoft/user) package:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/security/authentication.md +#, no-wrap +msgid "composer require yiisoft/user\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/security/authentication.md +#, no-wrap +msgid "Configuring `Yiisoft\\User\\CurrentUser`" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authentication.md +msgid "The `Yiisoft\\User\\CurrentUser` application service manages the user authentication status. It depends on `Yiisoft\\Auth\\IdentityRepositoryInterface` that should return an instance of `\\Yiisoft\\Auth\\IdentityInterface` which has the actual authentication logic." +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/security/authentication.md +#, no-wrap +msgid "" +"use Yiisoft\\Session\\Session;\n" +"use Yiisoft\\Session\\SessionInterface;\n" +"use Yiisoft\\Auth\\IdentityRepositoryInterface;\n" +"use Yiisoft\\Definitions\\Reference;\n" +"\n" +"return [\n" +" // ...\n" +"\n" +" SessionInterface::class => [\n" +" 'class' => Session::class,\n" +" '__construct()' => [\n" +" $params['session']['options'] ?? [],\n" +" $params['session']['handler'] ?? null,\n" +" ],\n" +" ],\n" +" IdentityRepositoryInterface::class => IdentityRepository::class,\n" +" CurrentUser::class => [\n" +" 'withSession()' => [Reference::to(SessionInterface::class)]\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/security/authentication.md +#, no-wrap +msgid "Implementing`\\Yiisoft\\Auth\\IdentityInterface`" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authentication.md +msgid "The identity class must implement the `\\Yiisoft\\Auth\\IdentityInterface` which has a single method:" +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/security/authentication.md +msgid "[[yii\\web\\IdentityInterface::getId()|getId()]]: it returns the ID of the user represented by this identity instance." +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authentication.md +msgid "In the following example, an identity class is implemented as a pure PHP object." +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/security/authentication.md +#, no-wrap +msgid "" +"id;\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/security/authentication.md +#, no-wrap +msgid "Implementing`\\Yiisoft\\Auth\\IdentityRepositoryInterface`" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authentication.md +msgid "The identity repository class must implement the `\\Yiisoft\\Auth\\IdentityRepositoryInterface` which has the following methods:" +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/security/authentication.md +msgid "`findIdentity(string $id): ?IdentityInterface`: it looks for an instance of the identity class using the specified ID. This method is used when you need to keep the login status via session." +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/security/authentication.md +msgid "`findIdentityByToken(string $token, string $type): ?IdentityInterface`: it looks for an instance of the identity class using the specified access token. This method is used when you need to authenticate a user by a single secret token (for example, in a stateless REST API)." +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authentication.md +msgid "A dummy implementation may look like the following:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/security/authentication.md +#, no-wrap +msgid "" +"namespace App\\User;\n" +"\n" +"use App\\User\\Identity;\n" +"use \\Yiisoft\\Auth\\IdentityInterface;\n" +"use \\Yiisoft\\Auth\\IdentityRepositoryInterface;\n" +"\n" +"final readonly class IdentityRepository implements IdentityRepositoryInterface\n" +"{\n" +" private const USERS = [\n" +" [\n" +" 'id' => 1,\n" +" 'token' => '12345' \n" +" ],\n" +" [\n" +" 'id' => 42,\n" +" 'token' => '54321'\n" +" ], \n" +" ];\n" +"\n" +" public function findIdentity(string $id) : ?IdentityInterface\n" +" {\n" +" foreach (self::USERS as $user) {\n" +" if ((string)$user['id'] === $id) {\n" +" return new Identity($id); \n" +" }\n" +" }\n" +" \n" +" return null;\n" +" }\n" +"\n" +" public function findIdentityByToken(string $token, string $type) : ?IdentityInterface\n" +" {\n" +" foreach (self::USERS as $user) {\n" +" if ($user['token'] === $token) {\n" +" return new Identity((string)$user['id']); \n" +" }\n" +" }\n" +" \n" +" return null;\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/security/authentication.md +#, no-wrap +msgid "Using `Yiisoft\\User\\CurrentUser`" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authentication.md +msgid "You can use `Yiisoft\\User\\CurrentUser` service to get current user identity. As any service, it could be auto-wired in either action handler constructor or method:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/security/authentication.md +#, no-wrap +msgid "" +"use Psr\\Http\\Message\\ServerRequestInterface;\n" +"use Yiisoft\\User\\CurrentUser;\n" +"\n" +"final readonly class SiteController\n" +"{\n" +" public function __construct(private CurrentUser $user) {}\n" +"\n" +" public function index(ServerRequestInterface $request): ResponseInterface\n" +" {\n" +" if ($this->user->isGuest()) {\n" +" // user is guest\n" +" } else {\n" +" $identity = $this->user->getIdentity();\n" +" // do something based on identity\n" +" }\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authentication.md +msgid "`isGuest()` determines if user is logged in or not. `getIdentity()` returns an instance of identity." +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authentication.md +msgid "To log in a user, you may use the following code:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/security/authentication.md +#, no-wrap +msgid "" +"$identity = $identityRepository->findByEmail($email);\n" +"\n" +"/* @var $user \\Yiisoft\\User\\CurrentUser */\n" +"$user->login($identity);\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authentication.md +msgid "The `login()` method sets the identity to the User service. It stores identity into session so user authentication status is maintained." +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authentication.md +msgid "To log out a user, call" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/security/authentication.md +#, no-wrap +msgid "" +"/* @var $user \\Yiisoft\\User\\CurrentUser */\n" +"$user->logout();\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/security/authentication.md +#, no-wrap +msgid "Protecting Routes" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authentication.md +msgid "The `Yiisoft\\Auth\\Middleware\\Authentication` middleware can be used to restrict access to a given route to authenticated users only." +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authentication.md +msgid "First, configure the `Yiisoft\\Auth\\AuthenticationMethodInterface`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/security/authentication.md +#, no-wrap +msgid "" +"use Yiisoft\\Auth\\AuthenticationMethodInterface;\n" +"use Yiisoft\\User\\Method\\WebAuth;\n" +"\n" +"return [\n" +" // ...\n" +" AuthenticationMethodInterface::class => WebAuth::class,\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authentication.md +msgid "Then, apply the `Yiisoft\\Auth\\Middleware\\Authentication` middleware to a route:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/security/authentication.md +#, no-wrap +msgid "" +"use Yiisoft\\Auth\\Middleware\\Authentication;\n" +" \n" +"Route::post('/create')\n" +" ->middleware(Authentication::class)\n" +" ->action([SiteController::class, 'create'])\n" +" ->name('site/create')\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authentication.md +#, no-wrap +msgid " Or to a group of routes:\n" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/security/authentication.md +#, no-wrap +msgid "" +"use Yiisoft\\Auth\\Middleware\\Authentication;\n" +"\n" +"Group::create()\n" +" ->middleware(Authentication::class)\n" +" ->routes(\n" +" Route::post('/create')\n" +" ->action([SiteController::class, 'create'])\n" +" ->name('site/create'),\n" +" Route::put('/update/{id}')\n" +" ->action([SiteController::class, 'update'])\n" +" ->name('site/update')\n" +" )\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/security/authentication.md +#, no-wrap +msgid "Authentication Events" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authentication.md +msgid "The user service raises a few events during the login and logout processes." +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/security/authentication.md +msgid "`\\Yiisoft\\User\\Event\\BeforeLogin`: raised at the beginning of `login()`. If the event handler calls `invalidate()` on an event object, the login process will be cancelled." +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/security/authentication.md +msgid "`\\Yiisoft\\User\\Event\\AfterLogin`: raised after a successful login." +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/security/authentication.md +msgid "`\\Yiisoft\\User\\Event\\BeforeLogout`: raised at the beginning of `logout()`. If the event handler calls `invalidate()` on an event object, the logout process will be cancelled." +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/security/authentication.md +msgid "`\\Yiisoft\\User\\Event\\AfterLogout`: raised after a successful logout." +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authentication.md +msgid "You may respond to these events to implement features such as login audit, online user statistics. For example, in the handler for `\\Yiisoft\\User\\Event\\AfterLogin`, you may record the login time and IP address in the `user` database table." +msgstr "" diff --git a/_translations/po/pt-BR/guide_security_authorization.md.po b/_translations/po/pt-BR/guide_security_authorization.md.po new file mode 100644 index 00000000..f0288ee2 --- /dev/null +++ b/_translations/po/pt-BR/guide_security_authorization.md.po @@ -0,0 +1,854 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-06-05 20:33+0000\n" +"PO-Revision-Date: 2026-06-05 20:33+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Fenced code block +#: ../src/guide/databases/db-migrations.md +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "./yii migrate:up\n" +msgstr "" + +#. type: Title # +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "Authorization" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "Authorization is the process of verifying that a user has enough permission to do something." +msgstr "" + +#. type: Title ## +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "Checking for permission" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "You can check if a user has certain permissions by using `\\Yiisoft\\User\\CurrentUser` service:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "" +"namespace App\\Blog\\Post;\n" +"\n" +"use Yiisoft\\User\\CurrentUser;\n" +"use Yiisoft\\Router\\HydratorAttribute\\RouteArgument;\n" +"use Psr\\Http\\Message\\ResponseInterface;\n" +"\n" +"final readonly class PostController\n" +"{\n" +" public function __construct(\n" +" private PostRepositoryInterface $postRepository,\n" +" private CurrentUser $user\n" +" )\n" +" {\n" +" }\n" +"\n" +" public function update(#[RouteArgument('id')] int $id): ResponseInterface\n" +" {\n" +" $post = $this->postRepository->findByPK($id);\n" +" if ($post === null) {\n" +" // respond with 404\n" +" }\n" +"\n" +" if (!$this->canCurrentUserUpdatePost($post)) {\n" +" // respond with 403\n" +" }\n" +"\n" +" // continue with updating the post\n" +" }\n" +"\n" +" private function canCurrentUserUpdatePost(Post $post): bool\n" +" {\n" +" return $post->getAuthorId() === $this->user->getId() &&\n" +" $this->user->can('updatePost');\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "Behind the scenes, `Yiisoft\\User\\CurrentUser::can()` method calls `Yiisoft\\Access\\AccessCheckerInterface::userHasPermission()` so you should provide an implementation in dependency container in order for it to work." +msgstr "" + +#. type: Title ## +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "Role-based access control (RBAC)" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "Role-Based Access Control (RBAC) provides a simple yet powerful centralized access control. Please refer to the [Wikipedia](https://en.wikipedia.org/wiki/Role-based_access_control) for details about comparing RBAC with other more traditional access control schemes." +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "Yii implements a General Hierarchical RBAC, following the [NIST RBAC model](https://csrc.nist.gov/CSRC/media/Publications/conference-paper/2000/07/26/the-nist-model-for-role-based-access-control-towards-a-unified-/documents/sandhu-ferraiolo-kuhn-00.pdf)." +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "Using RBAC involves two parts of work. The first part is to build up the RBAC authorization data, and the second part is to use the authorization data to perform access check in places where it's necessary. Since RBAC implements `\\Yiisoft\\Access\\AccessCheckerInterface`, using it's similar to using any other implementation of an access checker." +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "To ease description next, there are some basic RBAC concepts first." +msgstr "" + +#. type: Title ### +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "Basic concepts" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "A role represents a collection of *permissions* (for example, creating posts, updating posts). You may assign a role to one or many users. To check if a user has a specified permission, you may check if the user has a role with that permission." +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "Associated with each role or permission, there may be a *rule*. A rule represents a piece of code that an access checker will execute to decide if the corresponding role or permission applies to the current user. For example, the \"update post\" permission may have a rule that checks if the current user is the post creator. During access checking, if the user is NOT the post creator, there's no \"update post\" permission." +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "Both roles and permissions are in a hierarchy. In particular, a role may consist of other roles or permissions. And a permission may consist of other permissions. Yii implements a *partial order* hierarchy which includes the more special *tree* hierarchy. While a role can contain a permission, it isn't `true` vice versa." +msgstr "" + +#. type: Title ### +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "Configuring RBAC" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "Yii RBAC requires storage to be provided." +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "One of the following storages could be installed:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/security/authorization.md +msgid "[PHP storage](https://github.com/yiisoft/rbac-php) - PHP file storage;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/security/authorization.md +msgid "[DB storage](https://github.com/yiisoft/rbac-db) - database storage based on [Yii DB](https://github.com/yiisoft/db);" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/security/authorization.md +msgid "[Cycle DB storage](https://github.com/yiisoft/rbac-cycle-db) - database storage based on [Cycle DBAL](https://github.com/cycle/database)." +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "You can also provide your own storage using the [yiisoft/rbac](https://github.com/yiisoft/rbac) package." +msgstr "" + +#. type: Title #### +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "Configuring RBAC with the [PHP storage](https://github.com/yiisoft/rbac-php)" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "Install [yiisoft/rbac-php](https://github.com/yiisoft/rbac-php) package:" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "composer require yiisoft/rbac-php\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "Before we set off to define authorization data and perform access checking, you need to configure the `Yiisoft\\Access\\AccessCheckerInterface` in dependency container:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "" +"use Yiisoft\\Rbac\\ItemsStorageInterface;\n" +"use Yiisoft\\Rbac\\AssignmentsStorageInterface;\n" +"use Yiisoft\\Rbac\\ManagerInterface;\n" +"use Yiisoft\\Rbac\\Php\\ItemsStorage;\n" +"use Yiisoft\\Rbac\\Php\\AssignmentsStorage;\n" +"use Yiisoft\\Access\\AccessCheckerInterface;\n" +"use Yiisoft\\User\\CurrentUser;\n" +"\n" +"return [\n" +" // ...\n" +" ItemsStorageInterface::class => [\n" +" 'class' => ItemsStorage::class,\n" +" '__construct()' => [\n" +" 'filePath' => $params['rbacItemsStorageFilePath']\n" +" ]\n" +" ],\n" +" AssignmentsStorageInterface::class => [\n" +" 'class' => AssignmentsStorage::class,\n" +" '__construct()' => [\n" +" 'filePath' => $params['rbacAssignmentsStorageFilePath']\n" +" ]\n" +" ],\n" +" AccessCheckerInterface::class => ManagerInterface::class,\n" +"\n" +" CurrentUser::class => [\n" +" 'withAccessChecker()' => [Reference::to(AccessCheckerInterface::class)]\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "`Yiisoft\\Rbac\\Manager` uses PHP script files to store authorization data. Make sure the directory and all the files in it are writable by the Web server process if you want to change permission hierarchy online." +msgstr "" + +#. type: Title #### +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "Configuring RBAC with the [DB storage](https://github.com/yiisoft/rbac-db)" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "Install [yiisoft/rbac-db](https://github.com/yiisoft/rbac-db) package:" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "composer require yiisoft/rbac-db\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "" +"Install one of the following drivers:\n" +" - [SQLite](https://github.com/yiisoft/db-sqlite) (minimal required version is 3.8.3)\n" +" - [MySQL](https://github.com/yiisoft/db-mysql)\n" +" - [PostgreSQL](https://github.com/yiisoft/db-pgsql)\n" +" - [Microsoft SQL Server](https://github.com/yiisoft/db-mssql)\n" +" - [Oracle](https://github.com/yiisoft/db-oracle)\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "[Configure connection](https://yiisoft.github.io/docs/guide/start/databases.html#configuring-connection)." +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "" +"use Yiisoft\\Rbac\\ItemsStorageInterface;\n" +"use Yiisoft\\Rbac\\AssignmentsStorageInterface;\n" +"use Yiisoft\\Rbac\\ManagerInterface;\n" +"use Yiisoft\\Rbac\\Db\\ItemsStorage;\n" +"use Yiisoft\\Rbac\\Db\\AssignmentsStorage;\n" +"use Yiisoft\\Access\\AccessCheckerInterface;\n" +"\n" +"return [\n" +" // ...\n" +" ItemsStorageInterface::class => ItemsStorage::class,\n" +" AssignmentsStorageInterface::class => AssignmentsStorage::class,\n" +" AccessCheckerInterface::class => ManagerInterface::class,\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "Add the RBAC [DB storage](https://github.com/yiisoft/rbac-db) migration paths to params.php:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "" +"return [\n" +" // ...\n" +" 'yiisoft/db-migration' => [\n" +" 'sourcePaths' => [\n" +" __DIR__ . '/../../vendor/yiisoft/rbac-db/migrations/items',\n" +" __DIR__ . '/../../vendor/yiisoft/rbac-db/migrations/assignments',\n" +" ],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "Apply migrations:" +msgstr "" + +#. type: Title ### +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "Building authorization data" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "Building authorization data is all about the following tasks:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/security/authorization.md +msgid "defining roles and permissions;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/security/authorization.md +msgid "establishing relations between roles and permissions;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/security/authorization.md +msgid "defining rules;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/security/authorization.md +msgid "associating rules with roles and permissions;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/security/authorization.md +msgid "assigning roles to users." +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "Depending on authorization flexibility requirements, you can do the tasks in different ways. If only developers change your permission hierarchy, you can use either migrations or a console command. Migration advantage is that you could execute it along with other migrations. The Console command advantage is that you have a good overview of the hierarchy in the code without a need to read many migrations." +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "Either way, in the end, you'll get the following RBAC hierarchy:" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "![Simple RBAC hierarchy](/images/guide/security/rbac-hierarchy-1.svg \"Simple RBAC hierarchy\")" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "In case you want to build permission hierarchy dynamically, you need a UI or a console command. The API used to build the hierarchy itself won't be different." +msgstr "" + +#. type: Title ### +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "Using console command" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "If your permission hierarchy doesn't change at all, and you have a fixed number of users, you can create a [console command](../tutorial/console-applications.md) that will initialize authorization data once via APIs offered by `\\Yiisoft\\Rbac\\ManagerInterface`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "" +"removeAll();\n" +"\n" +" $this->manager->addPermission((new Permission(RbacCommand::CREATE_POST_PERMISSION))->withDescription('Create a post'));\n" +" $this->manager->addPermission((new Permission(RbacCommand::UPDATE_POST_PERMISSION))->withDescription('Update post'));\n" +"\n" +" // add the \"author\" role and give this role the \"createPost\" permission\n" +" $this->manager->addRole(new Role(RbacCommand::ROLE_AUTHOR));\n" +" $this->manager->addChild(RbacCommand::ROLE_AUTHOR, RbacCommand::CREATE_POST_PERMISSION);\n" +"\n" +" // add the \"admin\" role and give this role the \"updatePost\" permission\n" +" // as well as the permissions of the \"author\" role\n" +" $this->manager->addRole(new Role(RbacCommand::ROLE_ADMIN));\n" +" $this->manager->addChild(RbacCommand::ROLE_ADMIN, RbacCommand::UPDATE_POST_PERMISSION);\n" +" $this->manager->addChild(RbacCommand::ROLE_ADMIN, RbacCommand::ROLE_AUTHOR);\n" +"\n" +" // Assign roles to users. 1 and 2 are IDs returned by IdentityInterface::getId()\n" +" // usually implemented in your User model.\n" +" $this->manager->assign(RbacCommand::ROLE_AUTHOR, 2);\n" +" $this->manager->assign(RbacCommand::ROLE_ADMIN, 1);\n" +"\n" +" return ExitCode::OK;\n" +" }\n" +"\n" +" private function removeAll(): void\n" +" {\n" +" $this->manager->revokeAll(2);\n" +" $this->manager->revokeAll(1);\n" +"\n" +" $this->manager->removeRole(RbacCommand::ROLE_ADMIN);\n" +" $this->manager->removeRole(RbacCommand::ROLE_AUTHOR);\n" +"\n" +" $this->manager->removePermission(RbacCommand::CREATE_POST_PERMISSION);\n" +" $this->manager->removePermission(RbacCommand::UPDATE_POST_PERMISSION);\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "Add the command to `config/console/commands.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "" +"return [ \n" +" // ...\n" +" 'rbac:init' => App\\Command\\RbacCommand::class\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "You can execute the command above from the console the following way:" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "./yii rbac:init\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "" +"> If you don't want to hardcode what users have certain roles, don't put `->assign()` calls into the command. Instead,\n" +" create either UI or console command to manage assignments.\n" +msgstr "" + +#. type: Title #### +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "Using migrations" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "**TODO**: finish it when migrations are implemented.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "You can use [migrations](../databases/db-migrations.md) to initialize and change hierarchy via APIs offered by `\\Yiisoft\\Rbac\\ManagerInterface`." +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "Create new migration using `./yii migrate:create init_rbac` then implement creating a hierarchy:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "" +"manager->addPermission((new Permission(M260112125812InitRbac::CREATE_POST_PERMISSION))->withDescription('Create a post'));\n" +" $this->manager->addPermission((new Permission(M260112125812InitRbac::UPDATE_POST_PERMISSION))->withDescription('Update post'));\n" +"\n" +" // add the \"author\" role and give this role the \"createPost\" permission\n" +" $this->manager->addRole(new Role(M260112125812InitRbac::ROLE_AUTHOR));\n" +" $this->manager->addChild(M260112125812InitRbac::ROLE_AUTHOR, M260112125812InitRbac::CREATE_POST_PERMISSION);\n" +"\n" +" // add the \"admin\" role and give this role the \"updatePost\" permission\n" +" // as well as the permissions of the \"author\" role\n" +" $this->manager->addRole(new Role(M260112125812InitRbac::ROLE_ADMIN));\n" +" $this->manager->addChild(M260112125812InitRbac::ROLE_ADMIN, M260112125812InitRbac::UPDATE_POST_PERMISSION);\n" +" $this->manager->addChild(M260112125812InitRbac::ROLE_ADMIN, M260112125812InitRbac::ROLE_AUTHOR);\n" +"\n" +" // Assign roles to users. 1 and 2 are IDs returned by IdentityInterface::getId()\n" +" // usually implemented in your User model.\n" +" $this->manager->assign(M260112125812InitRbac::ROLE_AUTHOR, 2);\n" +" $this->manager->assign(M260112125812InitRbac::ROLE_ADMIN, 1);\n" +" }\n" +"\n" +" public function down(MigrationBuilder $b): void\n" +" {\n" +" $this->manager->revokeAll(2);\n" +" $this->manager->revokeAll(1);\n" +"\n" +" $this->manager->removeRole(M260112125812InitRbac::ROLE_ADMIN);\n" +" $this->manager->removeRole(M260112125812InitRbac::ROLE_AUTHOR);\n" +"\n" +" $this->manager->removePermission(M260112125812InitRbac::CREATE_POST_PERMISSION);\n" +" $this->manager->removePermission(M260112125812InitRbac::UPDATE_POST_PERMISSION);\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "" +"> If you don't want to hardcode which users have certain roles, don't put `->assign()` calls in migrations. Instead,\n" +" create either UI or console command to manage assignments.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "You could apply migration by using `./yii migrate:up`." +msgstr "" + +#. type: Title ## +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "Assigning roles to users" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "TODO: update when signup implemented in demo / template.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "The author can create a post, admin can update the post and do everything the author can." +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "If your application allows user signup, you need to assign roles to these new users at once. For example, in order for all signed-up users to become authors in your advanced project template, you need to change `frontend\\models\\SignupForm::signup()` as follows:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "" +"public function signup()\n" +"{\n" +" if ($this->validate()) {\n" +" $user = new User();\n" +" $user->username = $this->username;\n" +" $user->email = $this->email;\n" +" $user->setPassword($this->password);\n" +" $user->generateAuthKey();\n" +" $user->save(false);\n" +"\n" +" // the following three lines were added:\n" +" $authorRole = $this->manager->getRole('author');\n" +" if ($authorRole !== null) {\n" +" $this->manager->assign($authorRole->getName(), $user->getId());\n" +" }\n" +"\n" +" return $user;\n" +" }\n" +"\n" +" return null;\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "For applications that require complex access control with dynamically updated authorization data (such as an admin panel), you many need to develop special user interfaces using APIs offered by `Yiisoft\\Rbac\\Manager`." +msgstr "" + +#. type: Title ### +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "Using rules" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "As aforementioned, rules add extra constraint to roles and permissions. A rule is a class extending from `\\Yiisoft\\Rbac\\Rule`. It must implement the `execute()` method. In the hierarchy you've created before, the author can't edit his own post. Let's fix it. First, you need a rule to verify that the user is the post author:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "" +"namespace App\\User\\Rbac;\n" +"\n" +"use Yiisoft\\Rbac\\Item;\n" +"use Yiisoft\\Rbac\\RuleContext;\n" +"use Yiisoft\\Rbac\\RuleInterface;\n" +"\n" +"/**\n" +" * Checks if the authorID matches user passed via params.\n" +" */\n" +"final readonly class AuthorRule implements RuleInterface\n" +"{\n" +" public function execute(?string $userId, Item $item, RuleContext $context): bool\n" +" {\n" +" $post = $context->getParameterValue('post');\n" +" return $post !== null && $post->getAuthorId() == $userId;\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "The rule checks if user created the `post`. Create a special permission `updateOwnPost` in the command you've used before:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "" +"use Yiisoft\\Rbac\\Permission;\n" +"use Yiisoft\\Rbac\\ManagerInterface;\n" +"\n" +"// add the \"updateOwnPost\" permission and associate the rule with it.\n" +"$updateOwnPost = (new Permission('updateOwnPost'))\n" +" ->withDescription('Update own post')\n" +" ->withRuleName(AuthorRule::class);\n" +"$this->manager->addPermission($updateOwnPost);\n" +"\n" +"// \"updateOwnPost\" will be used from \"updatePost\"\n" +"$this->manager->addChild($updateOwnPost->getName(), $updatePost->getName());\n" +"\n" +"// allow \"author\" to update their own posts\n" +"$this->manager->addChild($authorRole->getName(), $updateOwnPost->getName());\n" +"\n" +"// Remove this line since we don't want the AuthorRule to be applied to the 'admin' role\n" +"$this->manager->addChild('admin', 'author');\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "Now you've got the following hierarchy:" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "![RBAC hierarchy with a rule](/images/guide/security/rbac-hierarchy-2.svg \"RBAC hierarchy with a rule\")" +msgstr "" + +#. type: Title ### +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "Access check" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "The check is done similarly to how it was done in the first section of this guide:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "" +"namespace App\\Blog\\Post;\n" +"\n" +"use Yiisoft\\User\\CurrentUser;\n" +"use Yiisoft\\Router\\HydratorAttribute\\RouteArgument;\n" +"use Psr\\Http\\Message\\ResponseInterface;\n" +"\n" +"final readonly class PostController\n" +"{\n" +" public function __construct(\n" +" private PostRepositoryInterface $postRepository,\n" +" private CurrentUser $user\n" +" )\n" +" {\n" +" }\n" +"\n" +" public function update(#[RouteArgument('id')] int $id): ResponseInterface\n" +" {\n" +" $post = $this->postRepository->findByPK($id);\n" +" if ($post === null) {\n" +" // respond with 404\n" +" }\n" +"\n" +" if (!$this->canCurrentUserUpdatePost($post)) {\n" +" // respond with 403\n" +" }\n" +"\n" +" // continue with updating the post\n" +" }\n" +"\n" +" private function canCurrentUserUpdatePost(Post $post): bool\n" +" {\n" +" return $this->user->can('updatePost', ['post' => $post]);\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "The difference is that now checking for a user's own post is part of the RBAC." +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "If the current user is Jane with `ID=1` you are starting at `createPost` and trying to get to `Jane`:" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "![Access check](/images/guide/security/rbac-access-check-1.svg \"Access check\")" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "To check if a user can update a post, you need to pass an extra parameter that's required by `AuthorRule` described before:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "" +"if ($user->can('updatePost', ['post' => $post])) {\n" +" // update post\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "Here is what happens if the current user is John:" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "![Access check](/images/guide/security/rbac-access-check-2.svg \"Access check\")" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "" +"You're starting with the `updatePost` and going through `updateOwnPost`. To pass the access check, `AuthorRule`\n" +"should return `true` from its `execute()` method. The method receives its `$params` from the `can()` method call, so the value is\n" +"`['post' => $post]`.\n" +"If everything is fine, you will get to `author` assigned to John.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "In the case of Jane, it's a bit simpler since she is an admin:" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "![Access check](/images/guide/security/rbac-access-check-3.svg \"Access check\")" +msgstr "" + +#. type: Title ## +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "Implementing your own access checker" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/authorization.md +msgid "If RBAC doesn't suit your needs, you can implement your own access checker without changing the application code:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/security/authorization.md +#, no-wrap +msgid "" +"namespace App\\User;\n" +"\n" +"use \\Yiisoft\\Access\\AccessCheckerInterface;\n" +"\n" +"final readonly class AccessChecker implements AccessCheckerInterface\n" +"{\n" +" private const PERMISSIONS = [\n" +" [\n" +" 1 => ['editPost'],\n" +" 42 => ['editPost', 'deletePost'],\n" +" ],\n" +" ];\n" +"\n" +" public function userHasPermission($userId, string $permissionName, array $parameters = []) : bool\n" +" {\n" +" if (!array_key_exists($userId, self::PERMISSIONS)) {\n" +" return false;\n" +" }\n" +"\n" +" return in_array($permissionName, self::PERMISSIONS[$userId], true); \n" +" }\n" +"}\n" +msgstr "" diff --git a/_translations/po/pt-BR/guide_security_best-practices.md.po b/_translations/po/pt-BR/guide_security_best-practices.md.po new file mode 100644 index 00000000..de6fa0c6 --- /dev/null +++ b/_translations/po/pt-BR/guide_security_best-practices.md.po @@ -0,0 +1,496 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-06-29 17:10+0000\n" +"PO-Revision-Date: 2026-06-29 17:10+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md +#: ../src/guide/concept/autoloading.md ../src/guide/concept/di-container.md +#: ../src/guide/security/best-practices.md ../src/guide/structure/domain.md +#: ../src/guide/tutorial/console-applications.md +#: ../src/internals/004-namespaces.md ../src/internals/007-exceptions.md +#: ../src/internals/008-interfaces.md +#, no-wrap +msgid "References" +msgstr "" + +#. type: Title # +#: ../src/guide/security/best-practices.md +#, no-wrap +msgid "Security best practices" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/best-practices.md +msgid "Below, we'll review common security principles and describe how to avoid threats when developing applications using Yii. Most of these principles aren't unique to Yii alone but apply to website or software development in general, so you will also find links for further reading on the general ideas behind these." +msgstr "" + +#. type: Title ## +#: ../src/guide/security/best-practices.md +#, no-wrap +msgid "Basic principles" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/best-practices.md +msgid "There are two main principles when it comes to security no matter which application is being developed:" +msgstr "" + +#. type: Bullet: '1. ' +#: ../src/guide/security/best-practices.md +msgid "Filter input." +msgstr "" + +#. type: Bullet: '2. ' +#: ../src/guide/security/best-practices.md +msgid "Escape output." +msgstr "" + +#. type: Title ### +#: ../src/guide/security/best-practices.md +#, no-wrap +msgid "Filter input" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/best-practices.md +msgid "Filter input means that you should never consider input safe, and you should always check if the value you've got is actually among allowed ones. For example, if you know that you sort by three fields `title`, `created_at` and `status` and the field came from user input, it's better to check the value you've got right where you're receiving it. In terms of basic PHP, that would look like the following:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/security/best-practices.md +#, no-wrap +msgid "" +"$sortBy = $_GET['sort'];\n" +"if (!in_array($sortBy, ['title', 'created_at', 'status'])) {\n" +"\tthrow new \\InvalidArgumentException('Invalid sort value.');\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/best-practices.md +msgid "In Yii, most probably you'll use form validation to do similar checks." +msgstr "" + +#. type: Plain text +#: ../src/guide/security/best-practices.md +msgid "Further reading on the topic:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/security/best-practices.md +msgid "" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/security/best-practices.md +msgid "" +msgstr "" + +#. type: Title ### +#: ../src/guide/security/best-practices.md +#, no-wrap +msgid "Escape output" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/best-practices.md +#, no-wrap +msgid "" +"Escape output means that, depending on the context where you're using data,\n" +"you should prepend it with special characters to negate its special meaning.\n" +"In context of HTML you should escape `<`, `>` and alike special characters.\n" +"In the context of JavaScript or SQL, it will be a different set of characters.\n" +"Since it's error-prone to escape manually, Yii provides various tools to perform escaping in different contexts.\n" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/security/best-practices.md +msgid "" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/security/best-practices.md +msgid "" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/security/best-practices.md +msgid "" +msgstr "" + +#. type: Title ## +#: ../src/guide/security/best-practices.md +#, no-wrap +msgid "Avoiding SQL injections" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/best-practices.md +msgid "SQL injection happens when you form a query text by concatenating unescaped strings such as the following:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/security/best-practices.md +#, no-wrap +msgid "" +"$username = $_GET['username'];\n" +"$sql = \"SELECT * FROM user WHERE username = '$username'\";\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/best-practices.md +msgid "Instead of supplying correct username attacker could give your applications something like `'; DROP TABLE user; --`. The Resulting SQL will be the following:" +msgstr "" + +#. type: Fenced code block (sql) +#: ../src/guide/security/best-practices.md +#, no-wrap +msgid "SELECT * FROM user WHERE username = ''; DROP TABLE user; --'\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/best-practices.md +msgid "This is a valid query that will search for users with empty username and then will drop `user` table most probably resulting in a broken website and data loss (you've set up regular backups, right?)." +msgstr "" + +#. type: Plain text +#: ../src/guide/security/best-practices.md +msgid "Make sure to either use PDO prepared statements directly or ensure that the library you prefer is doing it. In the case of prepared statements, it's impossible to manipulate the query as was demonstrated above." +msgstr "" + +#. type: Plain text +#: ../src/guide/security/best-practices.md +msgid "If you use data to specify column names or table names, the best thing to do is to allow only a predefined set of values:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/security/best-practices.md +#, no-wrap +msgid "" +"function actionList($orderBy = null)\n" +"{\n" +" if (!in_array($orderBy, ['name', 'status'])) {\n" +" throw new \\InvalidArgumentException('Only name and status are allowed to order by.');\n" +" }\n" +" \n" +" // ...\n" +"}\n" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/security/best-practices.md +msgid "" +msgstr "" + +#. type: Title ## +#: ../src/guide/security/best-practices.md +#, no-wrap +msgid "Avoiding XSS" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/best-practices.md +#, no-wrap +msgid "" +"XSS or cross-site scripting happens when output isn't escaped properly when outputting HTML to the browser. For example,\n" +"if user can enter his name and instead of `Alexander` he enters ``, every page that\n" +"outputs username without escaping it will execute JavaScript `alert('Hello!');` resulting in alert box popping up\n" +"in a browser. Depending on the website instead of innocent alert, such a script could send messages using your name or even\n" +"perform bank transactions.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/best-practices.md +msgid "Avoiding XSS is quite easy in Yii. There are two cases:" +msgstr "" + +#. type: Bullet: '1. ' +#: ../src/guide/security/best-practices.md +msgid "You want to output data as plain text." +msgstr "" + +#. type: Bullet: '2. ' +#: ../src/guide/security/best-practices.md +msgid "You want to output data as HTML." +msgstr "" + +#. type: Plain text +#: ../src/guide/security/best-practices.md +msgid "If all you need is plain text, then escaping is as easy as the following:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/security/best-practices.md +#, no-wrap +msgid "\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/best-practices.md +msgid "If it should be HTML, you could get some help from [HtmlPurifier](http://htmlpurifier.org/). Note that HtmlPurifier processing is quite heavy, so consider adding caching." +msgstr "" + +#. type: Title ## +#: ../src/guide/security/best-practices.md +#, no-wrap +msgid "Avoiding CSRF" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/best-practices.md +msgid "CSRF is an abbreviation for cross-site request forgery. The idea is that many applications assume that requests coming from a user browser are made by the user themselves. This assumption could be false." +msgstr "" + +#. type: Plain text +#: ../src/guide/security/best-practices.md +#, no-wrap +msgid "" +"For example, the website `an.example.com` has a `/logout` URL that, when accessed using a simple GET request, logs the user out. As long\n" +"as it's requested by the user themselves everything is OK, but one day bad guys are somehow posting\n" +"`` on a forum the user often visits. The browser doesn't make any difference between\n" +"requesting an image or requesting a page so when the user opens a page with such a manipulated `` tag,\n" +"the browser will send the GET request to that URL and the user will be logged out from `an.example.com`.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/best-practices.md +#, no-wrap +msgid "" +"That's the basic idea of how a CSRF attack works. One can say that logging out a user isn't a serious thing.\n" +"However, this was just an example.\n" +"There are many more things one could do using this approach.\n" +"For example, triggering payments or changing data. Imagine that some website has a URL\n" +"`http://an.example.com/purse/transfer?to=anotherUser&amount=2000`. Accessing it using GET request, causes transfer of $2000\n" +"from an authorized user account to user `anotherUser`.\n" +"You know that the browser will always send a GET request to load an image,\n" +"so you can change the code to accept only POST requests on that URL.\n" +"Unfortunately, this won't save you, because an attacker\n" +"can put some JavaScript code instead of `` tag, which allows sending POST requests to that URL as well.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/best-practices.md +msgid "For this reason, Yii applies extra mechanisms to protect against CSRF attacks." +msgstr "" + +#. type: Plain text +#: ../src/guide/security/best-practices.md +msgid "To avoid CSRF, you should always:" +msgstr "" + +#. type: Bullet: '1. ' +#: ../src/guide/security/best-practices.md +msgid "Follow HTTP specification. GET shouldn't change the application state. See [RFC2616](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html) for more details." +msgstr "" + +#. type: Bullet: '2. ' +#: ../src/guide/security/best-practices.md +msgid "Keep Yii CSRF protection enabled." +msgstr "" + +#. type: Plain text +#: ../src/guide/security/best-practices.md +msgid "Yii has CSRF protection via `Yiisoft\\Csrf\\CsrfTokenMiddleware` from the [`yiisoft/csrf`](https://github.com/yiisoft/csrf) package. Make sure it's in your application middleware stack. For AJAX/SPA backends that use cookie-based authentication, the same package provides `Yiisoft\\Csrf\\CsrfHeaderMiddleware` — an alternative approach that relies on custom request headers and the CORS preflight mechanism instead of token-in-form." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/security/best-practices.md +msgid "" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/security/best-practices.md +msgid "" +msgstr "" + +#. type: Title ## +#: ../src/guide/security/best-practices.md +#, no-wrap +msgid "Avoiding file exposure" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/best-practices.md +#, no-wrap +msgid "" +"By default, server webroot is meant to be pointed to `public` directory where `index.php` is. In the case of shared hosting\n" +" environments, it could be impossible to achieve, so you'll end up with all the code, configs and logs in server webroot.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/best-practices.md +msgid "If so, remember to deny access to everything except `web`. If it's impossible, consider hosting your application elsewhere." +msgstr "" + +#. type: Title ## +#: ../src/guide/security/best-practices.md +#, no-wrap +msgid "Avoiding debug info and tools in production" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/best-practices.md +msgid "In debug mode, Yii shows quite verbose errors which are certainly helpful for development. The thing is that these verbose errors are handy for attacker as well since these could reveal database structure, configuration values and parts of your code." +msgstr "" + +#. type: Plain text +#: ../src/guide/security/best-practices.md +msgid "Never run production applications with debugger or Gii accessible to everyone. One could use it to get information about database structure, code and to simply rewrite code with what's generated by Gii." +msgstr "" + +#. type: Plain text +#: ../src/guide/security/best-practices.md +msgid "You should avoid the debug toolbar in production unless necessary. It exposes all the application and config details possible. If you absolutely need it, check twice you restrict access to your IP only." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/security/best-practices.md +msgid "" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/security/best-practices.md +msgid "" +msgstr "" + +#. type: Title ## +#: ../src/guide/security/best-practices.md +#, no-wrap +msgid "Using secure connection over TLS" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/best-practices.md +msgid "Yii provides features that rely on cookies and/or PHP sessions. These can be vulnerable in case your connection is compromised. The risk is reduced if the app uses secure connection via TLS (often referred to as [SSL](https://en.wikipedia.org/wiki/Transport_Layer_Security))." +msgstr "" + +#. type: Plain text +#: ../src/guide/security/best-practices.md +msgid "Nowadays, anyone can get a certificate for free and automatically update it thanks to [Let's Encrypt](https://letsencrypt.org/)." +msgstr "" + +#. type: Title ## +#: ../src/guide/security/best-practices.md +#, no-wrap +msgid "Secure server configuration" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/best-practices.md +msgid "The purpose of this section is to highlight risks that need to be considered when creating a server configuration for serving a Yii-based website. Besides the points covered here, there may be other security-related configuration options to be considered, so don't consider this section to be complete." +msgstr "" + +#. type: Title ### +#: ../src/guide/security/best-practices.md +#, no-wrap +msgid "Avoiding `Host`-header attacks" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/best-practices.md +msgid "If the webserver is configured to serve the same site independent of the value of the `Host` header, this information mayn't be reliable and [may be faked by the user sending the HTTP request](https://www.acunetix.com/vulnerabilities/web/host-header-attack). In such situations, you should fix your webserver configuration to serve the site only for specified host names." +msgstr "" + +#. type: Plain text +#: ../src/guide/security/best-practices.md +msgid "For more information about the server configuration, please refer to the documentation of your webserver:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/security/best-practices.md +msgid "Apache 2: " +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/security/best-practices.md +msgid "Nginx: " +msgstr "" + +#. type: Title ### +#: ../src/guide/security/best-practices.md +#, no-wrap +msgid "Configuring SSL peer validation" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/best-practices.md +msgid "There is a typical misconception about how to solve SSL certificate validation issues such as:" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/security/best-practices.md +#, no-wrap +msgid "cURL error 60: SSL certificate problem: unable to get local issuer certificate\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/best-practices.md +msgid "or" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/security/best-practices.md +#, no-wrap +msgid "stream_socket_enable_crypto(): SSL operation failed with code 1. OpenSSL Error messages: error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/best-practices.md +msgid "Many sources wrongly suggest disabling SSL peer verification. That shouldn't be ever done since it enables man-in-the middle type of attacks. Instead, PHP should be configured properly:" +msgstr "" + +#. type: Bullet: '1. ' +#: ../src/guide/security/best-practices.md +msgid "Download [https://curl.haxx.se/ca/cacert.pem](https://curl.haxx.se/ca/cacert.pem)." +msgstr "" + +#. type: Bullet: '2. ' +#: ../src/guide/security/best-practices.md +msgid "Add the following to your php.ini:" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/security/best-practices.md +#, no-wrap +msgid "" +" openssl.cafile=\"/path/to/cacert.pem\"\n" +" curl.cainfo=\"/path/to/cacert.pem\".\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/security/best-practices.md +msgid "Note that you should keep the file up to date." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/security/best-practices.md +msgid "[OWASP top 10](https://owasp.org/Top10/)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/security/best-practices.md +msgid "[The Basics of Web Application Security](https://martinfowler.com/articles/web-security-basics.html) by Martin Fowler" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/security/best-practices.md +msgid "[PHP manual: security](https://www.php.net/manual/en/security.php)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/security/best-practices.md +msgid "[Information security at STackExchange](https://security.stackexchange.com/)" +msgstr "" diff --git a/_translations/po/pt-BR/guide_security_cryptography.md.po b/_translations/po/pt-BR/guide_security_cryptography.md.po new file mode 100644 index 00000000..80a9abb0 --- /dev/null +++ b/_translations/po/pt-BR/guide_security_cryptography.md.po @@ -0,0 +1,232 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-04 08:34+0500\n" +"PO-Revision-Date: 2025-09-04 08:34+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: en/security/cryptography.md +#, no-wrap +msgid "Cryptography" +msgstr "" + +#. type: Plain text +#: en/security/cryptography.md +msgid "In this section, we'll review the following security aspects:" +msgstr "" + +#. type: Bullet: '- ' +#: en/security/cryptography.md +msgid "Generating random data" +msgstr "" + +#. type: Bullet: '- ' +#: en/security/cryptography.md +msgid "Encryption and Decryption" +msgstr "" + +#. type: Bullet: '- ' +#: en/security/cryptography.md +msgid "Confirming Data Integrity" +msgstr "" + +#. type: Plain text +#: en/security/cryptography.md +msgid "To use these features, you need to install `yiisoft/security` package:" +msgstr "" + +#. type: Fenced code block +#: en/security/cryptography.md +#, no-wrap +msgid "composer install yiisoft/security\n" +msgstr "" + +#. type: Title ## +#: en/security/cryptography.md +#, no-wrap +msgid "Generating pseudorandom data" +msgstr "" + +#. type: Plain text +#: en/security/cryptography.md +msgid "Pseudorandom data are useful in many situations. For example, when resetting a password via email, you need to generate a token, save it to the database, and send it via email to the end user, which in turn will allow them to prove ownership of that account. It's important that this token be unique and hard to guess, else there is a possibility that an attacker can predict the token's value and reset the user's password." +msgstr "" + +#. type: Plain text +#: en/security/cryptography.md +msgid "`\\Yiisoft\\Security\\Random` makes generating pseudorandom data simple:" +msgstr "" + +#. type: Fenced code block (php) +#: en/security/cryptography.md +#, no-wrap +msgid "$key = \\Yiisoft\\Security\\Random::string(42);\n" +msgstr "" + +#. type: Plain text +#: en/security/cryptography.md +msgid "The code above would give you a random string consisting of 42 characters." +msgstr "" + +#. type: Plain text +#: en/security/cryptography.md +msgid "If you need bytes or integers, use PHP functions directly:" +msgstr "" + +#. type: Bullet: '- ' +#: en/security/cryptography.md +msgid "`random_bytes()` for bytes. Note that the output may not be ASCII." +msgstr "" + +#. type: Bullet: '- ' +#: en/security/cryptography.md +msgid "`random_int()` for integers." +msgstr "" + +#. type: Title ## +#: en/security/cryptography.md +#, no-wrap +msgid "Encryption and decryption" +msgstr "" + +#. type: Plain text +#: en/security/cryptography.md +msgid "Yii provides convenient helper functions to encrypt/decrypt data using a secret key. The data is passed through the encryption function so that only the person who has the secret key will be able to decrypt it. For example, you need to store some information in your database, but you need to make sure only the user who has the secret key can view it (even if one compromises the application database):" +msgstr "" + +#. type: Fenced code block (php) +#: en/security/cryptography.md +#, no-wrap +msgid "" +"$encryptedData = (new \\Yiisoft\\Security\\Crypt())->encryptByPassword($data, $password);\n" +"\n" +"// save data to a database or another storage\n" +"saveData($encryptedData);\n" +msgstr "" + +#. type: Plain text +#: en/security/cryptography.md +msgid "Decrypting it:" +msgstr "" + +#. type: Fenced code block (php) +#: en/security/cryptography.md +#, no-wrap +msgid "" +"// collect encrypted data from a database or another storage\n" +"$encryptedData = getEncryptedData();\n" +"\n" +"$data = (new \\Yiisoft\\Security\\Crypt())->decryptByPassword($encryptedData, $password);\n" +msgstr "" + +#. type: Plain text +#: en/security/cryptography.md +msgid "You could use a key instead of a password:" +msgstr "" + +#. type: Fenced code block (php) +#: en/security/cryptography.md +#, no-wrap +msgid "" +"$encryptedData = (new \\Yiisoft\\Security\\Crypt())->encryptByKey($data, $key);\n" +"\n" +"// save data to a database or another storage\n" +"saveData($encryptedData);\n" +msgstr "" + +#. type: Fenced code block (php) +#: en/security/cryptography.md +#, no-wrap +msgid "" +"// collect encrypted data from a database or another storage\n" +"$encryptedData = getEncryptedData();\n" +"\n" +"$data = (new \\Yiisoft\\Security\\Crypt())->decryptByKey($encryptedData, $key);\n" +msgstr "" + +#. type: Title ## +#: en/security/cryptography.md +#, no-wrap +msgid "Confirming data integrity" +msgstr "" + +#. type: Plain text +#: en/security/cryptography.md +msgid "There are situations in which you need to verify that your data hasn't been tampered with by a third party or even corrupted in some way. Yii provides a way to confirm data integrity by MAC signing." +msgstr "" + +#. type: Plain text +#: en/security/cryptography.md +msgid "The `$key` should be present at both sending and receiving sides. On the sending side:" +msgstr "" + +#. type: Fenced code block (php) +#: en/security/cryptography.md +#, no-wrap +msgid "" +"$signedMessage = (new \\Yiisoft\\Security\\Mac())->sign($message, $key);\n" +"\n" +"sendMessage($signedMessage);\n" +msgstr "" + +#. type: Plain text +#: en/security/cryptography.md +msgid "On the receiving side:" +msgstr "" + +#. type: Fenced code block (php) +#: en/security/cryptography.md +#, no-wrap +msgid "" +"$signedMessage = receiveMessage($signedMessage);\n" +"\n" +"try {\n" +" $message = (new \\Yiisoft\\Security\\Mac())->getMessage($signedMessage, $key);\n" +"} catch (\\Yiisoft\\Security\\DataIsTamperedException $e) {\n" +" // data is tampered\n" +"}\n" +msgstr "" + +#. type: Title ## +#: en/security/cryptography.md +#, no-wrap +msgid "Masking token length" +msgstr "" + +#. type: Plain text +#: en/security/cryptography.md +msgid "Masking a token helps to mitigate a BREACH attack by randomizing how the token outputted on each request. A random mask is applied to the token, making the string always unique." +msgstr "" + +#. type: Plain text +#: en/security/cryptography.md +msgid "To mask a token:" +msgstr "" + +#. type: Fenced code block (php) +#: en/security/cryptography.md +#, no-wrap +msgid "$maskedToken = \\Yiisoft\\Security\\TokenMask::apply($token);\n" +msgstr "" + +#. type: Plain text +#: en/security/cryptography.md +msgid "To get the original value from the masked one:" +msgstr "" + +#. type: Fenced code block (php) +#: en/security/cryptography.md +#, no-wrap +msgid "$token = \\Yiisoft\\Security\\TokenMask::remove($maskedToken);\n" +msgstr "" diff --git a/_translations/po/pt-BR/guide_security_overview.md.po b/_translations/po/pt-BR/guide_security_overview.md.po new file mode 100644 index 00000000..c62e4ef3 --- /dev/null +++ b/_translations/po/pt-BR/guide_security_overview.md.po @@ -0,0 +1,67 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-04 11:19+0500\n" +"PO-Revision-Date: 2025-09-04 11:19+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: en/security/overview.md +#, no-wrap +msgid "Security" +msgstr "Segurança" + +#. type: Plain text +#: en/security/overview.md +msgid "Good security is vital to the health and success of any application. Unfortunately, many developers cut corners when it comes to security, either due to a lack of understanding or because implementation is too much of a hurdle. To make your Yii-powered application as secure as possible, Yii has included several excellent and easy-to-use security features." +msgstr "" + +#. type: Bullet: '* ' +#: en/security/overview.md +msgid "[Authentication](authentication.md)" +msgstr "" + +#. type: Bullet: '* ' +#: en/security/overview.md +msgid "[Authorization](authorization.md)" +msgstr "" + +#. type: Bullet: '* ' +#: en/security/overview.md +msgid "[Working with Passwords](passwords.md)" +msgstr "" + +#. type: Bullet: '* ' +#: en/security/overview.md +msgid "[Cryptography](cryptography.md)" +msgstr "" + +#. type: Bullet: '* ' +#: en/security/overview.md +msgid "[Best Practices](best-practices.md)" +msgstr "" + +#. type: Bullet: '* ' +#: en/security/overview.md +msgid "[Trusted request](trusted-request.md)" +msgstr "" + +#. type: Plain text +#: en/security/overview.md +msgid "See also:" +msgstr "" + +#. type: Bullet: '* ' +#: en/security/overview.md +msgid "[Views security](../views/view.md#security)" +msgstr "" diff --git a/_translations/po/pt-BR/guide_security_passwords.md.po b/_translations/po/pt-BR/guide_security_passwords.md.po new file mode 100644 index 00000000..a58513b1 --- /dev/null +++ b/_translations/po/pt-BR/guide_security_passwords.md.po @@ -0,0 +1,77 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-04 11:19+0500\n" +"PO-Revision-Date: 2025-09-04 11:19+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: en/security/passwords.md +#, no-wrap +msgid "Working with passwords" +msgstr "" + +#. type: Plain text +#: en/security/passwords.md +msgid "Most developers know that passwords can't be stored in plain text, but many developers believe it's still safe to hash passwords using `md5`, `sha1` or `sha256` etc. There was a time when using the aforementioned hashing algorithms was enough, but modern hardware makes it possible to reverse such hashes and even stronger ones using brute force attacks." +msgstr "" + +#. type: Plain text +#: en/security/passwords.md +msgid "To offer increased security for user passwords, even in the worst case scenario (when one breaches your application), you need to use a hashing algorithm that's resilient against brute force attacks. The best current choice is `argon2`. Yii `yiisoft/security` package make securely generate and verify hashes easier and ensure the best possible hashing solution used." +msgstr "" + +#. type: Plain text +#: en/security/passwords.md +msgid "To use it, you need to require the package first:" +msgstr "" + +#. type: Fenced code block +#: en/security/passwords.md +#, no-wrap +msgid "composer require yiisoft/security\n" +msgstr "" + +#. type: Plain text +#: en/security/passwords.md +msgid "When a user provides a password for the first time (e.g., upon registration), the password needs to be hashed and stored:" +msgstr "" + +#. type: Fenced code block (php) +#: en/security/passwords.md +#, no-wrap +msgid "" +"$hash = (new PasswordHasher())->hash($password);\n" +"\n" +"// save hash to a database or another storage\n" +"saveHash($hash); \n" +msgstr "" + +#. type: Plain text +#: en/security/passwords.md +msgid "When a user attempts to log in, the submitted password must be verified against the previously hashed and stored password:" +msgstr "" + +#. type: Fenced code block (php) +#: en/security/passwords.md +#, no-wrap +msgid "" +"// get hash from a database or another storage\n" +"$hash = getHash();\n" +"\n" +"if ((new PasswordHasher())->validate($password, $hash)) {\n" +" // all good, logging in user\n" +"} else {\n" +" // wrong password\n" +"}\n" +msgstr "" diff --git a/_translations/po/pt-BR/guide_security_trusted-request.md.po b/_translations/po/pt-BR/guide_security_trusted-request.md.po new file mode 100644 index 00000000..ab27eb83 --- /dev/null +++ b/_translations/po/pt-BR/guide_security_trusted-request.md.po @@ -0,0 +1,76 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-04 11:19+0500\n" +"PO-Revision-Date: 2025-09-04 11:19+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: en/security/trusted-request.md +#, no-wrap +msgid "Trusted request" +msgstr "" + +#. type: Plain text +#: en/security/trusted-request.md +msgid "Getting user information, like a host and IP address, will work out of the box in a normal setup where a single webserver is used to serve the website. If your Yii application, however, runs behind a reverse proxy, you need to add configuration to retrieve this information as the direct client is now the proxy, and the user IP address is passed to the Yii application by a header set by the proxy." +msgstr "" + +#. type: Plain text +#: en/security/trusted-request.md +msgid "You shouldn't blindly trust headers provided by proxies unless you explicitly trust the proxy. Yii supports configuring trusted proxies via the `Yiisoft\\Yii\\Web\\Middleware\\TrustedHostsNetworkResolver`. You should add it to [middleware stack](../structure/middleware.md)." +msgstr "" + +#. type: Plain text +#: en/security/trusted-request.md +msgid "The following is a request config for an application that runs behind an array of reverse proxies, which are located in the `10.0.2.0/24` IP network:" +msgstr "" + +#. type: Fenced code block (php) +#: en/security/trusted-request.md +#, no-wrap +msgid "" +"/** @var \\Yiisoft\\Yii\\Web\\Middleware\\TrustedHostsNetworkResolver $trustedHostsNetworkResolver */\n" +"$trustedHostsNetworkResolver = $trustedHostsNetworkResolver->withAddedTrustedHosts(['1.0.2.0/24']);\n" +msgstr "" + +#. type: Plain text +#: en/security/trusted-request.md +msgid "The proxy sends the IP in the `X-Forwarded-For` header by default, and the protocol (`http` or `https`) is in `X-Forwarded-Proto`." +msgstr "" + +#. type: Plain text +#: en/security/trusted-request.md +msgid "In case your proxies are using different headers, you can use the request configuration to adjust these, e.g.:" +msgstr "" + +#. type: Fenced code block (php) +#: en/security/trusted-request.md +#, no-wrap +msgid "" +"/** @var \\Yiisoft\\Yii\\Web\\Middleware\\TrustedHostsNetworkResolver $trustedHostsNetworkResolver */\n" +"$trustedHostsNetworkResolver = $trustedHostsNetworkResolver\n" +" ->withAddedTrustedHosts(\n" +" ['1.0.2.0/24'],\n" +" ['X-ProxyUser-Ip'],\n" +" ['Front-End-Https'],\n" +" [],\n" +" [],\n" +" ['X-Proxy-User-Ip']\n" +" );\n" +msgstr "" + +#. type: Plain text +#: en/security/trusted-request.md +msgid "With the above configuration, `X-ProxyUser-Ip` and `Front-End-Https` headers are used to get user IP and protocol." +msgstr "" diff --git a/_translations/po/pt-BR/guide_start_creating-project.md.po b/_translations/po/pt-BR/guide_start_creating-project.md.po new file mode 100644 index 00000000..7d8026fb --- /dev/null +++ b/_translations/po/pt-BR/guide_start_creating-project.md.po @@ -0,0 +1,154 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-04-07 16:34+0000\n" +"PO-Revision-Date: 2026-04-07 16:34+0000\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/guide/start/creating-project.md +#, no-wrap +msgid "Creating a project" +msgstr "Criando um projeto" + +#. type: Plain text +#: ../src/guide/start/creating-project.md +msgid "In this guide we'll provide commands for both [Docker](https://docs.docker.com/get-started/get-docker/) and the built-in dev server with everything installed locally." +msgstr "Neste guia mostramos os comandos tanto para o [Docker](https://docs.docker.com/get-started/get-docker/) quanto para o servidor de desenvolvimento embutido, com tudo instalado localmente." + +#. type: Plain text +#: ../src/guide/start/creating-project.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> If you want to use another web server,\n" +"> see [\"Configuring web servers\"](../../cookbook/configuring-webservers/general.md).\n" +msgstr "" +"> [!NOTE]\n" +"> Se você quiser usar outro servidor web,\n" +"> veja [\"Configurando servidores web\"](../../cookbook/configuring-webservers/general.md).\n" + +#. type: Plain text +#: ../src/guide/start/creating-project.md +msgid "We recommend starting with a project template that's a minimal working Yii project implementing some basic features. It can serve as a good starting point for your projects." +msgstr "Recomendamos começar com um template de projeto, que é um projeto Yii mínimo e funcional com alguns recursos básicos. Ele serve como um bom ponto de partida para os seus projetos." + +#. type: Plain text +#: ../src/guide/start/creating-project.md +msgid "You can create a new project from a template using the [Composer](https://getcomposer.org) package manager:" +msgstr "Você pode criar um novo projeto a partir de um template usando o gerenciador de pacotes [Composer](https://getcomposer.org):" + +#. type: Fenced code block (sh) +#: ../src/guide/start/creating-project.md +#, no-wrap +msgid "composer create-project yiisoft/app your_project\n" +msgstr "composer create-project yiisoft/app your_project\n" + +#. type: Plain text +#: ../src/guide/start/creating-project.md +msgid "Docker users can run the following commands:" +msgstr "Quem usa Docker pode rodar os seguintes comandos:" + +#. type: Fenced code block (sh) +#: ../src/guide/start/creating-project.md +#, no-wrap +msgid "" +"docker run --rm -it -v \"$(pwd):/app\" --user $(id -u):$(id -g) composer/composer create-project yiisoft/app your_project\n" +"sudo chown -R $(id -u):$(id -g) your_project\n" +"cd your_project\n" +"make composer update\n" +msgstr "" +"docker run --rm -it -v \"$(pwd):/app\" --user $(id -u):$(id -g) composer/composer create-project yiisoft/app your_project\n" +"sudo chown -R $(id -u):$(id -g) your_project\n" +"cd your_project\n" +"make composer update\n" + +#. type: Plain text +#: ../src/guide/start/creating-project.md +msgid "If you want development version instead of release one:" +msgstr "Se você quiser a versão de desenvolvimento em vez da versão de release:" + +#. type: Fenced code block (sh) +#: ../src/guide/start/creating-project.md +#, no-wrap +msgid "" +"git clone https://github.com/yiisoft/app.git --depth 1 your_project && \\\n" +"cd your_project && \\\n" +"rm -rf .git && \\\n" +"make composer update\n" +msgstr "" +"git clone https://github.com/yiisoft/app.git --depth 1 your_project && \\\n" +"cd your_project && \\\n" +"rm -rf .git && \\\n" +"make composer update\n" + +#. type: Plain text +#: ../src/guide/start/creating-project.md +msgid "This installs the latest stable version of the Yii project template in a directory named `your_project`. You can choose a different directory name if you want." +msgstr "Isso instala a versão estável mais recente do template de projeto do Yii em um diretório chamado `your_project`. Você pode escolher outro nome de diretório se quiser." + +#. type: Plain text +#: ../src/guide/start/creating-project.md +#, no-wrap +msgid "" +"> [!TIP]\n" +"> If you want to install the latest development version of Yii, you may add `--stability=dev` to the command.\n" +"> Don't use the development version of Yii for production because it may break your running code.\n" +msgstr "" +"> [!TIP]\n" +"> Se você quiser instalar a versão de desenvolvimento mais recente do Yii, pode adicionar `--stability=dev` ao comando.\n" +"> Não use a versão de desenvolvimento do Yii em produção, porque ela pode quebrar o seu código em execução.\n" + +#. type: Plain text +#: ../src/guide/start/creating-project.md +msgid "Go into the newly created directory, copy `.env.example` to `.env`, and run:" +msgstr "Entre no diretório recém-criado, copie `.env.example` para `.env` e rode:" + +#. type: Fenced code block (sh) +#: ../src/guide/start/creating-project.md +#, no-wrap +msgid "./yii serve --port=80\n" +msgstr "./yii serve --port=80\n" + +#. type: Plain text +#: ../src/guide/start/creating-project.md +msgid "For Docker users, run:" +msgstr "Se você usa Docker, rode:" + +#. type: Fenced code block (sh) +#: ../src/guide/start/creating-project.md +#, no-wrap +msgid "make up\n" +msgstr "make up\n" + +#. type: Plain text +#: ../src/guide/start/creating-project.md +msgid "Open your browser to the URL `http://localhost/`." +msgstr "Abra no navegador a URL `http://localhost/`." + +#. type: Plain text +#: ../src/guide/start/creating-project.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> To change the port for the built-in server, pass `--port` to `./yii serve`. For Docker, set `DEV_PORT`\n" +"> in `docker/.env`.\n" +msgstr "" +"> [!NOTE]\n" +"> Para mudar a porta do servidor embutido, passe `--port` para `./yii serve`. No Docker, defina `DEV_PORT`\n" +"> em `docker/.env`.\n" + +#. type: Plain text +#: ../src/guide/start/creating-project.md +msgid "![Successful Installation of Yii](/images/guide/start/app-installed.png)" +msgstr "![Instalação do Yii concluída com sucesso](/images/guide/start/app-installed.png)" diff --git a/_translations/po/pt-BR/guide_start_databases.md.po b/_translations/po/pt-BR/guide_start_databases.md.po new file mode 100644 index 00000000..5e705b67 --- /dev/null +++ b/_translations/po/pt-BR/guide_start_databases.md.po @@ -0,0 +1,1219 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-10-11 10:37+0000\n" +"PO-Revision-Date: 2026-10-11 10:37+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/cookbook/organizing-code/domain.md +#: ../src/cookbook/organizing-code/service.md ../src/guide/start/databases.md +#, no-wrap +msgid "Repository" +msgstr "" + +#. type: Fenced code block (sh) +#: ../src/guide/databases/db-migrations.md ../src/guide/start/databases.md +#, no-wrap +msgid "make composer require yiisoft/db-migration\n" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/databases/db-migrations.md ../src/guide/start/databases.md +#, no-wrap +msgid "" +"'yiisoft/db-migration' => [\n" +" 'newMigrationNamespace' => 'App\\\\Migration',\n" +" 'sourceNamespaces' => ['App\\\\Migration'],\n" +"],\n" +msgstr "" + +#. type: Title # +#: ../src/guide/index.md ../src/guide/start/databases.md +#, no-wrap +msgid "Working with databases" +msgstr "Trabalhando com bancos de dados" + +#. type: Title ### +#: ../src/guide/runtime/routing.md ../src/guide/start/databases.md +#, no-wrap +msgid "Routing" +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "Yii doesn't dictate using a particular database or storage for your application. There are many ways you can work with relational databases:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/start/databases.md +msgid "[Yii DB](https://github.com/yiisoft/db)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/start/databases.md +msgid "[Yii Active Record](https://github.com/yiisoft/active-record)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/start/databases.md +msgid "[Cycle](https://github.com/cycle) via [Yii Cycle package](https://github.com/yiisoft/yii-cycle)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/start/databases.md +msgid "[Doctrine](https://www.doctrine-project.org/) via [Yii Doctrine package](https://github.com/stargazer-team/yii-doctrine)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/start/databases.md +msgid "[PDO](https://www.php.net/manual/en/book.pdo.php)" +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "For non-relational ones, there are usually official libraries available:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/start/databases.md +msgid "[ElasticSearch](https://github.com/elastic/elasticsearch-php)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/start/databases.md +msgid "[Redis](https://redis.io/docs/latest/develop/clients/php/)" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/guide/start/databases.md ../src/internals/000-packages.md +msgid "..." +msgstr "" + +#. type: Title ## +#: ../src/guide/start/databases.md +#, no-wrap +msgid "Choosing a data access approach" +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +#, no-wrap +msgid "" +"Yii3 keeps database access in optional packages. A new application doesn't get a global `Yii::$app->db` component\n" +"or a built-in Active Record layer automatically, so choose the package and boundary that fit your application.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +#, no-wrap +msgid "" +"If you used Yii 2.0 database access layer, `yiisoft/db` is the closest Yii3 equivalent. It provides database\n" +"connections, commands, schema support, and a query builder. Instead of calling `Yii::$app->db`, configure a\n" +"connection as a service and inject `ConnectionInterface` where the database is needed.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "If you used Yii 2.0 Active Record, you can install `yiisoft/active-record`. It is useful when your model classes mostly describe tables and relations. For applications where Yii 2.0 Active Record classes also contain form validation, request scenarios, authorization checks, or business workflows, move those responsibilities to form models, services, and domain objects instead of putting them back into the record class." +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "For most application code, put a repository or query service between the action/service layer and storage:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/start/databases.md +msgid "actions and application services depend on repository methods such as `findOneBySlug()`, `findAll()`, `save()`, and `deleteBySlug()`;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/start/databases.md +msgid "the repository hides whether persistence is implemented with `yiisoft/db`, Active Record, Cycle, Doctrine, or another storage;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/start/databases.md +msgid "the repository is the place to map raw database rows or records to typed objects used by the rest of the code." +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "Small CRUD applications can start with a concrete repository class. Larger applications usually benefit from a repository interface in the domain or module and an implementation in the infrastructure layer." +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "In this guide, we will focus on working with relational databases using Yii DB. We'll use PostgreSQL to implement a simple CRUD (create read update delete)." +msgstr "" + +#. type: Title ## +#: ../src/guide/start/databases.md +#, no-wrap +msgid "Installing PostgreSQL" +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "You need to install PostgreSQL. If you prefer not to use Docker, [get the installer from official website](https://www.postgresql.org/download/), install it and create a database." +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "If you use Docker, it is a bit simpler. Modify `docker/dev/compose.yml`:" +msgstr "" + +#. type: Fenced code block (yaml) +#: ../src/guide/start/databases.md +#, no-wrap +msgid "" +"services:\n" +" app:\n" +" build:\n" +" dockerfile: docker/Dockerfile\n" +" context: ..\n" +" target: dev\n" +" args:\n" +" USER_ID: ${UID}\n" +" GROUP_ID: ${GID}\n" +" env_file:\n" +" - path: ./dev/.env\n" +" - path: ./dev/override.env\n" +" required: false\n" +" ports:\n" +" - \"${DEV_PORT:-80}:80\"\n" +" volumes:\n" +" - ../:/app\n" +" - ../runtime:/app/runtime\n" +" - caddy_data:/data\n" +" - caddy_config:/config\n" +" tty: true\n" +" depends_on:\n" +" db:\n" +" condition: service_healthy\n" +"\n" +" db:\n" +" image: postgres:${POSTGRES_VERSION:-18}-alpine\n" +" environment:\n" +" POSTGRES_DB: app\n" +" POSTGRES_PASSWORD: password\n" +" POSTGRES_USER: user\n" +" POSTGRES_INITDB_ARGS: \"--locale-provider=icu --icu-locale=und --encoding=UTF8\"\n" +" volumes:\n" +" - ../runtime/db:/var/lib/postgresql:rw\n" +" ports:\n" +" - \"${DEV_DB_PORT:-5432}:5432\"\n" +" healthcheck:\n" +" test: [ \"CMD-SHELL\", \"pg_isready -U user -d app\" ]\n" +" interval: 5s\n" +" timeout: 5s\n" +" retries: 5\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "Note that we add `depends_on` so application waits for database to be up." +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +#, no-wrap +msgid "" +"> [!IMPORTANT]\n" +"> Also, we'll need a `pdo_pgsql` extension to communicate with PostgreSQL. You can enable it locally in `php.ini`.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "If you use Docker, check `docker/Dockerfile` and add `pdo_pgsql` in `install-php-extensions` list:" +msgstr "" + +#. type: Fenced code block (dockerfile) +#: ../src/guide/start/databases.md +#, no-wrap +msgid "" +"RUN install-php-extensions \\\n" +" opcache \\\n" +" mbstring \\\n" +" intl \\\n" +" dom \\\n" +" ctype \\\n" +" curl \\\n" +" phar \\\n" +" openssl \\\n" +" xml \\\n" +" xmlwriter \\\n" +" simplexml \\\n" +" pdo \\\n" +" pdo_pgsql\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "Then rebuild PHP image with" +msgstr "" + +#. type: Fenced code block (sh) +#: ../src/guide/start/databases.md +#, no-wrap +msgid "make build && make down && make up\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/start/databases.md +#, no-wrap +msgid "Configuring connection" +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "Now that we have the database, it's time to define the connection." +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "First we need a package to be installed:" +msgstr "" + +#. type: Fenced code block (sh) +#: ../src/guide/start/databases.md +#, no-wrap +msgid "make composer require yiisoft/db-pgsql:2.*\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "Now create `config/common/di/db-pgsql.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/start/databases.md +#, no-wrap +msgid "" +" [\n" +" 'class' => Connection::class,\n" +" '__construct()' => [\n" +" 'driver' => new Driver(\n" +" $params['yiisoft/db-pgsql']['dsn'],\n" +" $params['yiisoft/db-pgsql']['username'],\n" +" $params['yiisoft/db-pgsql']['password'],\n" +" ),\n" +" ],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "And define parameters in `config/common/params.php`. For Docker that would be:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/start/databases.md +#, no-wrap +msgid "" +"use Yiisoft\\Db\\Pgsql\\Dsn;\n" +"\n" +"return [\n" +" // ...\n" +" 'yiisoft/db-pgsql' => [\n" +" 'dsn' => new Dsn('pgsql', 'db', 'app', '5432'),\n" +" 'username' => 'user',\n" +" 'password' => 'password',\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "`db` host is resolved automatically within the Docker network." +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "For local installation without Docker the host in Dsn would be `localhost`. You'll have to adjust the rest to match how you configured the database." +msgstr "" + +#. type: Title ### +#: ../src/guide/start/databases.md +#, no-wrap +msgid "Multiple database connections" +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "When the application works with several databases, keep `ConnectionInterface` for the primary connection and add a class alias for each named connection:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/start/databases.md +#, no-wrap +msgid "" +" MainDatabase::class,\n" +"\n" +" MainDatabase::class => [\n" +" 'class' => Connection::class,\n" +" '__construct()' => [\n" +" 'driver' => new Driver(\n" +" $params['app/db']['main']['dsn'],\n" +" $params['app/db']['main']['username'],\n" +" $params['app/db']['main']['password'],\n" +" ),\n" +" ],\n" +" ],\n" +"\n" +" AnalyticsDatabase::class => [\n" +" 'class' => Connection::class,\n" +" '__construct()' => [\n" +" 'driver' => new Driver(\n" +" $params['app/db']['analytics']['dsn'],\n" +" $params['app/db']['analytics']['username'],\n" +" $params['app/db']['analytics']['password'],\n" +" ),\n" +" ],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "The alias class names are used as service IDs and type hints. They don't need PHP files of their own." +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "Define matching parameters:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/start/databases.md +#, no-wrap +msgid "" +"use Yiisoft\\Db\\Pgsql\\Dsn;\n" +"\n" +"return [\n" +" // ...\n" +" 'app/db' => [\n" +" 'main' => [\n" +" 'dsn' => new Dsn('pgsql', 'db', 'app', '5432'),\n" +" 'username' => 'user',\n" +" 'password' => 'password',\n" +" ],\n" +" 'analytics' => [\n" +" 'dsn' => new Dsn('pgsql', 'analytics-db', 'analytics', '5432'),\n" +" 'username' => 'analytics_user',\n" +" 'password' => 'analytics_password',\n" +" ],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "Services that need the primary database can still depend on `ConnectionInterface`. Services that need another database should type-hint the corresponding alias:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/start/databases.md +#, no-wrap +msgid "" +"columnBuilder();\n" +"\n" +" $b->createTable('page', [\n" +" 'id' => $column::uuidPrimaryKey(),\n" +" 'title' => $column::string()->notNull(),\n" +" 'slug' => $column::string()->notNull()->unique(),\n" +" 'text' => $column::text()->notNull(),\n" +" 'created_at' => $column::dateTime(),\n" +" 'updated_at' => $column::dateTime(),\n" +" ]);\n" +" }\n" +"\n" +" public function down(MigrationBuilder $b): void\n" +" {\n" +" $b->dropTable('page');\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "The `M251102141707Page` name of the migration class is generated so replace the `Page` suffix with the actual migration name. The `M251102141707` prefix is needed to find and sort migrations in the order they were added." +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "Note that we use UUID as the primary key. We are going to generate these IDs ourselves instead of relying on database so we'll need an extra compose package for that." +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/start/databases.md +#, no-wrap +msgid "make composer require ramsey/uuid\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "While the storage space is a bit bigger than using int, the workflow with such IDs is beneficial. Since you generate the ID yourself so you can define a set of related data and save it in a single transaction. The entities that define this set of data in the code are often called an \"aggregate\"." +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "Apply the migration with `make yii migrate:up`." +msgstr "" + +#. type: Title ## +#: ../src/guide/start/databases.md +#, no-wrap +msgid "An entity" +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "Now that you have a table it is time to define an entity in the code. Create `src/Web/Page/Page.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/start/databases.md +#, no-wrap +msgid "" +"toSlug($title),\n" +" text: $text,\n" +" createdAt: $createdAt,\n" +" updatedAt: $updatedAt,\n" +" );\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "Now that we have an entity, we need a place for methods to save it, delete it, and select either a single page or multiple pages. This is the repository boundary described earlier: the rest of the application works with `Page` objects and doesn't need to know how they are stored." +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "Create `src/Web/Page/PageRepository.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/start/databases.md +#, no-wrap +msgid "" +" $page->id,\n" +" 'title' => $page->title,\n" +" 'slug' => $page->slug,\n" +" 'text' => $page->text,\n" +" 'created_at' => $page->createdAt,\n" +" 'updated_at' => $page->updatedAt,\n" +" ];\n" +"\n" +" if ($this->exists($page->id)) {\n" +" $this->connection->createCommand()->update('{{%page}}', $row, ['id' => $page->id])->execute();\n" +" } else {\n" +" $this->connection->createCommand()->insert('{{%page}}', $row)->execute();\n" +" }\n" +" }\n" +"\n" +" public function findOneBySlug(string $slug): ?Page\n" +" {\n" +" $query = $this->connection\n" +" ->select()\n" +" ->from('{{%page}}')\n" +" ->where('slug = :slug', ['slug' => $slug]);\n" +"\n" +" return $this->createPage($query->one());\n" +" }\n" +"\n" +" /**\n" +" * @return iterable\n" +" */\n" +" public function findAll(): iterable\n" +" {\n" +" $rows = $this->connection\n" +" ->select()\n" +" ->from('{{%page}}')\n" +" ->all();\n" +"\n" +" foreach ($rows as $row) {\n" +" yield $this->createPage($row);\n" +" }\n" +" }\n" +"\n" +" private function createPage(?array $row): ?Page\n" +" {\n" +" if ($row === null) {\n" +" return null;\n" +" }\n" +"\n" +" return Page::create(\n" +" id: $row['id'],\n" +" title: $row['title'],\n" +" text: $row['text'],\n" +" slug: $row['slug'],\n" +" createdAt: new DateTimeImmutable($row['created_at']),\n" +" updatedAt: new DateTimeImmutable($row['updated_at']),\n" +" );\n" +" }\n" +"\n" +" public function deleteBySlug(string $slug): void\n" +" {\n" +" $this->connection->createCommand()->delete(\n" +" '{{%page}}',\n" +" ['slug' => $slug],\n" +" )->execute();\n" +" }\n" +"\n" +" public function exists(string $id): bool\n" +" {\n" +" return $this->connection->createQuery()\n" +" ->from('{{%page}}')\n" +" ->where(['id' => $id])\n" +" ->exists();\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "In this repository there are both methods to get data and `save()` to do insert or update. DB returns raw data as arrays but our repository automatically creates entities from this raw data so later we operate typed data." +msgstr "" + +#. type: Title ## +#: ../src/guide/start/databases.md +#, no-wrap +msgid "Actions and routes" +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "We need some actions to:" +msgstr "" + +#. type: Bullet: '1. ' +#: ../src/guide/start/databases.md +msgid "List all pages." +msgstr "" + +#. type: Bullet: '2. ' +#: ../src/guide/start/databases.md +msgid "View a page." +msgstr "" + +#. type: Bullet: '3. ' +#: ../src/guide/start/databases.md +msgid "Delete a page." +msgstr "" + +#. type: Bullet: '4. ' +#: ../src/guide/start/databases.md +msgid "Create a page." +msgstr "" + +#. type: Bullet: '5. ' +#: ../src/guide/start/databases.md +msgid "Update a page." +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "Then we need routing for all these." +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "Let's tackle these one by one." +msgstr "" + +#. type: Title ### +#: ../src/guide/start/databases.md +#, no-wrap +msgid "List all pages" +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "Create `src/Web/Page/ListAction.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/start/databases.md +#, no-wrap +msgid "" +"viewRenderer->render(__DIR__ . '/list', [\n" +" 'pages' => $this->pageRepository->findAll(),\n" +" ]);\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "Define list view in `src/Web/Page/list.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/start/databases.md +#, no-wrap +msgid "" +" $pages */\n" +"/** @var UrlGeneratorInterface $urlGenerator */\n" +"?>\n" +"\n" +"
    \n" +" \n" +"
  • \n" +" title, $urlGenerator->generate('page/view', ['slug' => $page->slug])) ?>\n" +"
  • \n" +" \n" +"
\n" +"\n" +"generate('page/edit', ['slug' => 'new'])) ?>\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/start/databases.md +#, no-wrap +msgid "View a page" +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "Create `src/Web/Page/ViewAction.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/start/databases.md +#, no-wrap +msgid "" +"pageRepository->findOneBySlug($slug);\n" +" if ($page === null) {\n" +" return $this->responseFactory->createResponse(Status::NOT_FOUND);\n" +" }\n" +"\n" +" return $this->viewRenderer->render(__DIR__ . '/view', [\n" +" 'page' => $page,\n" +" ]);\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "Now, a template in `src/Web/Page/view.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/start/databases.md +#, no-wrap +msgid "" +"\n" +"\n" +"

generate('page/list')) ?> → title) ?>

\n" +"\n" +"

\n" +" text) ?>\n" +"

\n" +"\n" +"generate('page/edit', ['slug' => $page->slug])) ?> |\n" +"\n" +"\n" +"post($urlGenerator->generate('page/delete', ['slug' => $page->slug]))\n" +" ->csrf($csrf);\n" +"?>\n" +"open() ?>\n" +" \n" +"close() ?>\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "In this view we have a form that submits a request for page deletion. Handing it with `GET` is common as well, but it is very wrong. Since deletion changes data, it needs to be handled by one of the non-idempotent HTTP methods. We use POST and a form in our example, but it could be `DELETE` and async request made with JavaScript. The button could be later styled properly to look similar to the \"Edit\"." +msgstr "" + +#. type: Title ### +#: ../src/guide/start/databases.md +#, no-wrap +msgid "Delete a page" +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "Create `src/Web/Page/DeleteAction.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/start/databases.md +#, no-wrap +msgid "" +"pageRepository->deleteBySlug($slug);\n" +"\n" +" return $this->responseFactory\n" +" ->createResponse(Status::SEE_OTHER)\n" +" ->withHeader('Location', $this->urlGenerator->generate('page/list'));\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/start/databases.md +#, no-wrap +msgid "Create or update a page" +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "First of all, we need a form at `src/Web/Page/Form.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/start/databases.md +#, no-wrap +msgid "" +"findOneBySlug($slug);\n" +" if ($page === null) {\n" +" return $this->responseFactory->createResponse(Status::NOT_FOUND);\n" +" }\n" +"\n" +" $form->title = $page->title;\n" +" $form->text = $page->text;\n" +" }\n" +"\n" +" $this->formHydrator->populateFromPostAndValidate($form, $request);\n" +"\n" +" if ($form->isValid()) {\n" +" $id = $isNew ? Uuid::uuid7()->toString() : $page->id;\n" +"\n" +" $page = Page::create(\n" +" id: $id,\n" +" title: $form->title,\n" +" text: $form->text,\n" +" );\n" +"\n" +" $pageRepository->save($page);\n" +"\n" +" return $this->responseFactory\n" +" ->createResponse(Status::SEE_OTHER)\n" +" ->withHeader(\n" +" 'Location',\n" +" $this->urlGenerator->generate('page/view', ['slug' => $page->slug]),\n" +" );\n" +" }\n" +"\n" +" return $this->viewRenderer->render(__DIR__ . '/edit', [\n" +" 'form' => $form,\n" +" 'isNew' => $isNew,\n" +" 'slug' => $slug,\n" +" ]);\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +#, no-wrap +msgid "Note that `Uuid::uuid7()->toString()` won't work for MySQL and you'll need bytes instead, `Uuid::uuid7()->getBytes()`.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "In the above we use a special slug in the URL for new pages so the URL looks like `http://localhost/pages/new`. If the page isn't new, we pre-fill the form with the data from the database. Similar to how we did in [Working with forms](forms.md), we handle the form submission. After successful save we redirect to the page view." +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "Now, a template in `src/Web/Page/edit.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/start/databases.md +#, no-wrap +msgid "" +"post($urlGenerator->generate('page/edit', ['slug' => $slug]))\n" +" ->csrf($csrf);\n" +"?>\n" +"\n" +"open() ?>\n" +" required() ?>\n" +" required() ?>\n" +" \n" +"close() ?>\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "Adjust `config/common/routes.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/start/databases.md +#, no-wrap +msgid "" +"routes(\n" +" Route::get('/')\n" +" ->action(Web\\HomePage\\Action::class)\n" +" ->name('home'),\n" +" Route::methods([Method::GET, Method::POST], '/say')\n" +" ->action(Web\\Echo\\Action::class)\n" +" ->name('echo/say'),\n" +"\n" +" Group::create('/pages')->routes(\n" +" Route::get('')\n" +" ->action(Web\\Page\\ListAction::class)\n" +" ->name('page/list'),\n" +" Route::get('/{slug}')\n" +" ->action(Web\\Page\\ViewAction::class)\n" +" ->name('page/view'),\n" +" Route::methods([Method::GET, Method::POST], '/{slug}/edit')\n" +" ->action(Web\\Page\\EditAction::class)\n" +" ->name('page/edit'),\n" +" Route::post('/{slug}/delete')\n" +" ->action(Web\\Page\\DeleteAction::class)\n" +" ->name('page/delete'),\n" +" ),\n" +" ),\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "Note that we've grouped all page-related routes with a group under `/pages` prefix. That is a convenient way to both not to repeat yourself and add some extra middleware, such as authentication, to the whole group." +msgstr "" + +#. type: Title ## +#: ../src/guide/start/databases.md ../src/guide/start/hello.md +#, no-wrap +msgid "Trying it out" +msgstr "Testando" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "Now try it out by opening `http://localhost/pages` in your browser." +msgstr "" diff --git a/_translations/po/pt-BR/guide_start_demo-apps.md.po b/_translations/po/pt-BR/guide_start_demo-apps.md.po new file mode 100644 index 00000000..bbdb705c --- /dev/null +++ b/_translations/po/pt-BR/guide_start_demo-apps.md.po @@ -0,0 +1,60 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-06-05 10:18+0000\n" +"PO-Revision-Date: 2026-06-05 10:18+0000\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/guide/start/demo-apps.md +#, no-wrap +msgid "Demo Applications" +msgstr "Aplicações de demonstração" + +#. type: Plain text +#: ../src/guide/start/demo-apps.md +msgid "There are several demo applications that showcase different architectural approaches and framework capabilities." +msgstr "Existem várias aplicações de demonstração que mostram diferentes abordagens de arquitetura e recursos do framework." + +#. type: Plain text +#: ../src/guide/start/demo-apps.md +#, no-wrap +msgid "**[Demo Blog](https://github.com/yiisoft/demo-blog) — Layered DDD architecture**\n" +msgstr "**[Demo Blog](https://github.com/yiisoft/demo-blog) — Arquitetura DDD em camadas**\n" + +#. type: Plain text +#: ../src/guide/start/demo-apps.md +msgid "A blog application demonstrating a layered architecture following Domain-Driven Design (DDD) principles. This demo is a good starting point if you want to learn how to structure a Yii3 application with a clear separation of concerns between domain, application, and infrastructure layers." +msgstr "Uma aplicação de blog que demonstra uma arquitetura em camadas seguindo os princípios do Domain-Driven Design (DDD). Esta demo é um bom ponto de partida se você quer aprender a estruturar uma aplicação Yii3 com uma separação clara de responsabilidades entre as camadas de domínio, aplicação e infraestrutura." + +#. type: Plain text +#: ../src/guide/start/demo-apps.md +#, no-wrap +msgid "**[Demo Diary](https://github.com/yiisoft/demo-diary) — Vertical slices architecture**\n" +msgstr "**[Demo Diary](https://github.com/yiisoft/demo-diary) — Arquitetura de vertical slices**\n" + +#. type: Plain text +#: ../src/guide/start/demo-apps.md +msgid "A diary application built using the vertical slices architecture pattern. In this approach, each feature is implemented end-to-end rather than being split across horizontal layers, making it easier to add or modify features independently." +msgstr "Uma aplicação de diário construída com o padrão de arquitetura de vertical slices. Nessa abordagem, cada funcionalidade é implementada de ponta a ponta em vez de ser dividida em camadas horizontais, o que facilita adicionar ou modificar funcionalidades de forma independente." + +#. type: Plain text +#: ../src/guide/start/demo-apps.md +#, no-wrap +msgid "**[Demo Summarizer](https://github.com/yiisoft/demo-summarizer) — Large language model (LLM) document summarizer**\n" +msgstr "**[Demo Summarizer](https://github.com/yiisoft/demo-summarizer) — Resumidor de documentos com modelo de linguagem (LLM)**\n" + +#. type: Plain text +#: ../src/guide/start/demo-apps.md +msgid "A runnable Yii3 demo for uploading documents, extracting readable Markdown, summarizing content, and tracking processing progress." +msgstr "Uma demo executável do Yii3 para enviar documentos, extrair Markdown legível, resumir o conteúdo e acompanhar o progresso do processamento." diff --git a/_translations/po/pt-BR/guide_start_forms.md.po b/_translations/po/pt-BR/guide_start_forms.md.po new file mode 100644 index 00000000..442bc1db --- /dev/null +++ b/_translations/po/pt-BR/guide_start_forms.md.po @@ -0,0 +1,799 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-06-30 09:05+0000\n" +"PO-Revision-Date: 2026-06-30 09:05+0000\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md ../src/guide/start/forms.md ../src/guide/start/hello.md +#, no-wrap +msgid "Summary" +msgstr "Resumo" + +#. type: Title # +#: ../src/guide/start/forms.md +#, no-wrap +msgid "Working with forms" +msgstr "Trabalhando com formulários" + +#. type: Plain text +#: ../src/guide/start/forms.md +msgid "This section continues to improve on \"Saying Hello.\" Instead of using URL, you will now ask a user for a message via form." +msgstr "Esta seção continua a melhorar o \"Dizendo olá\". Em vez de usar a URL, agora você vai pedir a mensagem ao usuário por meio de um formulário." + +#. type: Plain text +#: ../src/guide/start/forms.md +msgid "Through this tutorial, you will learn how to:" +msgstr "Neste tutorial, você vai aprender a:" + +#. type: Bullet: '* ' +#: ../src/guide/start/forms.md +msgid "Create a form model to represent the data entered by a user through a form." +msgstr "Criar um form model para representar os dados que o usuário informa em um formulário." + +#. type: Bullet: '* ' +#: ../src/guide/start/forms.md +msgid "Declare rules to validate the data entered." +msgstr "Declarar regras para validar os dados informados." + +#. type: Bullet: '* ' +#: ../src/guide/start/forms.md +msgid "Build an HTML form in a view." +msgstr "Montar um formulário HTML em uma view." + +#. type: Title ## +#: ../src/guide/start/forms.md +#, no-wrap +msgid "Installing form package" +msgstr "Instalando o pacote de formulários" + +#. type: Plain text +#: ../src/guide/start/forms.md +msgid "To install form package, issue the following command in your application directory:" +msgstr "Para instalar o pacote de formulários, rode o seguinte comando no diretório da sua aplicação:" + +#. type: Fenced code block +#: ../src/guide/start/forms.md +#, no-wrap +msgid "composer require yiisoft/form-model\n" +msgstr "composer require yiisoft/form-model\n" + +#. type: Plain text +#: ../src/guide/start/forms.md +msgid "For Docker that would be:" +msgstr "No Docker, fica assim:" + +#. type: Fenced code block +#: ../src/guide/start/forms.md +#, no-wrap +msgid "make composer require yiisoft/form-model\n" +msgstr "make composer require yiisoft/form-model\n" + +#. type: Title ## +#: ../src/guide/start/forms.md +#, no-wrap +msgid "Creating a form" +msgstr "Criando um formulário" + +#. type: Plain text +#: ../src/guide/start/forms.md +msgid "The data to be requested from the user will be represented by a `Form` class as shown below and saved in the file `/src/Web/Echo/Form.php`:" +msgstr "Os dados que serão pedidos ao usuário ficam representados por uma classe `Form`, como mostrado abaixo, salva no arquivo `/src/Web/Echo/Form.php`:" + +#. type: Fenced code block (php) +#: ../src/guide/start/forms.md +#, no-wrap +msgid "" +" Note: Validation attributes are Yii Validator rules. For common checks, first look for an existing rule. If a field\n" +"> also needs application-specific validation, use `Callback` for that domain logic. With PHP attributes, use the `method`\n" +"> option because PHP attributes can't contain closures. For example, validate UUID syntax with `Uuid`, then add\n" +"> `#[Callback(method: 'validateUuidV7', skipOnError: true)]` only when your domain specifically requires UUID version 7.\n" +msgstr "" +"> Nota: os atributos de validação são regras do Yii Validator. Para verificações comuns, procure primeiro uma regra existente. Se um campo\n" +"> também precisar de validação específica da aplicação, use `Callback` para essa lógica de domínio. Com atributos PHP, use a opção `method`,\n" +"> porque atributos PHP não podem conter closures. Por exemplo, valide a sintaxe do UUID com `Uuid` e só então adicione\n" +"> `#[Callback(method: 'validateUuidV7', skipOnError: true)]` quando o seu domínio exigir especificamente UUID versão 7.\n" + +#. type: Fenced code block (php) +#: ../src/guide/start/forms.md +#, no-wrap +msgid "" +"use Yiisoft\\Validator\\Result;\n" +"use Yiisoft\\Validator\\Rule\\Callback;\n" +"use Yiisoft\\Validator\\Rule\\Uuid;\n" +"\n" +"#[Uuid(skipOnError: true)]\n" +"#[Callback(method: 'validateUuidV7', skipOnError: true)]\n" +"public string $id = '';\n" +"\n" +"private function validateUuidV7(mixed $value): Result\n" +"{\n" +" return \\App\\Support\\Uuid::isVersion7($value)\n" +" ? new Result()\n" +" : (new Result())->addError('ID must be a UUID version 7.');\n" +"}\n" +msgstr "" +"use Yiisoft\\Validator\\Result;\n" +"use Yiisoft\\Validator\\Rule\\Callback;\n" +"use Yiisoft\\Validator\\Rule\\Uuid;\n" +"\n" +"#[Uuid(skipOnError: true)]\n" +"#[Callback(method: 'validateUuidV7', skipOnError: true)]\n" +"public string $id = '';\n" +"\n" +"private function validateUuidV7(mixed $value): Result\n" +"{\n" +" return \\App\\Support\\Uuid::isVersion7($value)\n" +" ? new Result()\n" +" : (new Result())->addError('ID must be a UUID version 7.');\n" +"}\n" + +#. type: Plain text +#: ../src/guide/start/forms.md +msgid "The callback method returns a `Result`: return an empty result when the value is valid or add an error when it isn't. The method body can call any validation code your application already uses, such as `App\\Support\\Uuid::isValid($value, 'v7')`. See [Callback rule details](https://github.com/yiisoft/validator/blob/master/docs/guide/en/built-in-rules-callback.md) for full examples and available method signatures." +msgstr "O método de callback retorna um `Result`: retorne um resultado vazio quando o valor for válido ou adicione um erro quando não for. O corpo do método pode chamar qualquer código de validação que a sua aplicação já usa, como `App\\Support\\Uuid::isValid($value, 'v7')`. Veja os [detalhes da regra Callback](https://github.com/yiisoft/validator/blob/master/docs/guide/en/built-in-rules-callback.md) para exemplos completos e as assinaturas de método disponíveis." + +#. type: Plain text +#: ../src/guide/start/forms.md +msgid "For validation logic reused in several forms, create a custom Yii Validator rule and handler instead of copying callback methods. See the [custom rule guide](https://github.com/yiisoft/validator/blob/master/docs/guide/en/creating-custom-rules.md) for the rule/handler structure." +msgstr "Para uma lógica de validação reaproveitada em vários formulários, crie uma regra e um handler personalizados do Yii Validator em vez de copiar métodos de callback. Veja o [guia de regras personalizadas](https://github.com/yiisoft/validator/blob/master/docs/guide/en/creating-custom-rules.md) para a estrutura de regra/handler." + +#. type: Title ## +#: ../src/guide/start/forms.md +#, no-wrap +msgid "Custom validation" +msgstr "Validação personalizada" + +#. type: Plain text +#: ../src/guide/start/forms.md +msgid "Validation attributes are Yii Validator rules. For common checks, first look for an existing rule. For example, to validate a UUID string, use `Uuid`:" +msgstr "Os atributos de validação são regras do Yii Validator. Para verificações comuns, procure primeiro uma regra existente. Por exemplo, para validar uma string UUID, use `Uuid`:" + +#. type: Fenced code block (php) +#: ../src/guide/start/forms.md +#, no-wrap +msgid "" +"use Yiisoft\\FormModel\\FormModel;\n" +"use Yiisoft\\Validator\\Rule\\Uuid;\n" +"\n" +"final class Form extends FormModel\n" +"{\n" +" #[Uuid]\n" +" public string $id = '';\n" +"}\n" +msgstr "" +"use Yiisoft\\FormModel\\FormModel;\n" +"use Yiisoft\\Validator\\Rule\\Uuid;\n" +"\n" +"final class Form extends FormModel\n" +"{\n" +" #[Uuid]\n" +" public string $id = '';\n" +"}\n" + +#. type: Plain text +#: ../src/guide/start/forms.md +msgid "When a field needs application-specific validation that isn't covered by a built-in rule, use `Callback`. This is useful for one-off checks or for delegating to a domain/library method. With PHP attributes, use the `method` option because PHP attributes can't contain closures. For example, the following form validates a card number checksum:" +msgstr "Quando um campo precisa de uma validação específica da aplicação que nenhuma regra embutida cobre, use `Callback`. Isso é útil para verificações pontuais ou para delegar a um método do domínio ou de uma biblioteca. Com atributos PHP, use a opção `method`, porque atributos PHP não podem conter closures. Por exemplo, o formulário a seguir valida o dígito verificador de um número de cartão:" + +#. type: Fenced code block (php) +#: ../src/guide/start/forms.md +#, no-wrap +msgid "" +"addError('Card number must be a string.');\n" +" }\n" +"\n" +" $digits = str_replace([' ', '-'], '', $value);\n" +"\n" +" if ($digits === '' || !ctype_digit($digits)) {\n" +" return (new Result())->addError('Card number must contain digits only.');\n" +" }\n" +"\n" +" $sum = 0;\n" +" $double = false;\n" +"\n" +" foreach (array_reverse(str_split($digits)) as $digit) {\n" +" $number = (int) $digit;\n" +"\n" +" if ($double) {\n" +" $number *= 2;\n" +" if ($number > 9) {\n" +" $number -= 9;\n" +" }\n" +" }\n" +"\n" +" $sum += $number;\n" +" $double = !$double;\n" +" }\n" +"\n" +" if ($sum % 10 !== 0) {\n" +" return (new Result())->addError('Card number checksum is invalid.');\n" +" }\n" +"\n" +" return new Result();\n" +" }\n" +"}\n" +msgstr "" +"addError('Card number must be a string.');\n" +" }\n" +"\n" +" $digits = str_replace([' ', '-'], '', $value);\n" +"\n" +" if ($digits === '' || !ctype_digit($digits)) {\n" +" return (new Result())->addError('Card number must contain digits only.');\n" +" }\n" +"\n" +" $sum = 0;\n" +" $double = false;\n" +"\n" +" foreach (array_reverse(str_split($digits)) as $digit) {\n" +" $number = (int) $digit;\n" +"\n" +" if ($double) {\n" +" $number *= 2;\n" +" if ($number > 9) {\n" +" $number -= 9;\n" +" }\n" +" }\n" +"\n" +" $sum += $number;\n" +" $double = !$double;\n" +" }\n" +"\n" +" if ($sum % 10 !== 0) {\n" +" return (new Result())->addError('Card number checksum is invalid.');\n" +" }\n" +"\n" +" return new Result();\n" +" }\n" +"}\n" + +#. type: Plain text +#: ../src/guide/start/forms.md +msgid "The callback method returns a `Result`: return an empty result when the value is valid or add an error when it isn't. The method body can call any validation code your application already uses, such as `App\\Payment\\CardNumber::hasValidChecksum($value)`." +msgstr "O método de callback retorna um `Result`: retorne um resultado vazio quando o valor for válido ou adicione um erro quando não for. O corpo do método pode chamar qualquer código de validação que a sua aplicação já usa, como `App\\Payment\\CardNumber::hasValidChecksum($value)`." + +#. type: Title ## +#: ../src/guide/start/forms.md +#, no-wrap +msgid "Validating several fields together" +msgstr "Validando vários campos juntos" + +#. type: Plain text +#: ../src/guide/start/forms.md +msgid "Property attributes are enough when each field can be validated independently. When a rule depends on several fields, put a `Callback` rule on the form model class and attach an error to the field that should display it." +msgstr "Atributos nas propriedades bastam quando cada campo pode ser validado de forma independente. Quando uma regra depende de vários campos, coloque uma regra `Callback` na classe do form model e associe o erro ao campo que deve exibi-lo." + +#. type: Plain text +#: ../src/guide/start/forms.md +msgid "For example, a report filter may require the start date to be earlier than or equal to the end date:" +msgstr "Por exemplo, um filtro de relatório pode exigir que a data inicial seja anterior ou igual à data final:" + +#. type: Fenced code block (php) +#: ../src/guide/start/forms.md +#, no-wrap +msgid "" +"dateFrom === '' || $this->dateTo === '') {\n" +" return $result;\n" +" }\n" +"\n" +" $dateFrom = $this->parseDate($this->dateFrom);\n" +" $dateTo = $this->parseDate($this->dateTo);\n" +"\n" +" if ($dateFrom === null || $dateTo === null) {\n" +" return $result;\n" +" }\n" +"\n" +" if ($dateFrom > $dateTo) {\n" +" $result->addError('The start date must be earlier than or equal to the end date.', [], ['dateFrom']);\n" +" }\n" +"\n" +" return $result;\n" +" }\n" +"\n" +" private function parseDate(string $value): ?DateTimeImmutable\n" +" {\n" +" $date = DateTimeImmutable::createFromFormat('!Y-m-d', $value);\n" +" $errors = DateTimeImmutable::getLastErrors();\n" +"\n" +" if ($date === false || ($errors !== false && ($errors['warning_count'] > 0 || $errors['error_count'] > 0))) {\n" +" return null;\n" +" }\n" +"\n" +" return $date;\n" +" }\n" +"}\n" +msgstr "" +"dateFrom === '' || $this->dateTo === '') {\n" +" return $result;\n" +" }\n" +"\n" +" $dateFrom = $this->parseDate($this->dateFrom);\n" +" $dateTo = $this->parseDate($this->dateTo);\n" +"\n" +" if ($dateFrom === null || $dateTo === null) {\n" +" return $result;\n" +" }\n" +"\n" +" if ($dateFrom > $dateTo) {\n" +" $result->addError('The start date must be earlier than or equal to the end date.', [], ['dateFrom']);\n" +" }\n" +"\n" +" return $result;\n" +" }\n" +"\n" +" private function parseDate(string $value): ?DateTimeImmutable\n" +" {\n" +" $date = DateTimeImmutable::createFromFormat('!Y-m-d', $value);\n" +" $errors = DateTimeImmutable::getLastErrors();\n" +"\n" +" if ($date === false || ($errors !== false && ($errors['warning_count'] > 0 || $errors['error_count'] > 0))) {\n" +" return null;\n" +" }\n" +"\n" +" return $date;\n" +" }\n" +"}\n" + +#. type: Plain text +#: ../src/guide/start/forms.md +msgid "The class-level `Callback` receives the whole object as `$value`, but using `$this` is usually clearer in a form model method. Returning an empty `Result` means the cross-field rule passed. The third argument of `addError()` is the value path; `['dateFrom']` makes the error appear on the `dateFrom` field when rendering the form." +msgstr "O `Callback` no nível da classe recebe o objeto inteiro como `$value`, mas usar `$this` costuma ser mais claro em um método do form model. Retornar um `Result` vazio significa que a regra entre campos passou. O terceiro argumento de `addError()` é o caminho do valor; `['dateFrom']` faz o erro aparecer no campo `dateFrom` quando o formulário é renderizado." + +#. type: Title ## +#: ../src/guide/start/forms.md +#, no-wrap +msgid "Using the form " +msgstr "Usando o formulário" + +#. type: Plain text +#: ../src/guide/start/forms.md +msgid "Now that you have a form, use it in your action from \"[Saying Hello](hello.md)\"." +msgstr "Agora que você tem um formulário, use-o na sua action do \"[Dizendo olá](hello.md)\"." + +#. type: Plain text +#: ../src/guide/start/forms.md +msgid "Here's what you end up with in `/src/Web/Echo/Action.php`:" +msgstr "Este é o resultado final em `/src/Web/Echo/Action.php`:" + +#. type: Fenced code block (php) +#: ../src/guide/start/forms.md +#, no-wrap +msgid "" +"formHydrator->populateFromPostAndValidate($form, $request);\n" +"\n" +" return $this->viewRenderer->render(__DIR__ . '/template', [\n" +" 'form' => $form,\n" +" ]);\n" +" }\n" +"}\n" +msgstr "" +"formHydrator->populateFromPostAndValidate($form, $request);\n" +"\n" +" return $this->viewRenderer->render(__DIR__ . '/template', [\n" +" 'form' => $form,\n" +" ]);\n" +" }\n" +"}\n" + +#. type: Plain text +#: ../src/guide/start/forms.md +msgid "Instead of reading from route, you fill your form from request's POST data and validate it with the help of `FormHydrator`. Next you pass the form to the view." +msgstr "Em vez de ler da rota, você preenche o formulário com os dados POST da requisição e o valida com a ajuda do `FormHydrator`. Depois, passa o formulário para a view." + +#. type: Plain text +#: ../src/guide/start/forms.md +msgid "For the form to function we need to allow both GET to render the form and POST to send the data. Adjust your route in `config/common/routes.php`:" +msgstr "Para o formulário funcionar, precisamos permitir tanto GET, para renderizar o formulário, quanto POST, para enviar os dados. Ajuste a sua rota em `config/common/routes.php`:" + +#. type: Fenced code block (php) +#: ../src/guide/start/forms.md +#, no-wrap +msgid "" +"routes(\n" +" Route::get('/')\n" +" ->action(Web\\HomePage\\Action::class)\n" +" ->name('home'),\n" +" Route::methods([Method::GET, Method::POST], '/say')\n" +" ->action(Web\\Echo\\Action::class)\n" +" ->name('echo/say'),\n" +" ),\n" +"];\n" +msgstr "" +"routes(\n" +" Route::get('/')\n" +" ->action(Web\\HomePage\\Action::class)\n" +" ->name('home'),\n" +" Route::methods([Method::GET, Method::POST], '/say')\n" +" ->action(Web\\Echo\\Action::class)\n" +" ->name('echo/say'),\n" +" ),\n" +"];\n" + +#. type: Title ## +#: ../src/guide/start/forms.md +#, no-wrap +msgid "Adjusting view" +msgstr "Ajustando a view" + +#. type: Plain text +#: ../src/guide/start/forms.md +msgid "To render a form, you need to change your view, `src/Web/Echo/template.php`:" +msgstr "Para renderizar um formulário, você precisa alterar a sua view, `src/Web/Echo/template.php`:" + +#. type: Fenced code block (php) +#: ../src/guide/start/forms.md +#, no-wrap +msgid "" +"post($urlGenerator->generate('echo/say'))\n" +" ->csrf($csrf);\n" +"?>\n" +"\n" +"open() ?>\n" +" required() ?>\n" +" \n" +"close() ?>\n" +"\n" +"isValid()): ?>\n" +" Echo said: message) ?>\n" +"\n" +msgstr "" +"post($urlGenerator->generate('echo/say'))\n" +" ->csrf($csrf);\n" +"?>\n" +"\n" +"open() ?>\n" +" required() ?>\n" +" \n" +"close() ?>\n" +"\n" +"isValid()): ?>\n" +" Echo said: message) ?>\n" +"\n" + +#. type: Plain text +#: ../src/guide/start/forms.md +msgid "If the form is valid, you display a message. The rest initializes and renders the form." +msgstr "Se o formulário for válido, você exibe uma mensagem. O restante inicializa e renderiza o formulário." + +#. type: Plain text +#: ../src/guide/start/forms.md +msgid "First, you initialize `$htmlForm` with the POST type and the action URL generated with the help from the URL generator. You can access it as `$urlGenerator` in all views. You also need to pass the CSRF token to the form, which is also available in every view as `$csrf` thanks to the view injections listed in `config/common/params.php`:" +msgstr "Primeiro, você inicializa `$htmlForm` com o tipo POST e a URL da action gerada com a ajuda do gerador de URLs. Você pode acessá-lo como `$urlGenerator` em todas as views. Também precisa passar o token CSRF para o formulário, que também está disponível em toda view como `$csrf` graças às view injections listadas em `config/common/params.php`:" + +#. type: Fenced code block (php) +#: ../src/guide/start/forms.md +#, no-wrap +msgid "" +"'yiisoft/yii-view-renderer' => [\n" +" 'injections' => [\n" +" Reference::to(CsrfViewInjection::class),\n" +" ],\n" +"],\n" +msgstr "" +"'yiisoft/yii-view-renderer' => [\n" +" 'injections' => [\n" +" Reference::to(CsrfViewInjection::class),\n" +" ],\n" +"],\n" + +#. type: Plain text +#: ../src/guide/start/forms.md +msgid "The template renders the CSRF token value as a hidden input to ensure that the request originates from the form page and not from another website. It will be submitted along with POST form data. Omitting it would result in [HTTP response code 422](https://tools.ietf.org/html/rfc4918#section-11.2)." +msgstr "O template renderiza o valor do token CSRF como um input oculto para garantir que a requisição vem da página do formulário e não de outro site. Ele é enviado junto com os dados POST do formulário. Sem ele, o resultado seria o [código de resposta HTTP 422](https://tools.ietf.org/html/rfc4918#section-11.2)." + +#. type: Plain text +#: ../src/guide/start/forms.md +msgid "You use `Field::text()` to output \"message\" field, so it takes care about filling the value, escaping it, rendering field label and validation errors." +msgstr "Você usa `Field::text()` para exibir o campo \"message\", então ele cuida de preencher o valor, escapá-lo e renderizar o label do campo e os erros de validação." + +#. type: Plain text +#: ../src/guide/start/forms.md +msgid "Now, in case you submit an empty message, you will get a validation error: \"The message to be echoed must contain at least 2 characters.\"" +msgstr "Agora, se você enviar uma mensagem vazia, vai receber um erro de validação: \"The message to be echoed must contain at least 2 characters.\"" + +#. type: Title ## +#: ../src/guide/start/forms.md +#, no-wrap +msgid "Trying it Out" +msgstr "Testando" + +#. type: Plain text +#: ../src/guide/start/forms.md +msgid "To see how it works, use your browser to access the following URL:" +msgstr "Para ver como funciona, acesse a seguinte URL no navegador:" + +#. type: Fenced code block +#: ../src/guide/start/forms.md +#, no-wrap +msgid "http://localhost:8080/say\n" +msgstr "http://localhost:8080/say\n" + +#. type: Plain text +#: ../src/guide/start/forms.md +msgid "You will see a page with a form input field and a label that indicates what data to enter. Also, the form has a \"submit\" button labeled \"Say\". If you click the \"submit\" button without entering anything, you will see that the field is required. If you enter a single character, the form displays an error message next to the problematic input field." +msgstr "Você vai ver uma página com um campo de formulário e um label indicando qual dado informar. O formulário também tem um botão \"submit\" com o texto \"Say\". Se você clicar no botão \"submit\" sem digitar nada, vai ver que o campo é obrigatório. Se digitar um único caractere, o formulário mostra uma mensagem de erro ao lado do campo com problema." + +#. type: Plain text +#: ../src/guide/start/forms.md +msgid "![Form with a validation error](/images/guide/start/form-error.png)" +msgstr "![Formulário com erro de validação](/images/guide/start/form-error.png)" + +#. type: Plain text +#: ../src/guide/start/forms.md +msgid "After you enter a valid message and click the \"submit\" button, the page echoes the data that you entered." +msgstr "Depois de digitar uma mensagem válida e clicar no botão \"submit\", a página mostra de volta os dados que você digitou." + +#. type: Plain text +#: ../src/guide/start/forms.md +msgid "![Form with a success message](/images/guide/start/form-success.png)" +msgstr "![Formulário com mensagem de sucesso](/images/guide/start/form-success.png)" + +#. type: Plain text +#: ../src/guide/start/forms.md +msgid "In this section of the guide, you've learned how to create a form model class to represent the user data and validate said data." +msgstr "Nesta seção do guia, você aprendeu a criar uma classe de form model para representar os dados do usuário e validar esses dados." + +#. type: Plain text +#: ../src/guide/start/forms.md +msgid "You've also learned how to get data from users and how to display data back in the browser. This is a task that could take you a lot of time when developing an application, but Yii provides powerful widgets to make this task easy." +msgstr "Você também aprendeu a receber dados dos usuários e a exibi-los de volta no navegador. Essa é uma tarefa que pode tomar muito tempo no desenvolvimento de uma aplicação, mas o Yii oferece widgets poderosos que a tornam fácil." + +#. type: Plain text +#: ../src/guide/start/forms.md +msgid "In the next section, you will learn how to work with databases, which are needed in nearly every application." +msgstr "Na próxima seção, você vai aprender a trabalhar com bancos de dados, que são necessários em quase toda aplicação." diff --git a/_translations/po/pt-BR/guide_start_gii.md.po b/_translations/po/pt-BR/guide_start_gii.md.po new file mode 100644 index 00000000..7399c8e6 --- /dev/null +++ b/_translations/po/pt-BR/guide_start_gii.md.po @@ -0,0 +1,32 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-03-06 12:40+0000\n" +"PO-Revision-Date: 2026-03-06 12:40+0000\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/guide/start/gii.md +#, no-wrap +msgid "Generating code with Gii" +msgstr "Gerando código com o Gii" + +#. type: Plain text +#: ../src/guide/start/gii.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> Gii is under development and will be available later.\n" +msgstr "" +"> [!NOTE]\n" +"> O Gii está em desenvolvimento e vai ficar disponível mais tarde.\n" diff --git a/_translations/po/pt-BR/guide_start_hello.md.po b/_translations/po/pt-BR/guide_start_hello.md.po new file mode 100644 index 00000000..ae2d01c8 --- /dev/null +++ b/_translations/po/pt-BR/guide_start_hello.md.po @@ -0,0 +1,362 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-06-05 20:33+0000\n" +"PO-Revision-Date: 2026-06-05 20:33+0000\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md ../src/guide/start/forms.md ../src/guide/start/hello.md +#, no-wrap +msgid "Summary" +msgstr "Resumo" + +#. type: Title ## +#: ../src/guide/start/databases.md ../src/guide/start/hello.md +#, no-wrap +msgid "Trying it out" +msgstr "Testando" + +#. type: Title # +#: ../src/guide/start/hello.md +#, no-wrap +msgid "Saying hello" +msgstr "Dizendo olá" + +#. type: Plain text +#: ../src/guide/start/hello.md +msgid "This section describes how to create a new \"Hello\" page in your application. It's a simple page that will echo back whatever you pass to it or, if nothing passed, will just say \"Hello!\"." +msgstr "Esta seção descreve como criar uma nova página \"Hello\" na sua aplicação. É uma página simples que devolve o que você passar para ela ou, se nada for passado, apenas diz \"Hello!\"." + +#. type: Plain text +#: ../src/guide/start/hello.md +msgid "To achieve this goal, you will define a route and create [a handler](../structure/handler.md) that does the job and forms the response. Then you will improve it to use [view](../views/view.md) for building the response." +msgstr "Para isso, você vai definir uma rota e criar [um handler](../structure/handler.md) que faz o trabalho e monta a resposta. Depois, vai melhorá-lo para usar uma [view](../views/view.md) na construção da resposta." + +#. type: Plain text +#: ../src/guide/start/hello.md +msgid "Through this tutorial, you will learn three things:" +msgstr "Neste tutorial, você vai aprender três coisas:" + +#. type: Bullet: '1. ' +#: ../src/guide/start/hello.md +msgid "How to create a handler to respond to a request." +msgstr "Como criar um handler para responder a uma requisição." + +#. type: Bullet: '2. ' +#: ../src/guide/start/hello.md +msgid "How to map URL to the handler." +msgstr "Como mapear uma URL para o handler." + +#. type: Bullet: '3. ' +#: ../src/guide/start/hello.md +msgid "How to use [view](../views/view.md) to compose the response's content." +msgstr "Como usar uma [view](../views/view.md) para compor o conteúdo da resposta." + +#. type: Title ## +#: ../src/guide/start/hello.md +#, no-wrap +msgid "Creating a handler" +msgstr "Criando um handler" + +#. type: Plain text +#: ../src/guide/start/hello.md +msgid "For the \"Hello\" task, you will create a handler class that reads a `message` parameter from the request and displays that message back to the user. If the request doesn't provide a `message` parameter, the action will display the default \"Hello\" message." +msgstr "Para a tarefa \"Hello\", você vai criar uma classe handler que lê o parâmetro `message` da requisição e mostra essa mensagem de volta para o usuário. Se a requisição não trouxer o parâmetro `message`, a action mostra a mensagem padrão \"Hello\"." + +#. type: Plain text +#: ../src/guide/start/hello.md +msgid "Create `src/Web/Echo/Action.php`:" +msgstr "Crie `src/Web/Echo/Action.php`:" + +#. type: Fenced code block (php) +#: ../src/guide/start/hello.md +#, no-wrap +msgid "" +"responseFactory->createResponse();\n" +" $response->getBody()->write('The message is: ' . Html::encode($message));\n" +" return $response;\n" +" }\n" +"}\n" +msgstr "" +"responseFactory->createResponse();\n" +" $response->getBody()->write('The message is: ' . Html::encode($message));\n" +" return $response;\n" +" }\n" +"}\n" + +#. type: Plain text +#: ../src/guide/start/hello.md +msgid "In your example, the `__invoke` method receives the `$message` parameter that with the help of `RouteArgument` attribute gets the message from URL. The value defaults to `\"Hello!\"`. If the request is made to `/say/Goodbye`, the action assigns the value \"Goodbye\" to the `$message` variable." +msgstr "No exemplo, o método `__invoke` recebe o parâmetro `$message`, que, com a ajuda do atributo `RouteArgument`, pega a mensagem da URL. O valor padrão é `\"Hello!\"`. Se a requisição for feita para `/say/Goodbye`, a action atribui o valor \"Goodbye\" à variável `$message`." + +#. type: Plain text +#: ../src/guide/start/hello.md +msgid "The application passes the response through the [middleware stack](../structure/middleware.md) to the emitter that outputs the response to the end user." +msgstr "A aplicação passa a resposta pela [pilha de middlewares](../structure/middleware.md) até o emitter, que envia a resposta ao usuário final." + +#. type: Title ## +#: ../src/guide/start/hello.md +#, no-wrap +msgid "Configuring router" +msgstr "Configurando o router" + +#. type: Plain text +#: ../src/guide/start/hello.md +msgid "Now, to map your handler to URL, you need to add a route in `config/common/routes.php`:" +msgstr "Agora, para mapear o handler para uma URL, você precisa adicionar uma rota em `config/common/routes.php`:" + +#. type: Fenced code block (php) +#: ../src/guide/start/hello.md +#, no-wrap +msgid "" +"routes(\n" +" Route::get('/')\n" +" ->action(Web\\HomePage\\Action::class)\n" +" ->name('home'),\n" +" Route::get('/say[/{message}]')\n" +" ->action(Web\\Echo\\Action::class)\n" +" ->name('echo/say'),\n" +" ),\n" +"];\n" +msgstr "" +"routes(\n" +" Route::get('/')\n" +" ->action(Web\\HomePage\\Action::class)\n" +" ->name('home'),\n" +" Route::get('/say[/{message}]')\n" +" ->action(Web\\Echo\\Action::class)\n" +" ->name('echo/say'),\n" +" ),\n" +"];\n" + +#. type: Plain text +#: ../src/guide/start/hello.md +msgid "In the above, you map the `/say[/{message}]` pattern to `\\App\\Web\\Echo\\Action`. For a request, the router creates an instance and calls the `__invoke()` method. The `{message}` part of the pattern writes anything specified in this place to the `message` route argument. `[]` marks this part of the pattern as optional." +msgstr "Acima, você mapeia o padrão `/say[/{message}]` para `\\App\\Web\\Echo\\Action`. A cada requisição, o router cria uma instância e chama o método `__invoke()`. A parte `{message}` do padrão grava o que for informado nessa posição no argumento de rota `message`. `[]` marca essa parte do padrão como opcional." + +#. type: Plain text +#: ../src/guide/start/hello.md +msgid "You also give a `echo/say` name to this route to be able to generate URLs pointing to it." +msgstr "Você também dá o nome `echo/say` a essa rota para poder gerar URLs que apontem para ela." + +#. type: Plain text +#: ../src/guide/start/hello.md +msgid "After creating the action and the view open `http://localhost/say/Hello+World` in your browser." +msgstr "Depois de criar a action e a view, abra `http://localhost/say/Hello+World` no navegador." + +#. type: Plain text +#: ../src/guide/start/hello.md +msgid "This URL displays a page with \"The message is: Hello World\"." +msgstr "Essa URL mostra uma página com \"The message is: Hello World\"." + +#. type: Plain text +#: ../src/guide/start/hello.md +msgid "If you omit the `message` parameter in the URL, the page displays \"The message is: Hello!\"." +msgstr "Se você omitir o parâmetro `message` na URL, a página mostra \"The message is: Hello!\"." + +#. type: Title ## +#: ../src/guide/start/hello.md +#, no-wrap +msgid "Creating a View Template" +msgstr "Criando um template de view" + +#. type: Plain text +#: ../src/guide/start/hello.md +msgid "Usually, the task is more complicated than printing out \"hello world\" and involves rendering some complex HTML. For this task, it's handy to use view templates. They're scripts you write to generate a response's body." +msgstr "Normalmente, a tarefa é mais complicada do que imprimir \"hello world\" e envolve renderizar algum HTML complexo. Para isso, é prático usar templates de view. Eles são scripts que você escreve para gerar o corpo de uma resposta." + +#. type: Plain text +#: ../src/guide/start/hello.md +msgid "For the \"Hello\" task, create a `src/Web/Echo/template.php` template that prints the `message` parameter received from the action method:" +msgstr "Para a tarefa \"Hello\", crie um template `src/Web/Echo/template.php` que imprime o parâmetro `message` recebido do método da action:" + +#. type: Fenced code block (php) +#: ../src/guide/start/hello.md ../src/guide/views/view.md +#, no-wrap +msgid "" +"\n" +"\n" +"

The message is:

\n" +msgstr "" +"\n" +"\n" +"

The message is:

\n" + +#. type: Plain text +#: ../src/guide/start/hello.md +msgid "In the above code, the `message` parameter uses HTML encoding before you print it. You need that because the parameter comes from an end user and is vulnerable to [cross-site scripting (XSS) attacks](https://en.wikipedia.org/wiki/Cross-site_scripting) by embedding malicious JavaScript in the parameter." +msgstr "No código acima, o parâmetro `message` passa por codificação HTML antes de ser impresso. Isso é necessário porque o parâmetro vem do usuário final e está sujeito a [ataques de cross-site scripting (XSS)](https://pt.wikipedia.org/wiki/Cross-site_scripting) com JavaScript malicioso embutido no parâmetro." + +#. type: Plain text +#: ../src/guide/start/hello.md +msgid "Naturally, you may put more content in the `say` view. The content can consist of HTML tags, plain text, and even PHP statements. In fact, the view service executes the `say` view as a PHP script." +msgstr "Naturalmente, você pode colocar mais conteúdo na view `say`. O conteúdo pode ter tags HTML, texto puro e até instruções PHP. Na verdade, o serviço de view executa a view `say` como um script PHP." + +#. type: Plain text +#: ../src/guide/start/hello.md +msgid "To use the view, you need to change `src/Web/Echo/Action.php`:" +msgstr "Para usar a view, você precisa alterar `src/Web/Echo/Action.php`:" + +#. type: Fenced code block (php) +#: ../src/guide/start/hello.md ../src/guide/views/view.md +#, no-wrap +msgid "" +"viewRenderer->render(__DIR__ . '/template', [\n" +" 'message' => $message,\n" +" ]);\n" +" }\n" +"}\n" +msgstr "" +"viewRenderer->render(__DIR__ . '/template', [\n" +" 'message' => $message,\n" +" ]);\n" +" }\n" +"}\n" + +#. type: Plain text +#: ../src/guide/start/hello.md +msgid "Now open your browser and check it again. You should see the similar text but with a layout applied." +msgstr "Agora abra o navegador e confira de novo. Você deve ver um texto parecido, mas com um layout aplicado." + +#. type: Plain text +#: ../src/guide/start/hello.md +msgid "Also, you've separated the part about how it works and part of how it's presented. In the larger applications, it helps a lot to deal with complexity." +msgstr "Além disso, você separou a parte de como funciona da parte de como é apresentado. Em aplicações maiores, isso ajuda muito a lidar com a complexidade." + +#. type: Plain text +#: ../src/guide/start/hello.md +msgid "In this section, you've touched the handler and template parts of the typical web application. You created a handler as part of a class to handle a specific request. You also created a view to compose the response's content. In this simple example, no data source was involved as the only data used was the `message` parameter." +msgstr "Nesta seção, você passou pelas partes de handler e de template de uma aplicação web típica. Você criou um handler como parte de uma classe para tratar uma requisição específica. Também criou uma view para compor o conteúdo da resposta. Neste exemplo simples, nenhuma fonte de dados foi usada, já que o único dado era o parâmetro `message`." + +#. type: Plain text +#: ../src/guide/start/hello.md +msgid "You've also learned about routing in Yii, which acts as the bridge between user requests and handlers." +msgstr "Você também aprendeu sobre o roteamento no Yii, que funciona como a ponte entre as requisições do usuário e os handlers." + +#. type: Plain text +#: ../src/guide/start/hello.md +msgid "In the next section, you will learn how to fetch data and add a new page containing an HTML form." +msgstr "Na próxima seção, você vai aprender a buscar dados e adicionar uma nova página com um formulário HTML." diff --git a/_translations/po/pt-BR/guide_start_looking-ahead.md.po b/_translations/po/pt-BR/guide_start_looking-ahead.md.po new file mode 100644 index 00000000..cd8f7556 --- /dev/null +++ b/_translations/po/pt-BR/guide_start_looking-ahead.md.po @@ -0,0 +1,27 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-12-24 13:00+0000\n" +"PO-Revision-Date: 2025-12-24 13:00+0000\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/guide/start/looking-ahead.md +#, no-wrap +msgid "Looking ahead" +msgstr "Seguindo em frente" + +#. type: Plain text +#: ../src/guide/start/looking-ahead.md +msgid "If you've read through the entire \"Getting Started\" chapter, you have now created a complete Yii application. In the process, you've learned how to implement some commonly necessary features, such as getting data from users via an HTML form, fetching data from a database, and displaying data in a paginated fashion. You've also learned how to use [Gii](gii.md) to generate code automatically. Using Gii for code generation turns the bulk of your Web development process into a task as simple as just filling out some forms." +msgstr "Se você leu todo o capítulo \"Primeiros passos\", já criou uma aplicação Yii completa. No caminho, aprendeu a implementar alguns recursos comuns, como receber dados dos usuários por um formulário HTML, buscar dados em um banco de dados e exibir dados de forma paginada. Também aprendeu a usar o [Gii](gii.md) para gerar código automaticamente. Usar o Gii para gerar código transforma boa parte do desenvolvimento web em algo tão simples quanto preencher alguns formulários." diff --git a/_translations/po/pt-BR/guide_start_prerequisites.md.po b/_translations/po/pt-BR/guide_start_prerequisites.md.po new file mode 100644 index 00000000..8fcf717a --- /dev/null +++ b/_translations/po/pt-BR/guide_start_prerequisites.md.po @@ -0,0 +1,97 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-05-28 20:46+0000\n" +"PO-Revision-Date: 2026-05-28 20:46+0000\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/guide/start/prerequisites.md +#, no-wrap +msgid "What do you need to know?" +msgstr "O que você precisa saber?" + +#. type: Plain text +#: ../src/guide/start/prerequisites.md +msgid "The Yii learning curve isn't as steep as other PHP frameworks, but still, there are some things you should learn before starting with Yii." +msgstr "A curva de aprendizado do Yii não é tão íngreme quanto a de outros frameworks PHP, mas ainda assim há algumas coisas que você deve aprender antes de começar com o Yii." + +#. type: Title ## +#: ../src/guide/start/prerequisites.md +#, no-wrap +msgid "PHP" +msgstr "PHP" + +#. type: Plain text +#: ../src/guide/start/prerequisites.md +msgid "Yii is a PHP framework, so make sure you [read and understand language reference](https://www.php.net/manual/en/langref.php)." +msgstr "O Yii é um framework PHP, então [leia e entenda a referência da linguagem](https://www.php.net/manual/pt_BR/langref.php)." + +#. type: Title ## +#: ../src/guide/start/prerequisites.md +#, no-wrap +msgid "Object-oriented programming" +msgstr "Programação orientada a objetos" + +#. type: Plain text +#: ../src/guide/start/prerequisites.md +msgid "You need a basic understanding of object-oriented programming. If you're not familiar with it, check one of the many tutorials available such as [the one from tuts+](https://code.tutsplus.com/tutorials/object-oriented-php-for-beginners--net-12762)." +msgstr "Você precisa de uma noção básica de programação orientada a objetos. Se ainda não conhece, veja um dos muitos tutoriais disponíveis, como [o do tuts+](https://code.tutsplus.com/tutorials/object-oriented-php-for-beginners--net-12762)." + +#. type: Plain text +#: ../src/guide/start/prerequisites.md +msgid "When you develop with Yii, you write code in an object-oriented fashion, so make sure you're familiar with [PHP OOP support](https://www.php.net/manual/en/language.oop5.php)." +msgstr "Ao desenvolver com o Yii, você escreve código orientado a objetos, então conheça bem o [suporte do PHP a POO](https://www.php.net/manual/pt_BR/language.oop5.php)." + +#. type: Plain text +#: ../src/guide/start/prerequisites.md +msgid "Note that the more complicated your application is, the more advanced OOP concepts you should learn to successfully manage that complexity." +msgstr "Quanto mais complexa for a sua aplicação, mais conceitos avançados de POO você vai precisar aprender para lidar bem com essa complexidade." + +#. type: Title ## +#: ../src/guide/start/prerequisites.md +#, no-wrap +msgid "Command line and Composer" +msgstr "Linha de comando e Composer" + +#. type: Plain text +#: ../src/guide/start/prerequisites.md +msgid "Yii extensively uses the de-facto standard PHP package manager, [Composer](https://getcomposer.org) so make sure you read and understand its [guide](https://getcomposer.org/doc/01-basic-usage.md). If you aren't familiar with using the command line, it's time to start trying. Once you learn the basics, you'll never want to work without it." +msgstr "O Yii usa amplamente o gerenciador de pacotes que é o padrão de fato no PHP, o [Composer](https://getcomposer.org), então leia e entenda o [guia dele](https://getcomposer.org/doc/01-basic-usage.md). Se você não tem costume de usar a linha de comando, é hora de começar. Depois de aprender o básico, você não vai querer trabalhar sem ela." + +#. type: Title ## +#: ../src/guide/start/prerequisites.md +#, no-wrap +msgid "HTTP" +msgstr "HTTP" + +#. type: Plain text +#: ../src/guide/start/prerequisites.md +msgid "Since Yii is a web framework and the web largely uses HTTP, it's a good idea to [learn more about it](https://developer.mozilla.org/en-US/docs/Web/HTTP)." +msgstr "Como o Yii é um framework web e a web usa principalmente HTTP, é uma boa ideia [aprender mais sobre ele](https://developer.mozilla.org/pt-BR/docs/Web/HTTP)." + +#. type: Title ## +#: ../src/guide/start/prerequisites.md +#, no-wrap +msgid "Docker" +msgstr "Docker" + +#. type: Plain text +#: ../src/guide/start/prerequisites.md +msgid "The default application template leverages Docker, so we recommend that you [read and understand the concepts](https://docs.docker.com/get-started/)." +msgstr "O template de aplicação padrão usa Docker, então recomendamos que você [leia e entenda os conceitos](https://docs.docker.com/get-started/)." + +#. type: Plain text +#: ../src/guide/start/prerequisites.md +msgid "Also, you will benefit from familiarizing yourself with [twelve-factor app](https://12factor.net/) principles." +msgstr "Também vale a pena conhecer os princípios do [twelve-factor app](https://12factor.net/pt_br/)." diff --git a/_translations/po/pt-BR/guide_start_workflow.md.po b/_translations/po/pt-BR/guide_start_workflow.md.po new file mode 100644 index 00000000..24b643a3 --- /dev/null +++ b/_translations/po/pt-BR/guide_start_workflow.md.po @@ -0,0 +1,286 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-06-05 20:33+0000\n" +"PO-Revision-Date: 2026-06-05 20:33+0000\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/guide/index.md ../src/guide/start/workflow.md +#, no-wrap +msgid "Application structure" +msgstr "Estrutura da aplicação" + +#. type: Title # +#: ../src/guide/start/workflow.md +#, no-wrap +msgid "Application Workflow" +msgstr "Fluxo da aplicação" + +#. type: Plain text +#: ../src/guide/start/workflow.md +msgid "After installing Yii, you have a working Yii application. This section introduces the application's built-in functionality, how the code is organized, and how the application handles requests in general." +msgstr "Depois de instalar o Yii, você tem uma aplicação Yii funcionando. Esta seção apresenta as funcionalidades que vêm com a aplicação, como o código está organizado e como a aplicação trata as requisições de forma geral." + +#. type: Plain text +#: ../src/guide/start/workflow.md +msgid "Note that unlike the framework itself, after you install a project template, it's all yours. You're free to add or delete code and overall change it as you need." +msgstr "Diferente do próprio framework, depois que você instala um template de projeto, ele é todo seu. Você pode adicionar ou remover código e mudar o que precisar." + +#. type: Title ## +#: ../src/guide/start/workflow.md +#, no-wrap +msgid "Functionality" +msgstr "Funcionalidades" + +#. type: Plain text +#: ../src/guide/start/workflow.md +msgid "The installed application contains only one page, accessible at `http://localhost/`. It shares a common layout that you can reuse on further pages." +msgstr "A aplicação instalada tem apenas uma página, acessível em `http://localhost/`. Ela usa um layout comum que você pode reaproveitar nas próximas páginas." + +#. type: Plain text +#: ../src/guide/start/workflow.md +#, no-wrap +msgid "" +"\n" +msgstr "" +"\n" + +#. type: Plain text +#: ../src/guide/start/workflow.md +msgid "In addition to the web application, you can access a console script via `./yii` or, in case of Docker, `make yii`. Use this script to run background and maintenance tasks for the application, which the [Console Application Section](../tutorial/console-applications.md) describes." +msgstr "Além da aplicação web, você pode acessar um script de console via `./yii` ou, no caso do Docker, `make yii`. Use esse script para rodar tarefas em segundo plano e de manutenção da aplicação, descritas na [seção de aplicações de console](../tutorial/console-applications.md)." + +#. type: Title ## +#: ../src/guide/start/workflow.md +#, no-wrap +msgid "Experimental debugger" +msgstr "Debugger experimental" + +#. type: Plain text +#: ../src/guide/start/workflow.md +msgid "Yii has a debugger that can collect debug data for web requests and expose it through the [Yii Dev Panel](https://yiisoft.github.io/yii-dev-panel/). The debugger is a work in progress. It isn't released as a stable package, and its API, routes, and setup may change or be deprecated." +msgstr "O Yii tem um debugger que coleta dados de debug das requisições web e os expõe pelo [Yii Dev Panel](https://yiisoft.github.io/yii-dev-panel/). O debugger ainda está em desenvolvimento. Ele não foi lançado como pacote estável, e a API, as rotas e a configuração podem mudar ou ser descontinuadas." + +#. type: Plain text +#: ../src/guide/start/workflow.md +msgid "To try the current development version, install the debug API package:" +msgstr "Para testar a versão de desenvolvimento atual, instale o pacote da API de debug:" + +#. type: Fenced code block (shell) +#: ../src/guide/start/workflow.md +#, no-wrap +msgid "composer require yiisoft/yii-debug-api:^3.0@dev\n" +msgstr "composer require yiisoft/yii-debug-api:^3.0@dev\n" + +#. type: Plain text +#: ../src/guide/start/workflow.md +msgid "Enable debug mode in `.env`:" +msgstr "Ative o modo debug no `.env`:" + +#. type: Fenced code block (dotenv) +#: ../src/guide/start/workflow.md +#, no-wrap +msgid "APP_DEBUG=true\n" +msgstr "APP_DEBUG=true\n" + +#. type: Plain text +#: ../src/guide/start/workflow.md +msgid "The package registers its routes automatically. Start the application and open `/debug` to check that the debug API is available. Then open [Yii Dev Panel](https://yiisoft.github.io/yii-dev-panel/) and set your application URL there." +msgstr "O pacote registra as rotas automaticamente. Inicie a aplicação e abra `/debug` para conferir se a API de debug está disponível. Depois abra o [Yii Dev Panel](https://yiisoft.github.io/yii-dev-panel/) e informe a URL da sua aplicação." + +#. type: Plain text +#: ../src/guide/start/workflow.md +#, no-wrap +msgid "" +"> [!CAUTION]\n" +"> Use debug mode for local development. In production, keep `APP_DEBUG=false` and don't expose debug routes publicly.\n" +msgstr "" +"> [!CAUTION]\n" +"> Use o modo debug no desenvolvimento local. Em produção, mantenha `APP_DEBUG=false` e não exponha as rotas de debug publicamente.\n" + +#. type: Plain text +#: ../src/guide/start/workflow.md +msgid "The most important directories and files in your application are (assuming the application's root directory is `app`):" +msgstr "Os diretórios e arquivos mais importantes da sua aplicação são (considerando que o diretório raiz da aplicação é `app`):" + +#. type: Fenced code block +#: ../src/guide/start/workflow.md +#, no-wrap +msgid "" +"assets/ Asset bundle source files.\n" +"config/ Configuration files.\n" +" common/ Common configuration and DI definitions.\n" +" console/ Console-specific configuration.\n" +" environments/ Environment-specific configuration (dev/test/prod).\n" +" web/ Web-specific configuration.\n" +"docker/ Docker-specific files.\n" +"public/ Files publically accessible from the Internet.\n" +" assets/ Published/compiled assets.\n" +" index.php Entry script.\n" +"runtime/ Files generated during runtime.\n" +"src/ Application source code.\n" +" Console/ Console commands.\n" +" Shared/ Code shared between web and console applications.\n" +" Web/ Web-specific code (actions, handlers, layout).\n" +" Shared/ Shared web components.\n" +" Layout/ Layout components and templates.\n" +" Environment.php Environment configuration class.\n" +"tests/ A set of Codeception tests for the application.\n" +" Console/ Console command tests.\n" +" Functional/ Functional tests.\n" +" Unit/ Unit tests.\n" +" Web/ Web actions tests.\n" +"vendor/ Installed Composer packages.\n" +"Makefile Config for make command.\n" +"yii Console application entry point.\n" +msgstr "" +"assets/ Arquivos-fonte dos asset bundles.\n" +"config/ Arquivos de configuração.\n" +" common/ Configuração comum e definições de DI.\n" +" console/ Configuração específica do console.\n" +" environments/ Configuração por ambiente (dev/test/prod).\n" +" web/ Configuração específica da web.\n" +"docker/ Arquivos específicos do Docker.\n" +"public/ Arquivos acessíveis publicamente pela internet.\n" +" assets/ Assets publicados/compilados.\n" +" index.php Script de entrada.\n" +"runtime/ Arquivos gerados em tempo de execução.\n" +"src/ Código-fonte da aplicação.\n" +" Console/ Comandos de console.\n" +" Shared/ Código compartilhado entre as aplicações web e console.\n" +" Web/ Código específico da web (actions, handlers, layout).\n" +" Shared/ Componentes web compartilhados.\n" +" Layout/ Componentes e templates de layout.\n" +" Environment.php Classe de configuração do ambiente.\n" +"tests/ Conjunto de testes Codeception da aplicação.\n" +" Console/ Testes dos comandos de console.\n" +" Functional/ Testes funcionais.\n" +" Unit/ Testes unitários.\n" +" Web/ Testes das actions web.\n" +"vendor/ Pacotes do Composer instalados.\n" +"Makefile Configuração do comando make.\n" +"yii Ponto de entrada da aplicação de console.\n" + +#. type: Plain text +#: ../src/guide/start/workflow.md +msgid "In general, the files in the application fall into two groups: those under `app/public` and those under other directories. You can access the former directly via HTTP (i.e., in a browser), while you shouldn't expose the latter." +msgstr "De forma geral, os arquivos da aplicação se dividem em dois grupos: os que ficam em `app/public` e os que ficam nos outros diretórios. Os primeiros podem ser acessados diretamente via HTTP (ou seja, no navegador), enquanto os demais não devem ser expostos." + +#. type: Plain text +#: ../src/guide/start/workflow.md +msgid "Each application has an entry script `public/index.php`, the only web-accessible PHP script in the application. The entry script uses an [application runner](https://github.com/yiisoft/yii-runner) to create an instance of an incoming request with the help of one of PSR-7 packages and passes it to an [application](../structure/application.md) instance. The application executes a set of middleware sequentially to process the request. It then passes the result to the emitter, which sends the response to the browser." +msgstr "Toda aplicação tem um script de entrada `public/index.php`, o único script PHP acessível pela web na aplicação. O script de entrada usa um [application runner](https://github.com/yiisoft/yii-runner) para criar uma instância da requisição recebida com a ajuda de um dos pacotes PSR-7 e a passa para uma instância da [aplicação](../structure/application.md). A aplicação executa um conjunto de middlewares em sequência para processar a requisição. Depois, passa o resultado para o emitter, que envia a resposta ao navegador." + +#. type: Plain text +#: ../src/guide/start/workflow.md +msgid "Depending on the middleware you use, the application may behave differently. By default, a router uses the requested URL and configuration to choose a handler and execute it to produce a response." +msgstr "Dependendo dos middlewares que você usa, a aplicação pode se comportar de forma diferente. Por padrão, um router usa a URL requisitada e a configuração para escolher um handler e executá-lo para produzir a resposta." + +#. type: Plain text +#: ../src/guide/start/workflow.md +msgid "You can learn more about the application template from the [yiisoft/app package documentation](https://github.com/yiisoft/app/blob/master/README.md)." +msgstr "Você pode saber mais sobre o template de aplicação na [documentação do pacote yiisoft/app](https://github.com/yiisoft/app/blob/master/README.md)." + +#. type: Title ## +#: ../src/guide/start/workflow.md +#, no-wrap +msgid "Request Lifecycle" +msgstr "Ciclo de vida da requisição" + +#. type: Plain text +#: ../src/guide/start/workflow.md +msgid "The following diagram shows how an application handles a request." +msgstr "O diagrama a seguir mostra como uma aplicação trata uma requisição." + +#. type: Fenced code block (mermaid) +#: ../src/guide/start/workflow.md +#, no-wrap +msgid "" +"flowchart LR\n" +" user[User's client] --> index\n" +" index[index.php] --> DI[Initialize Dependency Container]\n" +" config[configs] -.-> DI\n" +" DI --> RequestFactory[RequestFactory]\n" +" RequestFactory -->|Request| app[Application]\n" +" app -->|Request| middleware[Middleware]\n" +" middleware -->|Request| router[Router]\n" +" router -->|Request| action[Action Handler]\n" +" action -->|Response| emitter[SapiEmitter]\n" +" router -->|Response| emitter\n" +" middleware -->|Response| emitter\n" +" app -->|Response| emitter\n" +" emitter --> user\n" +msgstr "" +"flowchart LR\n" +" user[User's client] --> index\n" +" index[index.php] --> DI[Initialize Dependency Container]\n" +" config[configs] -.-> DI\n" +" DI --> RequestFactory[RequestFactory]\n" +" RequestFactory -->|Request| app[Application]\n" +" app -->|Request| middleware[Middleware]\n" +" middleware -->|Request| router[Router]\n" +" router -->|Request| action[Action Handler]\n" +" action -->|Response| emitter[SapiEmitter]\n" +" router -->|Response| emitter\n" +" middleware -->|Response| emitter\n" +" app -->|Response| emitter\n" +" emitter --> user\n" + +#. type: Bullet: '1. ' +#: ../src/guide/start/workflow.md +msgid "A user makes a request to the [entry script](../structure/entry-script.md) `public/index.php`." +msgstr "Um usuário faz uma requisição para o [script de entrada](../structure/entry-script.md) `public/index.php`." + +#. type: Bullet: '2. ' +#: ../src/guide/start/workflow.md +msgid "The entry script with the help of the application runner loads the container [configuration](../concept/configuration.md) and creates an [application](../structure/application.md) instance and services necessary to handle the request." +msgstr "O script de entrada, com a ajuda do application runner, carrega a [configuração](../concept/configuration.md) do container e cria uma instância da [aplicação](../structure/application.md) e os serviços necessários para tratar a requisição." + +#. type: Bullet: '3. ' +#: ../src/guide/start/workflow.md +msgid "Request factory creates a request object based on a raw request that came from a user." +msgstr "A request factory cria um objeto de requisição a partir da requisição bruta que veio do usuário." + +#. type: Bullet: '4. ' +#: ../src/guide/start/workflow.md +msgid "Application passes a request object through a middleware array configured. One of these is typically a router." +msgstr "A aplicação passa o objeto de requisição pelo array de middlewares configurado. Um deles normalmente é o router." + +#. type: Bullet: '5. ' +#: ../src/guide/start/workflow.md +msgid "The Router finds out what handler to execute based on request and configuration." +msgstr "O router descobre qual handler executar com base na requisição e na configuração." + +#. type: Bullet: '6. ' +#: ../src/guide/start/workflow.md +msgid "The handler may load some data, possibly from a database." +msgstr "O handler pode carregar alguns dados, possivelmente de um banco de dados." + +#. type: Bullet: '7. ' +#: ../src/guide/start/workflow.md +msgid "The handler forms a response by using data. Either directly or with the help of the view package." +msgstr "O handler monta uma resposta usando esses dados, diretamente ou com a ajuda do pacote de view." + +#. type: Bullet: '8. ' +#: ../src/guide/start/workflow.md +msgid "Emitter receives the response and takes care of sending the response to the user's browser." +msgstr "O emitter recebe a resposta e cuida de enviá-la para o navegador do usuário." diff --git a/_translations/po/pt-BR/guide_structure_action.md.po b/_translations/po/pt-BR/guide_structure_action.md.po new file mode 100644 index 00000000..de56aaf2 --- /dev/null +++ b/_translations/po/pt-BR/guide_structure_action.md.po @@ -0,0 +1,188 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-05-05 21:53+0000\n" +"PO-Revision-Date: 2026-05-05 21:53+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/guide/intro/upgrade-from-v2.md ../src/guide/structure/action.md +#, no-wrap +msgid "Actions" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/action.md +msgid "In a web application, the request URL determines what's executed. Matching is made by a router configured with multiple routes. Each route can be attached to a middleware that, given request, produces a response. Since middleware overall could be chained and can pass actual handling to the next middleware, we call the middleware actually doing the job an action." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/action.md +msgid "There are multiple ways to describe an action. The simplest one is using a closure:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/action.md +#, no-wrap +msgid "" +"use \\Psr\\Http\\Message\\ServerRequestInterface;\n" +"use \\Psr\\Http\\Message\\ResponseInterface;\n" +"use Yiisoft\\Router\\Route;\n" +"\n" +"Route::get('/')->action(function (ServerRequestInterface $request) use ($responseFactory): ResponseInterface {\n" +" $response = $responseFactory->createResponse();\n" +" $response->getBody()->write('You are at homepage.');\n" +" return $response;\n" +"});\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/action.md +msgid "It's fine for simple handling since any more complicated one would require getting dependencies, so a good idea would be moving the handling to a class method. Callback middleware could be used for the purpose:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/action.md +#, no-wrap +msgid "" +"use Yiisoft\\Router\\Route;\n" +"\n" +"Route::get('/')->action(FrontPageAction::class),\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/action.md +msgid "The class itself would be like:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/action.md +#, no-wrap +msgid "" +"use \\Psr\\Http\\Message\\ServerRequestInterface;\n" +"use \\Psr\\Http\\Message\\ResponseInterface;\n" +"\n" +"final readonly class FrontPageAction\n" +"{\n" +" public function __invoke(ServerRequestInterface $request): ResponseInterface\n" +" {\n" +" // build response for a front page \n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/action.md +msgid "For many cases, it makes sense to group handling for many routes into a single class:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/action.md +#, no-wrap +msgid "" +"use Yiisoft\\Router\\Route;\n" +"\n" +"Route::get('/post/index')->action([PostController::class, 'actionIndex']),\n" +"Route::get('/post/view/{id:\\d+}')->action([PostController::class, 'actionView']),\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/action.md +msgid "The class itself would look like the following:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/action.md +#, no-wrap +msgid "" +"use \\Psr\\Http\\Message\\ServerRequestInterface;\n" +"use \\Psr\\Http\\Message\\ResponseInterface;\n" +"use Yiisoft\\Router\\HydratorAttribute\\RouteArgument;\n" +"\n" +"final readonly class PostController\n" +"{\n" +" public function actionIndex(ServerRequestInterface $request): ResponseInterface\n" +" {\n" +" // render posts list\n" +" }\n" +" \n" +" \n" +" public function actionView(\n" +" ServerRequestInterface $request,\n" +" #[RouteArgument('id')]\n" +" int $id,\n" +" ): ResponseInterface\n" +" {\n" +" // render a single post by $id\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/action.md +msgid "We usually call such a class \"controller.\"" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/action.md +msgid "The `{id}` part of the `/post/view/{id:\\d+}` route is a named route parameter. Route parameters are available from `Yiisoft\\Router\\CurrentRoute`. To receive one as an action argument, add the `RouteArgument` attribute to the corresponding parameter. The attribute name should match the route parameter name." +msgstr "" + +#. type: Title ## +#: ../src/guide/structure/action.md +#, no-wrap +msgid "Autowiring" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/action.md +#, no-wrap +msgid "" +"Both constructors of action-classes and action-methods are automatically getting services from\n" +" the dependency injection container:\n" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/action.md +#, no-wrap +msgid "" +"use \\Psr\\Http\\Message\\ServerRequestInterface;\n" +"use \\Psr\\Http\\Message\\ResponseInterface;\n" +"use Psr\\Log\\LoggerInterface;\n" +"\n" +"final readonly class PostController\n" +"{\n" +" public function __construct(\n" +" private PostRepository $postRepository\n" +" )\n" +" {\n" +" }\n" +"\n" +" public function actionIndex(ServerRequestInterface $request, LoggerInterface $logger): ResponseInterface\n" +" {\n" +" $logger->debug('Rendering posts list');\n" +" // render posts list\n" +" }\n" +" \n" +" \n" +" public function actionView(ServerRequestInterface $request): ResponseInterface\n" +" {\n" +" // render a single post \n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/action.md +msgid "In the above example `PostRepository` is injected automatically via constructor. That means it is available in every action. Logger is injected into `index` action only." +msgstr "" diff --git a/_translations/po/pt-BR/guide_structure_application.md.po b/_translations/po/pt-BR/guide_structure_application.md.po new file mode 100644 index 00000000..5d222613 --- /dev/null +++ b/_translations/po/pt-BR/guide_structure_application.md.po @@ -0,0 +1,47 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-12-27 03:24+0000\n" +"PO-Revision-Date: 2025-12-27 03:24+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/guide/structure/application.md +#, no-wrap +msgid "Application" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/application.md +msgid "The primary purpose of the web application and its runner in Yii3 is to process requests to get responses." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/application.md +msgid "Typically, the runtime consists of:" +msgstr "" + +#. type: Bullet: '1. ' +#: ../src/guide/structure/application.md +msgid "Startup. Get config, create an instance of container and do additional environment initialization such as registering error handler, so it can handle errors occurring. Fire `ApplicationStartup` event." +msgstr "" + +#. type: Bullet: '2. ' +#: ../src/guide/structure/application.md +msgid "Handle requests via passing request objects to middleware dispatcher to execute [middleware stack](middleware.md) and get a response object. In usual PHP applications, it's done once. In [environments such as RoadRunner](../tutorial/using-with-event-loop.md), it could be done multiple times with the same application instance. Response object is converted into an actual HTTP response by using emitter. Fire `AfterEmit` event." +msgstr "" + +#. type: Bullet: '3. ' +#: ../src/guide/structure/application.md +msgid "Shutdown. Fire `ApplicationShutdown` event." +msgstr "" diff --git a/_translations/po/pt-BR/guide_structure_designing-packages.md.po b/_translations/po/pt-BR/guide_structure_designing-packages.md.po new file mode 100644 index 00000000..a599a143 --- /dev/null +++ b/_translations/po/pt-BR/guide_structure_designing-packages.md.po @@ -0,0 +1,789 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-06-02 22:29+0000\n" +"PO-Revision-Date: 2026-06-02 22:29+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Fenced code block (sh) +#: ../src/cookbook/using-yii-in-third-party-apps.md +#: ../src/guide/structure/designing-packages.md +#: ../src/guide/structure/module.md ../src/guide/structure/package.md +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "composer yii-config-rebuild\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/concept/configuration.md +#: ../src/guide/structure/designing-packages.md +#: ../src/guide/structure/module.md +#, no-wrap +msgid "Routes" +msgstr "" + +#. type: Title ## +#: ../src/guide/concept/configuration.md ../src/guide/concept/events.md +#: ../src/guide/structure/designing-packages.md +#: ../src/internals/022-config-groups.md +#, no-wrap +msgid "Events" +msgstr "" + +#. type: Title ## +#: ../src/guide/concept/configuration.md +#: ../src/guide/structure/designing-packages.md +#: ../src/internals/022-config-groups.md +#, no-wrap +msgid "Parameters" +msgstr "" + +#. type: Title ## +#: ../src/guide/databases/db-migrations.md +#: ../src/guide/structure/designing-packages.md +#, no-wrap +msgid "Migrations" +msgstr "" + +#. type: Title ## +#: ../src/guide/intro/upgrade-from-v2.md +#: ../src/guide/structure/designing-packages.md +#, no-wrap +msgid "Console commands" +msgstr "" + +#. type: Title # +#: ../src/guide/structure/designing-packages.md +#, no-wrap +msgid "Designing packages for Yii applications" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "This page describes how to design a Composer package that adds behavior to a Yii application through configuration. Use it when your package needs to register services, routes, events, commands, assets, migrations, translations, or a theme." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "For installing and updating packages in an application, see [Using packages](package.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/structure/designing-packages.md +#, no-wrap +msgid "Composer metadata" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "Each package must have a `composer.json` file in its root directory. At minimum, define a package name, dependencies, autoloading, and Yii config metadata when the package integrates with a Yii application." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "Use a package name in the `vendor-name/project-name` format:" +msgstr "" + +#. type: Fenced code block (json) +#: ../src/guide/structure/designing-packages.md +#, no-wrap +msgid "" +"{\n" +" \"name\": \"vendor/blog\",\n" +" \"type\": \"library\",\n" +" \"description\": \"Blog integration for Yii applications\",\n" +" \"require\": {\n" +" \"php\": \">=8.2\",\n" +" \"yiisoft/router\": \"^4.0\"\n" +" },\n" +" \"autoload\": {\n" +" \"psr-4\": {\n" +" \"Vendor\\\\Blog\\\\\": \"src/\"\n" +" }\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "Use stable dependency constraints for stable releases. Avoid using `yiisoft` as your vendor name because it is reserved for Yii packages." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "If your package requires a Yii application, prefixing the project name with `yii-` can make that clear on Packagist." +msgstr "" + +#. type: Title ## +#: ../src/guide/structure/designing-packages.md +#, no-wrap +msgid "Package layout" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "A Yii-aware package is a regular Composer package with PHP classes, optional resource files, and optional config files. Keep the configuration in a predictable directory and make the public API explicit:" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/structure/designing-packages.md +#, no-wrap +msgid "" +"composer.json\n" +"config/\n" +" params.php\n" +" di.php\n" +" di-providers.php\n" +" routes.php\n" +" events.php\n" +" params-web.php\n" +" params-console.php\n" +" di-console.php\n" +"src/\n" +" ...\n" +"assets/\n" +" ...\n" +"migrations/\n" +" ...\n" +"messages/\n" +" ...\n" +"views/\n" +" ...\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "Use only the files your package needs. For example, a package with console commands but no web routes does not need `routes.php`." +msgstr "" + +#. type: Title ## +#: ../src/guide/structure/designing-packages.md +#, no-wrap +msgid "Config plugin metadata" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "Yii applications use [yiisoft/config](https://github.com/yiisoft/config) to discover package configuration. Declare package config files in the `extra.config-plugin` section of `composer.json`:" +msgstr "" + +#. type: Fenced code block (json) +#: ../src/guide/structure/designing-packages.md +#, no-wrap +msgid "" +"{\n" +" \"name\": \"vendor/blog\",\n" +" \"type\": \"library\",\n" +" \"autoload\": {\n" +" \"psr-4\": {\n" +" \"Vendor\\\\Blog\\\\\": \"src/\"\n" +" }\n" +" },\n" +" \"extra\": {\n" +" \"config-plugin\": {\n" +" \"params\": \"config/params.php\",\n" +" \"di\": \"config/di.php\",\n" +" \"di-providers\": \"config/di-providers.php\",\n" +" \"routes\": \"config/routes.php\",\n" +" \"events\": \"config/events.php\",\n" +" \"params-web\": \"config/params-web.php\",\n" +" \"params-console\": \"config/params-console.php\",\n" +" \"di-console\": \"config/di-console.php\"\n" +" }\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "Each `config-plugin` key is a config group name and each value is a path relative to the package root." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "Use the common, web, and console groups consistently:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/structure/designing-packages.md +msgid "`params`, `di`, `di-providers`, `di-delegates`, `events`, and `bootstrap` apply to both web and console entry points." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/structure/designing-packages.md +msgid "`params-web`, `di-web`, `di-providers-web`, `events-web`, `bootstrap-web`, and `routes` apply to web entry points." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/structure/designing-packages.md +msgid "`params-console`, `di-console`, `di-providers-console`, `events-console`, and `bootstrap-console` apply to console entry points." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "If your package defines a new config group, document how an application should load that group. Prefer the standard groups when you integrate with Yii services because application templates and Yii packages already use these names." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "After users install, update, remove, or dump Composer autoload files, the config plugin rebuilds the merge plan that Yii reads at runtime. If users edit their root package configuration manually, ask them to run:" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "Put default options in `config/params.php`. Group package parameters under the Composer package name to avoid collisions:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/designing-packages.md +#, no-wrap +msgid "" +" [\n" +" 'postsPerPage' => 20,\n" +" 'cacheTtl' => 3600,\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "Application developers can override these values in their own `config/common/params.php`, `config/web/params.php`, `config/console/params.php`, or environment-specific parameter files." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "Do not read environment variables or global state from package code when a parameter can express the choice. Use parameters to configure services through DI definitions or service providers." +msgstr "" + +#. type: Title ## +#: ../src/guide/structure/designing-packages.md +#, no-wrap +msgid "DI definitions" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "Use `config/di.php`, `config/di-web.php`, or `config/di-console.php` for direct container definitions:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/designing-packages.md +#, no-wrap +msgid "" +" [\n" +" 'class' => PostRepository::class,\n" +" '__construct()' => [\n" +" 'cacheTtl' => $params['vendor/blog']['cacheTtl'],\n" +" ],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "Prefer direct DI definitions when the configuration describes one service clearly." +msgstr "" + +#. type: Title ## +#: ../src/guide/structure/designing-packages.md +#, no-wrap +msgid "DI service providers" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "Use a DI provider when registration belongs together as a reusable unit: several related services, aliases, factory definitions, or extensions." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "Register providers in `config/di-providers.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/designing-packages.md +#, no-wrap +msgid "" +" BlogProvider::class,\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "Declare the group in `composer.json`:" +msgstr "" + +#. type: Fenced code block (json) +#: ../src/guide/structure/designing-packages.md +#, no-wrap +msgid "" +"\"extra\": {\n" +" \"config-plugin\": {\n" +" \"di-providers\": \"config/di-providers.php\"\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "A provider can return several service definitions and extensions. Place the provider class in `src/Provider/BlogProvider.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/designing-packages.md +#, no-wrap +msgid "" +" PostRepository::class,\n" +" PostRepositoryInterface::class => static fn (\n" +" ContainerInterface $container\n" +" ): CachedPostRepository => new CachedPostRepository(\n" +" $container->get(PostRepository::class),\n" +" $container->get(LoggerInterface::class),\n" +" ),\n" +" ];\n" +" }\n" +"\n" +" public function getExtensions(): array\n" +" {\n" +" return [];\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "Web packages can add routes through `config/routes.php`, declared as the `routes` group:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/designing-packages.md +#, no-wrap +msgid "" +"routes(\n" +" Route::get('')\n" +" ->action(IndexAction::class)\n" +" ->name('vendor/blog/index'),\n" +" ),\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "Route names should be package-prefixed. This avoids collisions with application routes and with routes from other packages." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "Keep package routes small and overridable. If an application needs full control over URLs, document the actions and let the application define its own routes." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "Use `config/events.php`, `config/events-web.php`, or `config/events-console.php` to attach package handlers to events:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/designing-packages.md +#, no-wrap +msgid "" +" [\n" +" ClearPostListCache::class,\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "Handlers can be closures, callables, invokable objects, invokable class names, or DI aliases supported by the event dispatcher configuration. Prefer class names for package handlers because applications can override their dependencies through the container." +msgstr "" + +#. type: Title # +#: ../src/guide/structure/designing-packages.md ../src/guide/views/asset.md +#, no-wrap +msgid "Assets" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "If your package ships CSS, JavaScript, images, or fonts, define asset bundles as PHP classes. For example, place this class in `src/Asset/BlogAsset.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/designing-packages.md +#, no-wrap +msgid "" +"register(BlogAsset::class);\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "Use `$sourcePath` for files shipped inside the package. Use `$basePath` and `$baseUrl` as the public target where the asset manager publishes them." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "Packages that need database schema changes should ship migrations and add their namespace or path to `yiisoft/db-migration` parameters." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "For namespaced migrations:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/designing-packages.md +#, no-wrap +msgid "" +" [\n" +" 'sourceNamespaces' => [\n" +" 'Vendor\\\\Blog\\\\Migration',\n" +" ],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "For path-based migrations:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/designing-packages.md +#, no-wrap +msgid "" +" [\n" +" 'sourcePaths' => [\n" +" __DIR__ . '/../migrations',\n" +" ],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "Put this in `config/params-console.php` and declare it as `params-console` in `composer.json`." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "This only contributes package migration locations. The application still needs `yiisoft/db-migration` installed and a database connection configured before migration commands can run." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "Package migrations must be stable after release. Do not edit a migration that users may already have applied. Add a new migration instead." +msgstr "" + +#. type: Title ## +#: ../src/guide/structure/designing-packages.md +#, no-wrap +msgid "Translations" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "If the package has user-facing messages, give it a dedicated translation category and register a category source in `config/di.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/designing-packages.md +#, no-wrap +msgid "" +" [\n" +" 'definition' => static function (): CategorySource {\n" +" $messageSource = new MessageSource(__DIR__ . '/../messages');\n" +"\n" +" return new CategorySource(\n" +" 'vendor-blog',\n" +" $messageSource,\n" +" new IntlMessageFormatter(),\n" +" $messageSource,\n" +" );\n" +" },\n" +" 'tags' => ['translation.categorySource'],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "Store messages by locale and category:" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/structure/designing-packages.md +#, no-wrap +msgid "" +"messages/\n" +" en-US/\n" +" vendor-blog.php\n" +" de/\n" +" vendor-blog.php\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "Use the explicit category when translating:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/designing-packages.md +#, no-wrap +msgid "$translator->translate('post.created', category: 'vendor-blog');\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/structure/designing-packages.md +#, no-wrap +msgid "Themes" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "A package can ship view files and assets for a theme. Do not activate it from vendor package configuration. Instead, document the root application configuration needed to enable it. For the application template, this belongs in `config/web/params.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/designing-packages.md +#, no-wrap +msgid "" +" [\n" +" 'theme' => [\n" +" 'pathMap' => [\n" +" '@views' => '@vendor/vendor/blog/views',\n" +" ],\n" +" 'basePath' => '@vendor/vendor/blog/assets',\n" +" 'baseUrl' => '@assetsUrl/vendor-blog',\n" +" ],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "Themes replace view paths according to a path map. Document which application view paths your theme replaces and which asset URL must be published or exposed by the application." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "Do not set `yiisoft/view.theme` directly in vendor package configuration. `yiisoft/view` already defines that key, and duplicate keys in the same configuration layer are not allowed." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "If your package only provides optional theme files, do not make the theme active by default. Provide the view files, asset bundle, and a documented parameter snippet so the application can opt in." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "Console packages can add Symfony Console commands through `config/params-console.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/designing-packages.md +#, no-wrap +msgid "" +" [\n" +" 'commands' => [\n" +" 'blog/reindex' => ReindexCommand::class,\n" +" ],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "Command names should be package-prefixed. Keep command dependencies constructor-injected and registered through DI." +msgstr "" + +#. type: Title ## +#: ../src/guide/structure/designing-packages.md +#, no-wrap +msgid "Application overrides" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "Package configuration is the default layer. The application can override it in its root package configuration. Design for that:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/structure/designing-packages.md +msgid "Use package-prefixed parameter keys, route names, event handler IDs, and DI aliases." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/structure/designing-packages.md +msgid "Keep default configuration small and documented." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/structure/designing-packages.md +msgid "Avoid doing irreversible work during service registration." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/structure/designing-packages.md +msgid "Put optional integrations in separate config files or providers when they require optional Composer packages." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/structure/designing-packages.md +msgid "Test the package inside a minimal Yii application so the config plugin, DI container, routes, console commands, migrations, translations, and assets are exercised together." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "When a user needs to customize package configuration, they usually do not need to copy the package config file. They can partially redefine the needed keys in the application configuration." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "After changing config group mappings, they should rebuild the merge plan with:" +msgstr "" + +#. type: Title ## +#: ../src/guide/structure/designing-packages.md +#, no-wrap +msgid "Releasing packages" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "Before tagging a release, test the package by itself and inside a minimal Yii application. Include a `README.md`, `CHANGELOG.md`, and `UPGRADE.md` when behavior or configuration changes require explanation." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/designing-packages.md +msgid "Use [semantic versioning](https://semver.org) for public releases. After the first release, do not edit migrations that users may already have applied; add new migrations instead." +msgstr "" diff --git a/_translations/po/pt-BR/guide_structure_entry-script.md.po b/_translations/po/pt-BR/guide_structure_entry-script.md.po new file mode 100644 index 00000000..cee78c99 --- /dev/null +++ b/_translations/po/pt-BR/guide_structure_entry-script.md.po @@ -0,0 +1,202 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-10-07 15:22+0000\n" +"PO-Revision-Date: 2026-10-07 15:22+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/guide/structure/entry-script.md +#, no-wrap +msgid "Entry scripts" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/entry-script.md +msgid "Entry scripts are the first step in the application bootstrapping process. An application (either Web application or console application) has a single entry script. End users make requests to entry scripts which instantiate application instances and forward the requests to them." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/entry-script.md +msgid "Entry scripts for Web applications must be stored under Web-accessible directories so that they can be accessed by end users. They're often named as `index.php`, but can also use any other names, provided Web servers can locate them." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/entry-script.md +msgid "Entry script for console application is `./yii`." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/entry-script.md +msgid "Entry scripts mainly perform the following work with the help of `ApplicationRunner`:" +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/structure/entry-script.md +msgid "Register [Composer autoloader](https://getcomposer.org/doc/01-basic-usage.md#autoloading);" +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/structure/entry-script.md +msgid "Obtain configuration;" +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/structure/entry-script.md +msgid "Use configuration to initialize a dependency injection container;" +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/structure/entry-script.md +msgid "Get an instance of the request." +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/structure/entry-script.md +msgid "Pass it to `Application` to handle and get a response from it." +msgstr "" + +#. type: Bullet: '* ' +#: ../src/guide/structure/entry-script.md +msgid "With the help of an emitter that transforms a response object into an actual HTTP response that's sent to the client browser." +msgstr "" + +#. type: Title ## +#: ../src/guide/structure/entry-script.md +#, no-wrap +msgid "Web Applications" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/entry-script.md +msgid "The following is the code in the entry script for the application template:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/entry-script.md +#, no-wrap +msgid "" +"debug();\n" +"// Run application:\n" +"$runner->run();\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/structure/entry-script.md +#, no-wrap +msgid "Console Applications" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/entry-script.md +msgid "Similarly, the following is the code for the entry script of a console application:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/entry-script.md +#, no-wrap +msgid "" +"#!/usr/bin/env php\n" +"withDefinitions($config->get('console'))\n" +" ->withProviders($config->get('providers-console'));\n" +"$container = new Container($containerConfig);\n" +"\n" +"/** @var ContainerInterface $container */\n" +"$container = $container->get(ContainerInterface::class);\n" +"\n" +"$application = $container->get(Application::class);\n" +"$exitCode = 1;\n" +"\n" +"try {\n" +" $application->start();\n" +" $exitCode = $application->run(null, new ConsoleBufferedOutput());\n" +"} catch (\\Error $error) {\n" +" $application->renderThrowable($error, new ConsoleBufferedOutput());\n" +"} finally {\n" +" $application->shutdown($exitCode);\n" +" exit($exitCode);\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/structure/entry-script.md +#, no-wrap +msgid "Alternative runtimes" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/entry-script.md +msgid "For alternative runtimes such as FrankenPHP, Rapira, RoadRunner, or Swoole, special entry scripts should be used. See:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/structure/entry-script.md +msgid "[Using Yii with FrankenPHP](../tutorial/using-yii-with-frankenphp.md)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/structure/entry-script.md +msgid "[Using Yii with Rapira](../tutorial/using-yii-with-rapira.md)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/structure/entry-script.md +msgid "[Using Yii with RoadRunner](../tutorial/using-yii-with-roadrunner.md)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/structure/entry-script.md +msgid "[Using Yii with Swoole](../tutorial/using-yii-with-swoole.md)" +msgstr "" diff --git a/_translations/po/pt-BR/guide_structure_middleware.md.po b/_translations/po/pt-BR/guide_structure_middleware.md.po new file mode 100644 index 00000000..9eb85211 --- /dev/null +++ b/_translations/po/pt-BR/guide_structure_middleware.md.po @@ -0,0 +1,315 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-06-29 17:10+0000\n" +"PO-Revision-Date: 2026-06-29 17:10+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/guide/structure/middleware.md +#, no-wrap +msgid "Middleware" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/middleware.md +msgid "Yii works with HTTP using the abstraction layer built around [PSR-7 HTTP message interfaces](https://www.php-fig.org/psr/psr-7/) and [PSR-15 request handler/middleware interfaces](https://www.php-fig.org/psr/psr-15/)." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/middleware.md +msgid "The application is composed of one or several middleware. Middleware runs between request and response. When the URL is requested, the request object is passed to the middleware dispatcher that starts executing middleware one after another. Each middleware, given the request, can:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/structure/middleware.md +msgid "Pass the request to the next middleware performing some work before / after it." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/structure/middleware.md +msgid "Form the response and return it." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/middleware.md +msgid "Depending on middleware used, application behavior may vary significantly." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/middleware.md +msgid "![Middleware](/images/guide/middleware.svg)" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/middleware.md +msgid "In the above each next middleware wraps the previous middleware. Alternatively, it could be presented as follows:" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/middleware.md +msgid "![Middleware](/images/guide/middleware_alternative.svg)" +msgstr "" + +#. type: Title ## +#: ../src/guide/structure/middleware.md +#, no-wrap +msgid "Using middleware" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/middleware.md +msgid "Any [PSR-15](https://www.php-fig.org/psr/psr-15/) compatible middleware could be used with Yii, and there are many. Say, you need to add basic authentication to one of the application URLs. URL-dependent middleware is configured using router, so you need to change the router factory." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/middleware.md +msgid "Authentication middleware is implemented by `middlewares/http-authentication` package so execute `composer require middlewares/http-authentication` in the application root directory." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/middleware.md +msgid "Now register the middleware in DI container configuration `config/web.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/middleware.md +#, no-wrap +msgid "" +" [\n" +" 'class' => \\Middlewares\\BasicAuthentication::class,\n" +" '__construct()' => [\n" +" 'users' => [\n" +" 'foo' => 'bar',\n" +" ],\n" +" ],\n" +" 'realm()' => ['Access to the staging site via basic auth'],\n" +" 'attribute()' => ['username'],\n" +"],\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/middleware.md +msgid "In the `config/routes.php`, add new route:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/middleware.md +#, no-wrap +msgid "" +"action([SiteController::class, 'auth'])\n" +" ->name('site/auth')\n" +" ->prependMiddleware(BasicAuthentication::class)\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/middleware.md +msgid "When configuring routing, you're binding `/basic-auth` URL to a chain of middleware consisting of basic authentication, and the action itself. A chain is a special middleware that executes all the middleware it's configured with." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/middleware.md +msgid "The action itself could be the following:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/middleware.md +#, no-wrap +msgid "" +"public function auth(ServerRequestInterface $request): ResponseInterface\n" +"{\n" +" $response = $this->responseFactory->createResponse();\n" +" $response->getBody()->write('Hi ' . $request->getAttribute('username'));\n" +" return $response;\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/middleware.md +msgid "Basic authentication middleware wrote to request `username` attribute, so you can access the data if needed." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/middleware.md +msgid "To apply middleware to application overall regardless of URL, adjust `config/application.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/middleware.md +#, no-wrap +msgid "" +"return [\n" +" Yiisoft\\Yii\\Http\\Application::class => [\n" +" '__construct()' => [\n" +" 'dispatcher' => DynamicReference::to(static function (Injector $injector) {\n" +" return ($injector->make(MiddlewareDispatcher::class))\n" +" ->withMiddlewares(\n" +" [\n" +" ErrorCatcher::class,\n" +" BasicAuthentication::class,\n" +" SessionMiddleware::class,\n" +" CsrfTokenMiddleware::class,\n" +" Router::class,\n" +" ]\n" +" );\n" +" }),\n" +" 'fallbackHandler' => Reference::to(NotFoundHandler::class),\n" +" ],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/structure/middleware.md +#, no-wrap +msgid "Creating your own middleware" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/middleware.md +msgid "To create middleware, you need to implement a single `process` method of `Psr\\Http\\Server\\MiddlewareInterface`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/middleware.md +#, no-wrap +msgid "public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface;\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/middleware.md +msgid "There are multiple ways to handle a request, and choosing one depends on what the middleware should achieve." +msgstr "" + +#. type: Title ### +#: ../src/guide/structure/middleware.md +#, no-wrap +msgid "Forming a response directly" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/middleware.md +msgid "To respond directly, one needs a response factory passed via constructor:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/middleware.md +#, no-wrap +msgid "" +"responseFactory->createResponse();\n" +" $response->getBody()->write('Hello!');\n" +" return $response;\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/structure/middleware.md +#, no-wrap +msgid "Delegating handling to the next middleware" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/middleware.md +#, no-wrap +msgid "" +"If middleware either isn't intended to form a response or change the request or can't do anything this time,\n" +"handling could be left to the next middleware in the stack: \n" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/middleware.md +#, no-wrap +msgid "" +"public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface\n" +"{\n" +" return $handler->handle($request); \n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/middleware.md +msgid "In case you need to pass data to the next middleware, you can use request attributes:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/middleware.md +#, no-wrap +msgid "" +"$request = $request->withAttribute('answer', 42);\n" +"return $handler->handle($request);\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/middleware.md +msgid "To get it in the next middleware:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/middleware.md +#, no-wrap +msgid "$answer = $request->getAttribute('answer');\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/structure/middleware.md +#, no-wrap +msgid "Capturing response to manipulate it" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/middleware.md +msgid "You may want to capture the response to manipulate it. It could be useful for adding CORS headers, gzipping content, etc." +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/middleware.md +#, no-wrap +msgid "" +"$response = $handler->handle($request);\n" +"// extra handing\n" +"return $response;\n" +msgstr "" diff --git a/_translations/po/pt-BR/guide_structure_module.md.po b/_translations/po/pt-BR/guide_structure_module.md.po new file mode 100644 index 00000000..340d3dbd --- /dev/null +++ b/_translations/po/pt-BR/guide_structure_module.md.po @@ -0,0 +1,448 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-06-02 22:29+0000\n" +"PO-Revision-Date: 2026-06-02 22:29+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Fenced code block (sh) +#: ../src/cookbook/using-yii-in-third-party-apps.md +#: ../src/guide/structure/designing-packages.md +#: ../src/guide/structure/module.md ../src/guide/structure/package.md +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "composer yii-config-rebuild\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/concept/configuration.md +#: ../src/guide/structure/designing-packages.md +#: ../src/guide/structure/module.md +#, no-wrap +msgid "Routes" +msgstr "" + +#. type: Title # +#: ../src/guide/structure/module.md +#, no-wrap +msgid "Modules" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/module.md +msgid "A module is an application part grouped around a business context or a reusable feature. In Yii, this is a design boundary, not a required base class. A module can be:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/structure/module.md +msgid "application code under the `App\\` namespace;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/structure/module.md +msgid "a [Composer package](package.md) installed into `vendor/`;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/structure/module.md +msgid "code that starts in the application and is later extracted into a package." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/module.md +msgid "Use a module when a group of actions, domain services, repositories, event handlers, views, assets, commands, and related configuration changes together and has a name that makes sense to the business." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/module.md +msgid "For example, a blog module can live in an application as:" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/structure/module.md +#, no-wrap +msgid "" +"src/\n" +" Blog/\n" +" Post/\n" +" Post.php\n" +" PostRepositoryInterface.php\n" +" InMemoryPostRepository.php\n" +" Web/\n" +" IndexAction.php\n" +" index.php\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/module.md +msgid "The same structure can later become a Composer package by changing the namespace and adding package metadata and configuration files. See [Designing packages](designing-packages.md) for package-specific details." +msgstr "" + +#. type: Title ## +#: ../src/guide/structure/module.md +#, no-wrap +msgid "Module boundaries" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/module.md +msgid "Keep module code together by context first and by technical type second. This is close to the [vertical slices](../../cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md) approach, but at a larger application-structure boundary. Prefer `App\\Blog\\Post\\PostRepositoryInterface` over a global `App\\Repository\\PostRepositoryInterface` when the repository belongs to blog posts only." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/module.md +msgid "Treat module classes as a public API only when another module is expected to use them. Good public API classes are usually:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/structure/module.md +msgid "commands or queries that express a use case;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/structure/module.md +msgid "DTOs or value objects passed between modules;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/structure/module.md +msgid "interfaces for services another module may call;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/structure/module.md +msgid "events emitted by the module." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/module.md +msgid "Keep implementation classes private to the module namespace. Other modules should not depend on `App\\Blog\\Post\\InMemoryPostRepository` or a controller action directly. They should depend on an interface, a use case class, or an event." +msgstr "" + +#. type: Title ## +#: ../src/guide/structure/module.md +#, no-wrap +msgid "Interfaces between modules" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/module.md +msgid "Put an interface where the contract belongs:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/structure/module.md +msgid "If the interface describes a capability provided by a module, place it in that module. For example, `App\\Blog\\Post\\PostRepositoryInterface` belongs to the blog module because it describes how blog posts are read." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/structure/module.md +msgid "If the interface describes what a module needs from the outside world, place it in the consuming module. For example, `App\\Order\\Customer\\CustomerVerifierInterface` belongs to the order module if orders only need a yes-or-no customer check. The customer module, an application adapter, or a package can provide the implementation." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/module.md +msgid "This keeps dependencies explicit. A module can depend on another module's public contract, but it should not reach into another module's internal implementation classes." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/module.md +msgid "First, define the interface in the module:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/module.md +#, no-wrap +msgid "" +"\n" +" */\n" +" public function findLatest(): array;\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/module.md +msgid "Put the implementation in the same module and bind the interface to it:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/module.md +#, no-wrap +msgid "" +" InMemoryPostRepository::class,\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/module.md +msgid "In the default application template, put this file under `config/common/di/`, for example `config/common/di/blog.php`. The template loads `config/common/di/*.php` into the shared `di` configuration group, so the binding is available to web and console entry points." +msgstr "" + +#. type: Title ## +#: ../src/guide/structure/module.md +#, no-wrap +msgid "Web actions" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/module.md +msgid "Actions belong to the module when they are the web entry point for module behavior:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/module.md +#, no-wrap +msgid "" +"viewRenderer->render(__DIR__ . '/index', [\n" +" 'posts' => $this->posts->findLatest(),\n" +" ]);\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/module.md +msgid "Keep request parsing and response creation in the action. Keep business decisions in the module's domain classes or use case services." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/module.md +msgid "For a small application, add module routes directly to `config/common/routes.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/module.md +#, no-wrap +msgid "" +"routes(\n" +" Route::get('/')\n" +" ->action(Web\\HomePage\\Action::class)\n" +" ->name('home'),\n" +" ),\n" +"\n" +" Group::create('/blog')\n" +" ->routes(\n" +" Route::get('')\n" +" ->action(IndexAction::class)\n" +" ->name('blog/index'),\n" +" ),\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/module.md +msgid "Use module-prefixed route names, such as `blog/index`, to avoid collisions." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/module.md +msgid "If the application has many modules, you can give each module its own route config file. Change the `routes` group in `config/configuration.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/module.md +#, no-wrap +msgid "" +"'routes' => [\n" +" 'common/routes.php',\n" +" 'common/routes/*.php',\n" +"],\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/module.md +msgid "Then create `config/common/routes/blog.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/structure/module.md +#, no-wrap +msgid "" +"routes(\n" +" Route::get('')\n" +" ->action(IndexAction::class)\n" +" ->name('blog/index'),\n" +" ),\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/module.md +msgid "After changing `config/configuration.php` or adding files matched by a config wildcard, rebuild the merge plan:" +msgstr "" + +#. type: Title ## +#: ../src/guide/structure/module.md +#, no-wrap +msgid "Module configuration" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/module.md +msgid "Application modules use the same configuration groups as packages. The difference is where the configuration lives:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/structure/module.md +msgid "application module configuration lives in the root application under `config/`;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/structure/module.md +msgid "package module configuration lives in the package and is declared in `extra.config-plugin`." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/module.md +msgid "Common locations for application module configuration are:" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/structure/module.md +#, no-wrap +msgid "" +"config/\n" +" common/\n" +" di/\n" +" blog.php\n" +" routes/\n" +" blog.php\n" +" params.php\n" +" console/\n" +" params.php\n" +" web/\n" +" params.php\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/module.md +msgid "Put shared service definitions in `common/di/`. Put web-only definitions in `web/di/`. Put console-only parameters or command registrations in `console/params.php`." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/module.md +msgid "When a module grows enough to become reusable, move its PHP classes to a Composer package, move its configuration files to the package `config/` directory, and declare them in the package `composer.json`:" +msgstr "" + +#. type: Fenced code block (json) +#: ../src/guide/structure/module.md +#, no-wrap +msgid "" +"{\n" +" \"extra\": {\n" +" \"config-plugin\": {\n" +" \"di\": \"config/di.php\",\n" +" \"routes\": \"config/routes.php\"\n" +" }\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/module.md +msgid "The application can then override package defaults in its own config files." +msgstr "" + +#. type: Title ## +#: ../src/guide/structure/module.md +#, no-wrap +msgid "Cross-module communication" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/module.md +msgid "Choose the smallest coupling that supports the behavior:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/structure/module.md +msgid "Use constructor injection with an interface for a direct synchronous call." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/structure/module.md +msgid "Use an event when the producer should not know who reacts to something that happened." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/structure/module.md +msgid "Use an application service or use case class when orchestration belongs outside both modules." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/structure/module.md +msgid "Use a package when the module must be reused by more than one application." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/module.md +msgid "Avoid service locator calls and global state inside module classes. Let actions, commands, and services receive their dependencies through constructors so module boundaries stay visible in code and testable in isolation." +msgstr "" diff --git a/_translations/po/pt-BR/guide_structure_overview.md.po b/_translations/po/pt-BR/guide_structure_overview.md.po new file mode 100644 index 00000000..c9cef18a --- /dev/null +++ b/_translations/po/pt-BR/guide_structure_overview.md.po @@ -0,0 +1,160 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-12-24 08:02+0000\n" +"PO-Revision-Date: 2025-12-24 08:02+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/en/guide/structure/overview.md +#: ../src/en/guide/views/script-style-meta.md +#, no-wrap +msgid "Overview" +msgstr "" + +#. type: Plain text +#: ../src/en/guide/structure/overview.md +msgid "Yii applications code is typically grouped into modules by context. In each module there could be grouping by type." +msgstr "" + +#. type: Plain text +#: ../src/en/guide/structure/overview.md +msgid "For example, if the application is an online store, the context could be:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/guide/structure/overview.md +msgid "Customer" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/en/guide/structure/overview.md +msgid "Profile" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/en/guide/structure/overview.md +msgid "Products list" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/en/guide/structure/overview.md +msgid "Checkout" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/guide/structure/overview.md +msgid "Logistics" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/guide/structure/overview.md +msgid "Delivery" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/en/guide/structure/overview.md +msgid "Addresses" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/guide/structure/overview.md +msgid "Helpdesk" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/en/guide/structure/overview.md +msgid "Support" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/en/guide/structure/overview.md +msgid "Claims" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/en/guide/structure/overview.md +msgid "Returns" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/guide/structure/overview.md +msgid "Accounting" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/en/guide/structure/overview.md +msgid "Transactions" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/en/guide/structure/overview.md +msgid "Taxes" +msgstr "" + +#. type: Plain text +#: ../src/en/guide/structure/overview.md +msgid "For a \"Customer\" context, residing under `App\\Customer` namespace, structure would be:" +msgstr "" + +#. type: Fenced code block +#: ../src/en/guide/structure/overview.md +#, no-wrap +msgid "" +"App/\n" +" Customer/ <-- module namespace\n" +" Entity/\n" +" Customer.php <-- entity shared by \"Profile\" and \"Checkout\"\n" +" Profile/\n" +" Widget/\n" +" Gravatar.php\n" +" ProfileRepository.php <-- repository is usually specific to context\n" +" ProfileController.php <-- \"Customer\\Profile\" entry point\n" +" ProductList/ <-- module namespace \n" +" Entity/ <-- entities specific to \"Customer\\ProductList\"\n" +" Category.php\n" +" Product.php\n" +" ProductsListController.php <-- \"Customer\\ProductList\" entry point\n" +" Checkout/ <-- module namespace\n" +" CheckoutController.php\n" +msgstr "" + +#. type: Plain text +#: ../src/en/guide/structure/overview.md +msgid "A context may include sub-contexts. If a class is shared by multiple contexts, it's moved to the ancestor of both contexts." +msgstr "" + +#. type: Plain text +#: ../src/en/guide/structure/overview.md +msgid "A context may have [an entry point known as \"action\" or \"controller\"](action.md). Its job is to take [a request instance](../runtime/request.md), pass it to [domain layer](domain.md) in a suitable format, and create [a response](../runtime/response.md) based on domain layer return." +msgstr "" + +#. type: Plain text +#: ../src/en/guide/structure/overview.md +msgid "Besides, Yii applications also have the following:" +msgstr "" + +#. type: Bullet: '* ' +#: ../src/en/guide/structure/overview.md +msgid "[entry scripts](entry-script.md): they're PHP scripts that are directly accessible by end users. They're responsible for starting a request handling cycle. Typically, a single entry script is handling the whole application." +msgstr "" + +#. type: Bullet: '* ' +#: ../src/en/guide/structure/overview.md +msgid "[services](service.md): they're typically stateless objects registered within dependency container and provide various action methods." +msgstr "" + +#. type: Bullet: '* ' +#: ../src/en/guide/structure/overview.md +msgid "[middleware](middleware.md): they represent a code that needs to be invoked before and after the actual handling of each request by action handlers." +msgstr "" diff --git a/_translations/po/pt-BR/guide_structure_package.md.po b/_translations/po/pt-BR/guide_structure_package.md.po new file mode 100644 index 00000000..57ba58ef --- /dev/null +++ b/_translations/po/pt-BR/guide_structure_package.md.po @@ -0,0 +1,239 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-06-05 20:33+0000\n" +"PO-Revision-Date: 2026-06-05 20:33+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Fenced code block (sh) +#: ../src/cookbook/using-yii-in-third-party-apps.md +#: ../src/guide/structure/designing-packages.md +#: ../src/guide/structure/module.md ../src/guide/structure/package.md +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "composer yii-config-rebuild\n" +msgstr "" + +#. type: Title # +#: ../src/guide/structure/package.md +#, no-wrap +msgid "Using packages" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/package.md +msgid "Reusable code is distributed as [Composer packages](https://getcomposer.org/doc/05-repositories.md#package). A package can be an infrastructure library, a Yii integration, a reusable feature, or a module representing an application context." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/package.md +msgid "This page explains how to use packages in an application. To create a Yii-aware package, see [Designing packages for Yii applications](designing-packages.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/structure/package.md +#, no-wrap +msgid "Installing packages" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/package.md +msgid "By default, Composer installs packages registered on [Packagist](https://packagist.org/), the main repository for open source PHP packages." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/package.md +msgid "Install a package with:" +msgstr "" + +#. type: Fenced code block (sh) +#: ../src/guide/structure/package.md +#, no-wrap +msgid "composer require vendor-name/package-name\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/package.md +msgid "Composer updates two files:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/structure/package.md +msgid "`composer.json` stores the package name and version constraint." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/structure/package.md +msgid "`composer.lock` stores the exact versions installed." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/package.md +msgid "Commit both files so other environments install the same dependency versions." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/package.md +msgid "Installed packages are stored in the application `vendor/` directory." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/package.md +#, no-wrap +msgid "" +"> [!WARNING]\n" +"> Never edit files in `vendor/` directly. Change application configuration, extend classes, decorate services, or\n" +"> contribute fixes to the package instead.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/package.md +msgid "Package classes are available through Composer autoloading after installation. See [Autoloading](../concept/autoloading.md) for details." +msgstr "" + +#. type: Title ## +#: ../src/guide/structure/package.md +#, no-wrap +msgid "Updating packages" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/package.md +msgid "Update a package within the version constraint recorded in `composer.json`:" +msgstr "" + +#. type: Fenced code block (sh) +#: ../src/guide/structure/package.md +#, no-wrap +msgid "composer update vendor-name/package-name\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/package.md +msgid "Change the accepted version constraint with `composer require`:" +msgstr "" + +#. type: Fenced code block (sh) +#: ../src/guide/structure/package.md +#, no-wrap +msgid "composer require vendor-name/package-name:^2.0\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/package.md +msgid "After updating a Yii-aware package, Composer rebuilds Yii's configuration merge plan. If you changed configuration group mappings manually, rebuild it explicitly:" +msgstr "" + +#. type: Title ## +#: ../src/guide/structure/package.md +#, no-wrap +msgid "Removing packages" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/package.md +msgid "Remove a package with:" +msgstr "" + +#. type: Fenced code block (sh) +#: ../src/guide/structure/package.md +#, no-wrap +msgid "composer remove vendor-name/package-name\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/package.md +msgid "Then remove application code and configuration that referenced classes, services, routes, commands, assets, migrations, or translations from that package." +msgstr "" + +#. type: Title ## +#: ../src/guide/structure/package.md +#, no-wrap +msgid "Private packages" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/package.md +msgid "For private code, configure Composer repositories in the application `composer.json`. Common options are:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/structure/package.md +msgid "`vcs` for a Git repository." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/structure/package.md +msgid "`path` for a local package during development." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/structure/package.md +msgid "`composer` for a private Composer repository." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/package.md +msgid "For example, to work with a package located next to the application:" +msgstr "" + +#. type: Fenced code block (json) +#: ../src/guide/structure/package.md +#, no-wrap +msgid "" +"{\n" +" \"repositories\": [\n" +" {\n" +" \"type\": \"path\",\n" +" \"url\": \"../packages/blog\"\n" +" }\n" +" ]\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/package.md +msgid "Then install it normally:" +msgstr "" + +#. type: Fenced code block (sh) +#: ../src/guide/structure/package.md +#, no-wrap +msgid "composer require vendor/blog\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/package.md +msgid "Read more in the [Composer repository documentation](https://getcomposer.org/doc/05-repositories.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/structure/package.md +#, no-wrap +msgid "Package configuration" +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/package.md +msgid "Some Yii packages provide default configuration through [yiisoft/config](https://github.com/yiisoft/config). After installation, the package configuration becomes part of the vendor layer and the application can override it in the root package configuration." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/package.md +msgid "Prefer partial overrides in application config files over copying whole package config files. For example, override only the parameter or service definition you need." +msgstr "" + +#. type: Plain text +#: ../src/guide/structure/package.md +msgid "For more details, see [Configuration](../concept/configuration.md) and [Designing packages for Yii applications](designing-packages.md)." +msgstr "" diff --git a/_translations/po/pt-BR/guide_testing_end-to-end.md.po b/_translations/po/pt-BR/guide_testing_end-to-end.md.po new file mode 100644 index 00000000..3877a245 --- /dev/null +++ b/_translations/po/pt-BR/guide_testing_end-to-end.md.po @@ -0,0 +1,246 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-05-08 08:49+0000\n" +"PO-Revision-Date: 2026-05-08 08:49+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md ../src/guide/testing/end-to-end.md +#: ../src/guide/testing/environment-setup.md +#: ../src/guide/testing/quality-tools.md +msgid "With Docker:" +msgstr "" + +#. type: Title # +#: ../src/guide/testing/end-to-end.md +#, no-wrap +msgid "End-to-end tests" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/end-to-end.md +msgid "The Yii application template uses the `Web` Codeception suite for tests that go through an HTTP server. These tests live in `tests/Web` and use `App\\Tests\\Support\\WebTester`." +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/end-to-end.md +msgid "Use web tests for user-visible HTTP behavior: pages, links, forms, redirects, cookies, and error pages." +msgstr "" + +#. type: Title ## +#: ../src/guide/testing/end-to-end.md +#, no-wrap +msgid "Web suite" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/end-to-end.md +msgid "The template configures `tests/Web.suite.yml` like this:" +msgstr "" + +#. type: Fenced code block (yaml) +#: ../src/guide/testing/end-to-end.md ../src/guide/testing/environment-setup.md +#, no-wrap +msgid "" +"actor: WebTester\n" +"extensions:\n" +" enabled:\n" +" - Codeception\\Extension\\RunProcess:\n" +" 0: composer serve\n" +" sleep: 3\n" +"modules:\n" +" enabled:\n" +" - PhpBrowser:\n" +" url: http://127.0.0.1:8080\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/end-to-end.md +msgid "`RunProcess` starts the application with the Composer `serve` script. `PhpBrowser` sends HTTP requests to the server." +msgstr "" + +#. type: Title ## +#: ../src/guide/testing/end-to-end.md ../src/guide/testing/functional.md +#, no-wrap +msgid "Test a page" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/end-to-end.md +msgid "The template includes `tests/Web/HomePageCest.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/testing/end-to-end.md +#, no-wrap +msgid "" +"wantTo('home page works.');\n" +" $I->amOnPage('/');\n" +" $I->expectTo('see page home.');\n" +" $I->see('Hello!');\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/end-to-end.md +msgid "Run the web suite locally:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/testing/end-to-end.md +#, no-wrap +msgid "APP_ENV=test vendor/bin/codecept run Web\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/end-to-end.md ../src/guide/testing/unit.md +msgid "Run only this test:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/testing/end-to-end.md +#, no-wrap +msgid "APP_ENV=test vendor/bin/codecept run Web HomePageCest\n" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/testing/end-to-end.md +#, no-wrap +msgid "make test Web\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/testing/end-to-end.md +#, no-wrap +msgid "Test links and error pages" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/end-to-end.md +msgid "Use the same actor methods for navigation and response assertions:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/testing/end-to-end.md +#, no-wrap +msgid "" +"wantTo('see 404 page.');\n" +" $I->amOnPage('/non-existent-page');\n" +" $I->canSeeResponseCodeIs(404);\n" +" $I->see('404');\n" +" $I->see('The page /non-existent-page not found.');\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/testing/end-to-end.md +#, no-wrap +msgid "Smoke test with curl" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/end-to-end.md +msgid "For a deployment smoke test, start the application and check one URL:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/testing/end-to-end.md +#, no-wrap +msgid "APP_ENV=test ./yii serve --port=8080\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/end-to-end.md +msgid "In another terminal:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/testing/end-to-end.md +#, no-wrap +msgid "" +"curl -fsS http://127.0.0.1:8080/ > /tmp/home.html\n" +"grep -q \"Hello!\" /tmp/home.html\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/testing/end-to-end.md ../src/guide/testing/functional.md +#, no-wrap +msgid "Reset state" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/end-to-end.md +msgid "Web tests use real infrastructure, so reset state before each scenario:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/testing/end-to-end.md +msgid "Load only the records required by the scenario." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/testing/end-to-end.md +msgid "Clear session and cookie storage." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/testing/end-to-end.md +msgid "Clear generated files and outgoing messages." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/testing/end-to-end.md +msgid "Stop background workers, or make their effects deterministic." +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/end-to-end.md +msgid "If the scenario changes a database, reset it in the Cest `_before()` hook or in a project-specific helper:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/testing/end-to-end.md +#, no-wrap +msgid "" +"public function _before(WebTester $I): void\n" +"{\n" +" // Reset database tables, files, queues, and outgoing messages.\n" +"}\n" +msgstr "" diff --git a/_translations/po/pt-BR/guide_testing_environment-setup.md.po b/_translations/po/pt-BR/guide_testing_environment-setup.md.po new file mode 100644 index 00000000..d1cb7c48 --- /dev/null +++ b/_translations/po/pt-BR/guide_testing_environment-setup.md.po @@ -0,0 +1,365 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-05-08 08:49+0000\n" +"PO-Revision-Date: 2026-05-08 08:49+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md ../src/guide/testing/end-to-end.md +#: ../src/guide/testing/environment-setup.md +#: ../src/guide/testing/quality-tools.md +msgid "With Docker:" +msgstr "" + +#. type: Fenced code block (yaml) +#: ../src/guide/testing/end-to-end.md ../src/guide/testing/environment-setup.md +#, no-wrap +msgid "" +"actor: WebTester\n" +"extensions:\n" +" enabled:\n" +" - Codeception\\Extension\\RunProcess:\n" +" 0: composer serve\n" +" sleep: 3\n" +"modules:\n" +" enabled:\n" +" - PhpBrowser:\n" +" url: http://127.0.0.1:8080\n" +msgstr "" + +#. type: Title # +#: ../src/guide/testing/environment-setup.md +#, no-wrap +msgid "Testing environment setup" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/environment-setup.md +msgid "The Yii application template has the test environment configured. Use this page when creating a new project from the template, restoring removed test files, or adding a new suite." +msgstr "" + +#. type: Title ## +#: ../src/guide/testing/environment-setup.md +#, no-wrap +msgid "Composer configuration" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/environment-setup.md +msgid "The template requires Codeception, PHPUnit, and the modules used by the suites:" +msgstr "" + +#. type: Fenced code block (json) +#: ../src/guide/testing/environment-setup.md +#, no-wrap +msgid "" +"{\n" +" \"require-dev\": {\n" +" \"codeception/codeception\": \"^5.3\",\n" +" \"codeception/module-asserts\": \"^3.2\",\n" +" \"codeception/module-cli\": \"^2.0\",\n" +" \"codeception/module-phpbrowser\": \"^3.0\",\n" +" \"phpunit/phpunit\": \"^11.5\"\n" +" },\n" +" \"autoload-dev\": {\n" +" \"psr-4\": {\n" +" \"App\\\\Tests\\\\\": \"tests\"\n" +" }\n" +" },\n" +" \"scripts\": {\n" +" \"test\": \"codecept run\"\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/environment-setup.md +msgid "If these entries are already in your project, keep the installed versions from `composer.lock`." +msgstr "" + +#. type: Title ## +#: ../src/guide/testing/environment-setup.md +#, no-wrap +msgid "Main Codeception file" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/environment-setup.md +msgid "The root `codeception.yml` defines the test namespace, paths, bootstrap file, and coverage source:" +msgstr "" + +#. type: Fenced code block (yaml) +#: ../src/guide/testing/environment-setup.md +#, no-wrap +msgid "" +"namespace: App\\Tests\n" +"support_namespace: Support\n" +"bootstrap: bootstrap.php\n" +"\n" +"settings:\n" +" shuffle: true\n" +" colors: true\n" +"\n" +"paths:\n" +" tests: tests\n" +" output: tests/_output\n" +" data: tests/Support/Data\n" +" support: tests/Support\n" +"\n" +"coverage:\n" +" enabled: true\n" +" show_uncovered: true\n" +" show_only_summary: true\n" +" include:\n" +" - src/*\n" +" - public/index.php\n" +" - yii\n" +"\n" +"extensions:\n" +" enabled:\n" +" - Codeception\\Extension\\RunFailed\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/environment-setup.md +msgid "`tests/bootstrap.php` prepares the application environment for every suite:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/testing/environment-setup.md +#, no-wrap +msgid "" +"runAndGetResponse($request);\n" +" $body = $response->getBody();\n" +" if ($body->isSeekable()) {\n" +" $body->rewind();\n" +" }\n" +"\n" +" return $response;\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/functional.md +msgid "The template includes `tests/Functional/HomePageCest.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/testing/functional.md +#, no-wrap +msgid "" +"sendRequest(\n" +" new ServerRequest(uri: '/'),\n" +" );\n" +"\n" +" assertSame(200, $response->getStatusCode());\n" +" assertStringContainsString(\n" +" 'Don\\'t forget to check the guide',\n" +" $response->getBody()->getContents(),\n" +" );\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/functional.md ../src/guide/testing/unit.md +msgid "Run it:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/testing/functional.md +#, no-wrap +msgid "" +"APP_ENV=test vendor/bin/codecept run Functional\n" +"APP_ENV=test vendor/bin/codecept run Functional HomePageCest\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/testing/functional.md +#, no-wrap +msgid "Send request data" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/functional.md +msgid "Use PSR-7 methods to model the request:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/testing/functional.md +#, no-wrap +msgid "" +"$request = (new ServerRequest(uri: '/contact', method: 'POST'))\n" +" ->withHeader('Content-Type', 'application/x-www-form-urlencoded')\n" +" ->withParsedBody([\n" +" 'ContactForm' => [\n" +" 'name' => 'Sam',\n" +" 'email' => 'sam@example.test',\n" +" 'body' => 'Hello.',\n" +" ],\n" +" ]);\n" +"\n" +"$response = $tester->sendRequest($request);\n" +"\n" +"assertSame(302, $response->getStatusCode());\n" +"assertSame('/contact/sent', $response->getHeaderLine('Location'));\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/functional.md +msgid "For JSON APIs, write the JSON body into a PSR-7 stream and set `Content-Type: application/json`." +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/functional.md +msgid "Functional tests often touch runtime files, sessions, cache, and a database. Reset changed state in the Cest `_before()` hook or in a project helper:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/testing/functional.md +#, no-wrap +msgid "" +"public function _before(FunctionalTester $tester): void\n" +"{\n" +" // Reset database tables, cache pools, queues, and outgoing messages.\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/functional.md +msgid "Keep pure domain rules in unit tests. Put request and response behavior in functional tests." +msgstr "" diff --git a/_translations/po/pt-BR/guide_testing_overview.md.po b/_translations/po/pt-BR/guide_testing_overview.md.po new file mode 100644 index 00000000..e04594f1 --- /dev/null +++ b/_translations/po/pt-BR/guide_testing_overview.md.po @@ -0,0 +1,229 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-05-08 08:49+0000\n" +"PO-Revision-Date: 2026-05-08 08:49+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ### +#: ../src/cookbook/making-http-requests.md ../src/guide/index.md +#: ../src/guide/testing/overview.md ../src/guide/tutorial/docker.md +#, no-wrap +msgid "Testing" +msgstr "Testes" + +#. type: Fenced code block (shell) +#: ../src/guide/testing/environment-setup.md ../src/guide/testing/overview.md +#, no-wrap +msgid "APP_ENV=test vendor/bin/codecept run\n" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/testing/environment-setup.md ../src/guide/testing/overview.md +#, no-wrap +msgid "vendor/bin/codecept build\n" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/testing/environment-setup.md ../src/guide/testing/overview.md +#, no-wrap +msgid "make codecept build\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/overview.md +msgid "The Yii application template includes a ready test setup. It uses Codeception with PHPUnit assertions and has four suites:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/testing/overview.md +msgid "`Unit` for isolated PHP classes." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/testing/overview.md +msgid "`Functional` for application code called in the same PHP process." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/testing/overview.md +msgid "`Web` for requests sent through an HTTP server." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/testing/overview.md +msgid "`Console` for console commands." +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/overview.md +msgid "The main files are:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/testing/overview.md +msgid "`codeception.yml`." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/testing/overview.md +msgid "`tests/bootstrap.php`." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/testing/overview.md +msgid "`tests/Unit.suite.yml`." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/testing/overview.md +msgid "`tests/Functional.suite.yml`." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/testing/overview.md +msgid "`tests/Web.suite.yml`." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/testing/overview.md +msgid "`tests/Console.suite.yml`." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/testing/overview.md +msgid "`tests/Support/*Tester.php`." +msgstr "" + +#. type: Title ## +#: ../src/guide/testing/overview.md +#, no-wrap +msgid "Run tests locally" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/overview.md +msgid "Build actor classes after installing dependencies or changing a suite:" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/overview.md +msgid "Run all tests:" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/overview.md +msgid "The template also defines a Composer script:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/testing/overview.md +#, no-wrap +msgid "APP_ENV=test composer test\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/overview.md +msgid "Run one suite:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/testing/overview.md +#, no-wrap +msgid "" +"APP_ENV=test vendor/bin/codecept run Unit\n" +"APP_ENV=test vendor/bin/codecept run Functional\n" +"APP_ENV=test vendor/bin/codecept run Web\n" +"APP_ENV=test vendor/bin/codecept run Console\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/overview.md +msgid "Run one test class or method:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/testing/overview.md +#, no-wrap +msgid "" +"APP_ENV=test vendor/bin/codecept run Functional HomePageCest\n" +"APP_ENV=test vendor/bin/codecept run Functional HomePageCest:base\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/overview.md +msgid "`APP_ENV=test` is required for local commands because `tests/bootstrap.php` prepares the application environment before tests run." +msgstr "" + +#. type: Title ## +#: ../src/guide/testing/overview.md +#, no-wrap +msgid "Run tests in Docker" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/overview.md +msgid "Build actor classes:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/testing/overview.md +#, no-wrap +msgid "make test\n" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/testing/overview.md +#, no-wrap +msgid "" +"make test Unit\n" +"make test Functional\n" +"make test Web\n" +"make test Console\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/overview.md +msgid "The Docker test environment reads `docker/test/.env`, where `APP_ENV=test` is already set." +msgstr "" + +#. type: Title ## +#: ../src/guide/testing/overview.md +#, no-wrap +msgid "Choose a suite" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/overview.md +msgid "Start with unit tests for code that has no framework boundary: value objects, validators, domain services, and transformers." +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/overview.md +msgid "Use functional tests when code needs Yii configuration, dependency injection, routing, middleware, request handling, or template rendering." +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/overview.md +msgid "Use web tests for behavior that must go through an HTTP server: status codes, links, redirects, cookies, and rendered pages as seen by a client." +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/overview.md +msgid "Use console tests for commands in `src/Console`." +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/overview.md +msgid "Run static analysis in CI and before changing shared contracts." +msgstr "" diff --git a/_translations/po/pt-BR/guide_testing_quality-tools.md.po b/_translations/po/pt-BR/guide_testing_quality-tools.md.po new file mode 100644 index 00000000..16af8566 --- /dev/null +++ b/_translations/po/pt-BR/guide_testing_quality-tools.md.po @@ -0,0 +1,215 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-05-08 08:49+0000\n" +"PO-Revision-Date: 2026-05-08 08:49+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Plain text +#: ../src/cookbook/configuring-xdebug.md ../src/guide/testing/end-to-end.md +#: ../src/guide/testing/environment-setup.md +#: ../src/guide/testing/quality-tools.md +msgid "With Docker:" +msgstr "" + +#. type: Title # +#: ../src/guide/testing/quality-tools.md +#, no-wrap +msgid "Static analysis and code quality" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/quality-tools.md +msgid "The Yii application template includes static analysis and code quality tools alongside the test suite." +msgstr "" + +#. type: Title ## +#: ../src/guide/testing/quality-tools.md +#, no-wrap +msgid "Psalm" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/quality-tools.md +msgid "Run Psalm locally:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/testing/quality-tools.md +#, no-wrap +msgid "vendor/bin/psalm\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/quality-tools.md +msgid "Run Psalm in Docker:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/testing/quality-tools.md +#, no-wrap +msgid "make psalm\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/quality-tools.md +msgid "The template stores Psalm configuration in `psalm.xml`. The GitHub Actions workflow runs Psalm for supported PHP versions." +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/quality-tools.md +msgid "When Psalm reports an issue, fix the code or add a precise type annotation. Keep suppressions narrow and local to the line or method that needs them." +msgstr "" + +#. type: Title ## +#: ../src/guide/testing/quality-tools.md +#, no-wrap +msgid "Composer Dependency Analyser" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/quality-tools.md +msgid "Composer Dependency Analyser checks that `composer.json` matches the classes used by the application." +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/quality-tools.md +msgid "Run it locally:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/testing/quality-tools.md +#, no-wrap +msgid "vendor/bin/composer-dependency-analyser --config=composer-dependency-analyser.php\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/quality-tools.md +msgid "Run it in Docker:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/testing/quality-tools.md +#, no-wrap +msgid "make composer-dependency-analyser\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/quality-tools.md +msgid "Use this check after adding or removing package usage in `src`, `config`, or `tests`." +msgstr "" + +#. type: Title ## +#: ../src/guide/testing/quality-tools.md +#, no-wrap +msgid "PHP CS Fixer" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/quality-tools.md +msgid "PHP CS Fixer applies the project coding style from `.php-cs-fixer.php`." +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/testing/quality-tools.md +#, no-wrap +msgid "vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.php --diff\n" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/testing/quality-tools.md +#, no-wrap +msgid "make cs-fix\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/quality-tools.md +msgid "Commit formatting changes together with the code that needs them." +msgstr "" + +#. type: Title ## +#: ../src/guide/testing/quality-tools.md +#, no-wrap +msgid "Rector" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/quality-tools.md +msgid "Rector applies configured code upgrades and refactorings from `rector.php`." +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/quality-tools.md +msgid "Preview changes locally:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/testing/quality-tools.md +#, no-wrap +msgid "vendor/bin/rector --dry-run\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/quality-tools.md +msgid "Apply changes locally:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/testing/quality-tools.md +#, no-wrap +msgid "vendor/bin/rector\n" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/testing/quality-tools.md +#, no-wrap +msgid "make rector\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/quality-tools.md +msgid "Review Rector changes before committing them. Automated refactoring can change behavior when custom rules or broad paths are configured." +msgstr "" + +#. type: Title ## +#: ../src/guide/testing/quality-tools.md +#, no-wrap +msgid "Pull request checks" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/quality-tools.md +msgid "A practical local check before opening a pull request is:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/testing/quality-tools.md +#, no-wrap +msgid "" +"APP_ENV=test vendor/bin/codecept build\n" +"APP_ENV=test vendor/bin/codecept run\n" +"vendor/bin/psalm\n" +"vendor/bin/composer-dependency-analyser --config=composer-dependency-analyser.php\n" +"vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.php --diff\n" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/testing/quality-tools.md +#, no-wrap +msgid "" +"make codecept build\n" +"make test\n" +"make psalm\n" +"make composer-dependency-analyser\n" +"make cs-fix\n" +msgstr "" diff --git a/_translations/po/pt-BR/guide_testing_unit.md.po b/_translations/po/pt-BR/guide_testing_unit.md.po new file mode 100644 index 00000000..076caf5c --- /dev/null +++ b/_translations/po/pt-BR/guide_testing_unit.md.po @@ -0,0 +1,304 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-05-08 08:49+0000\n" +"PO-Revision-Date: 2026-05-08 08:49+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Plain text +#: ../src/guide/testing/end-to-end.md ../src/guide/testing/unit.md +msgid "Run only this test:" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/functional.md ../src/guide/testing/unit.md +msgid "Run it:" +msgstr "" + +#. type: Title # +#: ../src/guide/testing/unit.md +#, no-wrap +msgid "Unit tests" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/unit.md +msgid "Unit tests check a small piece of PHP code directly. In the Yii application template they live in `tests/Unit` and run through the `Unit` Codeception suite." +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/unit.md +msgid "The template includes `tests/Unit/EnvironmentTest.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/testing/unit.md +#, no-wrap +msgid "" +"generate('Hello, Yii3!');\n" +"\n" +" assertSame('hello-yii3', $slug);\n" +" }\n" +"}\n" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/testing/unit.md +#, no-wrap +msgid "APP_ENV=test vendor/bin/codecept run Unit SlugGeneratorTest\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/testing/unit.md +#, no-wrap +msgid "Test services with dependencies" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/unit.md +msgid "Pass dependencies through the constructor and use test doubles for I/O." +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/unit.md +msgid "Create `src/Clock/ClockInterface.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/testing/unit.md +#, no-wrap +msgid "" +"clock->now());\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/unit.md +msgid "Create `tests/Unit/PublishPostTest.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/testing/unit.md +#, no-wrap +msgid "" +"publish('Testing Yii');\n" +"\n" +" assertSame('Testing Yii', $post->title);\n" +" assertSame('2026-05-07 10:00:00', $post->publishedAt->format('Y-m-d H:i:s'));\n" +" }\n" +"}\n" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/testing/unit.md +#, no-wrap +msgid "APP_ENV=test vendor/bin/codecept run Unit PublishPostTest\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/testing/unit.md +msgid "Keep unit tests focused on one class or one small collaboration. Use functional tests when the behavior depends on Yii configuration, dependency injection, routing, or middleware." +msgstr "" diff --git a/_translations/po/pt-BR/guide_tutorial_console-applications.md.po b/_translations/po/pt-BR/guide_tutorial_console-applications.md.po new file mode 100644 index 00000000..19795c68 --- /dev/null +++ b/_translations/po/pt-BR/guide_tutorial_console-applications.md.po @@ -0,0 +1,155 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-03-30 08:11+0000\n" +"PO-Revision-Date: 2026-03-30 08:11+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md +#: ../src/guide/concept/autoloading.md ../src/guide/security/best-practices.md +#: ../src/guide/structure/domain.md +#: ../src/guide/tutorial/console-applications.md +#: ../src/internals/004-namespaces.md ../src/internals/007-exceptions.md +#: ../src/internals/008-interfaces.md +#, no-wrap +msgid "References" +msgstr "" + +#. type: Title ## +#: ../src/guide/index.md ../src/guide/tutorial/console-applications.md +#, no-wrap +msgid "Getting started" +msgstr "Primeiros passos" + +#. type: Title # +#: ../src/guide/tutorial/console-applications.md +#, no-wrap +msgid "Console applications" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/console-applications.md +msgid "Console applications are mainly used to create utility, background processing and maintenance tasks." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/console-applications.md +msgid "If you're using [yiisoft/app](https://github.com/yiisoft/app) or [yiisoft/app-api](https://github.com/yiisoft/app-api), console support is already included. You can access the entry point as:" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/tutorial/console-applications.md +#, no-wrap +msgid "./yii\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/console-applications.md +msgid "If you want a standalone console-only application, use the [yiisoft/app-console](https://github.com/yiisoft/app-console) project template:" +msgstr "" + +#. type: Fenced code block (sh) +#: ../src/guide/tutorial/console-applications.md +#, no-wrap +msgid "composer create-project yiisoft/app-console your-project\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/console-applications.md +msgid "To add console support to an existing project from scratch, refer to the [yiisoft/yii-console package documentation](https://github.com/yiisoft/yii-console)." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/console-applications.md +msgid "Out of the box only `serve` command is available. It's starting PHP built-in web server to serve the application locally." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/console-applications.md +msgid "Commands are executed with `symfony/console`. To create your own console command, you need to define a command:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/tutorial/console-applications.md +#, no-wrap +msgid "" +"setHelp('This command serves for demo purpose')\n" +" ->addArgument('name', InputArgument::OPTIONAL, 'Name to greet', 'anonymous');\n" +" }\n" +"\n" +" protected function execute(InputInterface $input, OutputInterface $output): int\n" +" {\n" +" $io = new SymfonyStyle($input, $output);\n" +"\n" +" $name = $input->getArgument('name');\n" +" $io->success(\"Hello, $name!\");\n" +" return ExitCode::OK;\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/console-applications.md +msgid "Now register the command in `config/params.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/tutorial/console-applications.md +#, no-wrap +msgid "" +"return [\n" +" 'yiisoft/yii-console' => [\n" +" 'commands' => [\n" +" 'demo:hello' => App\\Demo\\HelloCommand::class,\n" +" ],\n" +" ], \n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/console-applications.md +msgid "After it's done, the command could be executed as" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/tutorial/console-applications.md +#, no-wrap +msgid "./yii demo:hello Alice\n" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/console-applications.md +msgid "[Symfony Console component guide](https://symfony.com/doc/current/components/console.html)" +msgstr "" diff --git a/_translations/po/pt-BR/guide_tutorial_docker.md.po b/_translations/po/pt-BR/guide_tutorial_docker.md.po new file mode 100644 index 00000000..4d93a378 --- /dev/null +++ b/_translations/po/pt-BR/guide_tutorial_docker.md.po @@ -0,0 +1,709 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-04-07 16:34+0000\n" +"PO-Revision-Date: 2026-04-07 16:34+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ### +#: ../src/guide/index.md ../src/guide/tutorial/docker.md +#, no-wrap +msgid "Testing" +msgstr "Testes" + +#. type: Title # +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "Docker in Application Templates" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +msgid "Both [yiisoft/app](https://github.com/yiisoft/app) and [yiisoft/app-api](https://github.com/yiisoft/app-api) come with a ready-to-use Docker setup based on [FrankenPHP](https://frankenphp.dev/) with Caddy as the built-in web server. The setup covers local development, testing, and production deployment through a set of environment files, Docker Compose configurations, a multi-stage Dockerfile, and a `Makefile` that wraps common operations." +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "Docker directory overview" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +msgid "All Docker-related files live under the `docker/` directory:" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "" +"docker/\n" +"├── .env # Compose-level variables (stack name, ports, image names)\n" +"├── Dockerfile # Multi-stage image definition\n" +"├── compose.yml # Base Compose file (shared anchor for all environments)\n" +"├── dev/\n" +"│ ├── .env # Application environment variables for development\n" +"│ ├── .gitignore # Excludes override.env from version control\n" +"│ ├── compose.yml # Development-specific Compose overrides\n" +"│ └── override.env.example # Optional developer-local overrides template\n" +"├── test/\n" +"│ ├── .env # Application environment variables for testing\n" +"│ ├── .gitignore # Excludes override.env from version control\n" +"│ └── compose.yml # Test-specific Compose overrides\n" +"└── prod/\n" +" ├── .env # Application environment variables for production\n" +" ├── .gitignore # Excludes override.env from version control\n" +" └── compose.yml # Production-specific Compose overrides (Docker Swarm)\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +msgid "Each subdirectory (`dev/`, `test/`, `prod/`) corresponds to an environment stage and contains its own `.env` file with application-level configuration and a `compose.yml` that extends the base `docker/compose.yml`." +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "Environment files" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +msgid "The templates use two separate environment systems that serve different purposes and different runtimes." +msgstr "" + +#. type: Title ### +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid ".env.example (project root)" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +msgid "The project root contains a `.env.example` file that serves as a template for local development **without Docker**:" +msgstr "" + +#. type: Fenced code block (ini) +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "" +"# Local environment configuration.\n" +"# Copy this file to .env and adjust as needed.\n" +"# In production, set environment variables via server or container configuration instead.\n" +"APP_ENV=dev\n" +"APP_DEBUG=true\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +msgid "Copy it to create your local configuration file:" +msgstr "" + +#. type: Fenced code block (sh) +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "cp .env.example .env\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +msgid "The `.env` file is loaded automatically by `src/bootstrap.php` using [phpdotenv](https://github.com/vlucas/phpdotenv) only when `APP_ENV` is not already present in the process environment. This means **Docker-provided environment variables always take precedence** over the root `.env` file — both workflows can coexist safely in the same project directory." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> `phpdotenv` is a development dependency and is not installed in production\n" +"> (`composer install --no-dev`), so the root `.env` file has no effect on production containers.\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "docker/.env" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +msgid "This file contains variables used by the Compose files themselves — they are **not** passed into the running application container:" +msgstr "" + +#. type: Fenced code block (ini) +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "" +"# Variables for compose.yml files. Not available in the app.\n" +"\n" +"STACK_NAME=app\n" +"\n" +"# Development\n" +"\n" +"DEV_PORT=80\n" +"\n" +"# Production\n" +"\n" +"PROD_HOST=app.example.com\n" +"PROD_SSH=\"ssh://docker-web\"\n" +"\n" +"IMAGE=app\n" +"IMAGE_TAG=latest\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "" +"| Variable | Purpose |\n" +"|--------------|-------------------------------------------------------------------------|\n" +"| `STACK_NAME` | Docker Compose project name and Docker Swarm stack name. |\n" +"| `DEV_PORT` | Host port to expose the application on in development (`make up`). |\n" +"| `PROD_HOST` | Hostname used by Caddy labels for automatic HTTPS in production. |\n" +"| `PROD_SSH` | Remote Docker host for deploying to a Swarm node via SSH. |\n" +"| `IMAGE` | Docker image name used during build and push. |\n" +"| `IMAGE_TAG` | Docker image tag (`latest` by default; use a version string in CI/CD). |\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "docker/dev/.env" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +msgid "Contains application environment variables injected into the development container at runtime:" +msgstr "" + +#. type: Fenced code block (ini) +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "" +"# App dev environment.\n" +"# Note that variables are available in the app only, not in compose.yml.\n" +"\n" +"APP_ENV=dev\n" +"APP_DEBUG=true\n" +"SERVER_NAME=:80\n" +"XDEBUG_MODE=develop\n" +"COMPOSER_CACHE_DIR=/app/runtime/cache/composer\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "" +"| Variable | Purpose |\n" +"|-----------------------|--------------------------------------------------------------------------------------|\n" +"| `APP_ENV` | Application environment. `dev` enables developer-friendly behavior. |\n" +"| `APP_DEBUG` | Enables detailed error output and debug panels. |\n" +"| `SERVER_NAME` | Caddy server address — `:80` means listen on all interfaces on port 80. |\n" +"| `XDEBUG_MODE` | Xdebug mode. Use `develop` for helpers and `debug` to enable step debugging. |\n" +"| `COMPOSER_CACHE_DIR` | Moves Composer's cache into the mounted volume so it persists between runs. |\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "docker/test/.env" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +msgid "Contains application environment variables for the test container:" +msgstr "" + +#. type: Fenced code block (ini) +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "" +"# App test environment.\n" +"# Note that variables are available in the app only, not in compose.yml.\n" +"\n" +"APP_ENV=test\n" +"APP_DEBUG=false\n" +"APP_C3=true\n" +"SERVER_NAME=:80\n" +"XDEBUG_MODE=coverage\n" +"COMPOSER_CACHE_DIR=/app/runtime/cache/composer\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "" +"| Variable | Purpose |\n" +"|----------------------|-----------------------------------------------------------------------------------------------|\n" +"| `APP_ENV` | Sets the environment to `test` so the application loads test-specific configuration. |\n" +"| `APP_DEBUG` | Disabled in tests to match a realistic execution context. |\n" +"| `APP_C3` | Enables [c3](https://github.com/Codeception/c3) remote code coverage collection. |\n" +"| `SERVER_NAME` | Caddy server address. |\n" +"| `XDEBUG_MODE` | `coverage` activates Xdebug's code coverage driver required for coverage reports. |\n" +"| `COMPOSER_CACHE_DIR` | Persistent Composer cache inside the volume. |\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "docker/prod/.env" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +msgid "Contains application environment variables for the production container:" +msgstr "" + +#. type: Fenced code block (ini) +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "" +"# App prod environment.\n" +"# Note that variables are available in the app only, not in compose.yml.\n" +"\n" +"APP_ENV=prod\n" +"APP_DEBUG=false\n" +"SERVER_NAME=:80\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +msgid "The production environment intentionally uses a minimal configuration. Secrets and host-specific overrides should be managed through deployment tooling and never committed to version control." +msgstr "" + +#. type: Title ### +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "Override env files" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +msgid "Each environment directory contains a `.gitignore` that excludes an `override.env` file. This file is optional and, when present, is merged on top of the main `.env` for that environment:" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "" +"# docker/dev/override.env.example\n" +"APP_HOST_PATH=/projects/yiisoft/app\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +msgid "Copy the example file to create your local overrides:" +msgstr "" + +#. type: Fenced code block (sh) +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "cp docker/dev/override.env.example docker/dev/override.env\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +msgid "Use override files for developer-specific settings such as Xdebug IDE keys or local bind paths that should not be shared with the team." +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "Compose files" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +msgid "The Compose configuration is split across multiple files that Docker Compose merges at runtime. This approach avoids duplicating shared settings and keeps each environment's file focused and small." +msgstr "" + +#. type: Title ### +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "docker/compose.yml (base)" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +msgid "The base file defines shared settings inherited by all environments:" +msgstr "" + +#. type: Fenced code block (yaml) +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "" +"services:\n" +" app: &appconfig\n" +" extra_hosts:\n" +" - \"host.docker.internal:host-gateway\"\n" +"\n" +"volumes:\n" +" caddy_data:\n" +" caddy_config:\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +msgid "The `&appconfig` YAML anchor lets environment files reference and extend this service definition. The `host.docker.internal` entry maps to the Docker host so containers can reach services running on the host machine (for example, a local database)." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +msgid "The two named volumes (`caddy_data` and `caddy_config`) persist Caddy's certificate storage and configuration across container restarts." +msgstr "" + +#. type: Title ### +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "docker/dev/compose.yml" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +msgid "Extends the base file for local development:" +msgstr "" + +#. type: Fenced code block (yaml) +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "" +"services:\n" +" app:\n" +" build:\n" +" dockerfile: docker/Dockerfile\n" +" context: ..\n" +" target: dev\n" +" args:\n" +" USER_ID: ${UID}\n" +" GROUP_ID: ${GID}\n" +" env_file:\n" +" - path: ./dev/.env\n" +" - path: ./dev/override.env\n" +" required: false\n" +" ports:\n" +" - \"${DEV_PORT:-80}:80\"\n" +" volumes:\n" +" - ../:/app\n" +" - ../runtime:/app/runtime\n" +" - caddy_data:/data\n" +" - caddy_config:/config\n" +" tty: true\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +msgid "Key points:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/docker.md +msgid "**`target: dev`** — Selects the `dev` stage from the multi-stage Dockerfile." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/docker.md +msgid "**`USER_ID` / `GROUP_ID`** — Passed as build arguments so the container user matches the host user, preventing file permission issues on Linux." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/docker.md +msgid "**`env_file`** — Loads `docker/dev/.env` and, optionally, the developer's local `override.env`." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/docker.md +msgid "**`ports`** — Exposes port 80 (or `DEV_PORT` from `docker/.env`) on the host." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/docker.md +msgid "**`volumes`** — Mounts the entire project into `/app` so code changes are reflected immediately without rebuilding the image." +msgstr "" + +#. type: Title ### +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "docker/test/compose.yml" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +msgid "Identical in structure to the dev file but loads `docker/test/.env` and does not expose ports to the host, since tests run entirely inside the container network." +msgstr "" + +#. type: Title ### +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "docker/prod/compose.yml" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +msgid "Targets production deployments using Docker Swarm:" +msgstr "" + +#. type: Fenced code block (yaml) +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "" +"services:\n" +" app:\n" +" image: ${IMAGE}:${IMAGE_TAG}\n" +" networks:\n" +" - caddy_public\n" +" volumes:\n" +" - runtime:/app/runtime\n" +" - caddy_data:/data\n" +" - caddy_config:/config\n" +" env_file:\n" +" - path: ./prod/.env\n" +" - path: ./prod/override.env\n" +" required: false\n" +" deploy:\n" +" replicas: 2\n" +" update_config:\n" +" delay: 10s\n" +" parallelism: 1\n" +" order: start-first\n" +" failure_action: rollback\n" +" monitor: 10s\n" +" rollback_config:\n" +" parallelism: 0\n" +" order: stop-first\n" +" restart_policy:\n" +" condition: on-failure\n" +" delay: 5s\n" +" max_attempts: 3\n" +" window: 120s\n" +" labels:\n" +" caddy: ${PROD_HOST:-app.example.com}\n" +" caddy.reverse_proxy: \"{{upstreams 80}}\"\n" +"\n" +"volumes:\n" +" runtime:\n" +"\n" +"networks:\n" +" caddy_public:\n" +" external: true\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +msgid "Instead of building an image, the production file references a pre-built image (`${IMAGE}:${IMAGE_TAG}`). The `deploy` block configures Docker Swarm behaviour: two replicas with a rolling `start-first` update strategy and automatic rollback on failure. The `caddy` labels are picked up by a [Caddy Docker Proxy](https://github.com/lucaslorentz/caddy-docker-proxy) running in the same Swarm to configure automatic HTTPS routing." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> The `caddy_public` network must already exist on the Swarm before deploying.\n" +"> See the [Docker Swarm deployment guide](../../cookbook/deployment/docker-swarm.md) for full setup instructions.\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "Multi-stage Dockerfile" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +msgid "The `docker/Dockerfile` uses [multi-stage builds](https://docs.docker.com/build/building/multi-stage/) to produce lean images for each purpose from a single file, avoiding duplication of the base setup:" +msgstr "" + +#. type: Fenced code block (dockerfile) +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "" +"FROM composer/composer:2-bin AS composer\n" +"\n" +"FROM dunglas/frankenphp:1-php8.2-bookworm AS base\n" +"\n" +"RUN apt update && apt -y install \\\n" +" unzip\n" +"\n" +"RUN install-php-extensions \\\n" +" opcache mbstring intl dom ctype curl phar openssl xml xmlwriter simplexml pdo\n" +"\n" +"ENV LC_ALL=C.UTF-8\n" +"\n" +"#\n" +"# Development\n" +"#\n" +"\n" +"FROM base AS dev\n" +"ARG USER_ID=10001\n" +"ARG GROUP_ID=10001\n" +"ARG USER_NAME=appuser\n" +"ARG GROUP_NAME=appuser\n" +"\n" +"RUN install-php-extensions xdebug\n" +"\n" +"COPY --from=composer /composer /usr/bin/composer\n" +"\n" +"RUN \\\n" +" groupadd --gid ${GROUP_ID} ${GROUP_NAME}; \\\n" +" useradd --gid ${GROUP_ID} --uid ${USER_ID} ${GROUP_NAME}; \\\n" +" setcap CAP_NET_BIND_SERVICE=+eip /usr/local/bin/frankenphp; \\\n" +" chown -R ${USER_NAME}:${GROUP_NAME} /data/caddy && \\\n" +" chown -R ${USER_NAME}:${GROUP_NAME} /config/caddy\n" +"USER ${USER_NAME}\n" +"\n" +"#\n" +"# Production\n" +"#\n" +"\n" +"FROM base AS prod-builder\n" +"COPY --from=composer /composer /usr/bin/composer\n" +"COPY .. /app\n" +"RUN --mount=type=cache,target=/tmp/cache \\\n" +" composer install --no-dev --no-progress --no-interaction --classmap-authoritative && \\\n" +" rm composer.lock composer.json\n" +"\n" +"FROM base AS prod\n" +"ENV APP_ENV=prod\n" +"COPY --from=prod-builder --chown=www-data:www-data /app /app\n" +"USER www-data\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +msgid "The Dockerfile defines four stages:" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "" +"| Stage | Purpose |\n" +"|----------------|--------------------------------------------------------------------------------------------------|\n" +"| `composer` | Copies the Composer binary from the official image to avoid installing it in other stages. |\n" +"| `base` | Installs FrankenPHP, common PHP extensions, and system packages shared by all environments. |\n" +"| `dev` | Extends `base` with Xdebug and Composer. Creates a non-root user matching the host user's UID/GID to prevent permission issues with mounted volumes. |\n" +"| `prod-builder` | Extends `base`, copies the application source, and runs `composer install --no-dev` using a build cache. Removes `composer.lock` and `composer.json` afterwards to keep the final image clean. |\n" +"| `prod` | Copies only the built application from `prod-builder` into a clean `base` image. This produces a small final image because the Composer binary and intermediate files are not included. |\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "" +"> [!TIP]\n" +"> When building the production image you select a specific stage with `--target prod`. The `prod-builder`\n" +"> stage is an intermediate step and is never pushed to a registry.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +msgid "The `dev` target is selected when running `make up` or `make build`, while `make prod-build` targets `prod`." +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "make commands" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +msgid "The `Makefile` provides a convenient interface for all common Docker operations. Run `make` or `make help` to list available targets with their descriptions." +msgstr "" + +#. type: Title ### +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "Development" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "" +"| Command | Description |\n" +"|---------------|----------------------------------------------------------------|\n" +"| `make build` | Build (or rebuild) the development Docker image. |\n" +"| `make up` | Start the development environment in detached mode. |\n" +"| `make down` | Stop and remove containers, networks, and orphaned services. |\n" +"| `make stop` | Stop running containers without removing them. |\n" +"| `make clear` | Remove all development containers, networks, and volumes. |\n" +"| `make shell` | Open an interactive Bash shell inside the running `app` container. |\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "Running tools" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +msgid "Commands in this group run inside the development container using `docker compose run --rm`, so they work even when the container is not currently running:" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "" +"| Command | Description |\n" +"|--------------------------------------|-------------------------------------------------|\n" +"| `make yii ` | Run a `./yii` console command. |\n" +"| `make composer ` | Run Composer. |\n" +"| `make rector` | Run [Rector](https://getrector.com/) for automated PHP refactoring and code quality improvements. |\n" +"| `make cs-fix` | Run [PHP CS Fixer](https://cs.symfony.com/). |\n" +"| `make psalm` | Run [Psalm](https://psalm.dev/) static analysis. |\n" +"| `make composer-dependency-analyser` | Run [Composer Dependency Analyser](https://github.com/shipmonk-rnd/composer-dependency-analyser). |\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "" +"| Command | Description |\n" +"|------------------------|-----------------------------------------------------------|\n" +"| `make test` | Run the full test suite with Codeception. |\n" +"| `make test-coverage` | Run tests and generate an HTML coverage report. |\n" +"| `make codecept ` | Run any Codeception command with custom arguments. |\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "Production" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "" +"| Command | Description |\n" +"|----------------------|-------------------------------------------------------------------------------------|\n" +"| `make prod-build` | Build the production Docker image locally (`--target prod`). |\n" +"| `make prod-push` | Push the built image to the registry defined by `IMAGE` and `IMAGE_TAG`. |\n" +"| `make prod-deploy` | Deploy the stack to a remote Docker Swarm node defined by `PROD_SSH`. |\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/docker.md +#, no-wrap +msgid "" +"> [!TIP]\n" +"> Most commands accept additional arguments. For example, to install a specific package:\n" +"> ```sh\n" +"> make composer require yiisoft/yii-db-mysql\n" +"> ```\n" +"> To run a single test suite:\n" +"> ```sh\n" +"> make test -- Unit\n" +"> ```\n" +msgstr "" diff --git a/_translations/po/pt-BR/guide_tutorial_i18n.md.po b/_translations/po/pt-BR/guide_tutorial_i18n.md.po new file mode 100644 index 00000000..199fe64f --- /dev/null +++ b/_translations/po/pt-BR/guide_tutorial_i18n.md.po @@ -0,0 +1,697 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-06-02 22:29+0000\n" +"PO-Revision-Date: 2026-06-02 22:29+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Fenced code block (sh) +#: ../src/cookbook/using-yii-in-third-party-apps.md +#: ../src/guide/structure/designing-packages.md +#: ../src/guide/structure/module.md ../src/guide/structure/package.md +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "composer yii-config-rebuild\n" +msgstr "" + +#. type: Title # +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "Internationalization" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "Internationalization prepares an application for more than one locale. Localization is the locale-specific part: translated text, plural forms, date and number formats, and view templates for a locale such as `en-US` or `de`." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "In a Yii application, the usual parts are:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/i18n.md +msgid "locale selection for the current request;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/i18n.md +msgid "translated application messages;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/i18n.md +msgid "plural and parameter formatting;" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/i18n.md +msgid "localized view templates for pages that need different markup." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "This tutorial assumes a new [yiisoft/app](https://github.com/yiisoft/app) project." +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "Install packages" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "`yiisoft/app` already includes `yiisoft/i18n` and `yiisoft/translator`. Install PHP-file message storage:" +msgstr "" + +#. type: Fenced code block (sh) +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "composer require yiisoft/translator-message-php\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "Install the extractor as a development dependency:" +msgstr "" + +#. type: Fenced code block (sh) +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "composer require --dev yiisoft/translator-extractor\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "The examples use ICU message formatting for plural forms. Make sure the PHP `intl` extension is enabled. For simple placeholders only, use `Yiisoft\\Translator\\SimpleMessageFormatter` in the configuration below." +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "Configure application locale" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "The application template keeps basic application settings in `config/common/application.php`. Set the source locale there:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "" +" 'UTF-8',\n" +" 'locale' => 'en-US',\n" +" 'name' => 'My Project',\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "" +"The default layout uses this value in the `` attribute through `ApplicationParams`.\n" +"When your application chooses locale per request, set the selected locale on the view as shown in\n" +"[Choosing locale per request](#choosing-locale-per-request).\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "Configure translator defaults in `config/common/params.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "" +"'yiisoft/translator' => [\n" +" 'locale' => 'en-US',\n" +" 'fallbackLocale' => 'en-US',\n" +" 'defaultCategory' => 'app',\n" +"],\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "`locale` is the default translation locale. `fallbackLocale` is used when a translation is missing for the current locale. `defaultCategory` is the category used when a call to `translate()` does not specify one." +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "Configure message storage" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "Create `config/common/di/translator.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "" +" [\n" +" 'definition' => static function (Aliases $aliases) use ($params): CategorySource {\n" +" $messageSource = new MessageSource($aliases->get('@root/messages'));\n" +"\n" +" return new CategorySource(\n" +" $params['yiisoft/translator']['defaultCategory'],\n" +" $messageSource,\n" +" new IntlMessageFormatter(),\n" +" $messageSource,\n" +" );\n" +" },\n" +" 'tags' => ['translation.categorySource'],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "This registers the `app` category. The `MessageSource` reads PHP arrays from the `messages/` directory and writes extracted messages back to the same directory." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "Create the source and target message files:" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "" +"messages/\n" +"├── de/\n" +"│ └── app.php\n" +"└── en-US/\n" +" └── app.php\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "`messages/en-US/app.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "" +" 'Home',\n" +" 'home.welcome' => 'Welcome to Yii3',\n" +" 'cart.items' => '{count, plural, =0{No items} one{# item} other{# items}}',\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "`messages/de/app.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "" +" 'Home',\n" +" 'home.welcome' => 'Willkommen bei Yii3',\n" +" 'cart.items' => '{count, plural, =0{Keine Artikel} one{# Artikel} other{# Artikel}}',\n" +"];\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "Translate messages" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "Inject `Yiisoft\\Translator\\TranslatorInterface` where you prepare data for a response. For the default home page action, update `src/Web/HomePage/Action.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "" +"viewRenderer->render(__DIR__ . '/template', [\n" +" 'itemCount' => 3,\n" +" 'translator' => $this->translator,\n" +" ]);\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "Use the translator in `src/Web/HomePage/template.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "" +"setTitle($translator->translate('home.title'));\n" +"?>\n" +"\n" +"
\n" +"

translate('home.welcome')) ?>

\n" +"\n" +"

translate('cart.items', ['count' => $itemCount])) ?>

\n" +"
\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "Escape translated text before output. Store trusted HTML separately or render it from a view template." +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "Choosing locale per request" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "For a web application, choose locale early in the middleware stack and apply it to both the translator and the view. The example below uses the `lang` query parameter and a fixed allow list:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "" +"getLocale($request);\n" +"\n" +" $this->translator->setLocale($locale);\n" +" $this->view->setLocale($locale);\n" +"\n" +" return $handler->handle($request);\n" +" }\n" +"\n" +" private function getLocale(ServerRequestInterface $request): string\n" +" {\n" +" $locale = $request->getQueryParams()['lang'] ?? null;\n" +"\n" +" return is_string($locale) && in_array($locale, self::SUPPORTED_LOCALES, true)\n" +" ? $locale\n" +" : self::DEFAULT_LOCALE;\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "Register the middleware in `config/common/routes.php` or in the route group that needs localized output. Add middleware before the route action:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "" +"use App\\Web\\Middleware\\LocaleMiddleware;\n" +"use Yiisoft\\Router\\Route;\n" +"\n" +"return [\n" +" Route::get('/')\n" +" ->middleware(LocaleMiddleware::class)\n" +" ->action(App\\Web\\HomePage\\Action::class)\n" +" ->name('home'),\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "Update `src/Web/Shared/Layout/Main/layout.php` to read the locale from the current view state:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "getLocale()) ?>\">\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "Use the same approach when locale is stored in a session, a cookie, a user profile, or a route parameter." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "`yiisoft/i18n` provides `Yiisoft\\I18n\\Locale` for working with BCP 47 locale codes:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "" +"use Yiisoft\\I18n\\Locale;\n" +"\n" +"$locale = new Locale('de-DE');\n" +"\n" +"echo $locale->language(); // de\n" +"echo $locale->region(); // DE\n" +"echo $locale->fallbackLocale()->asString(); // de\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "This is useful when you need to derive a language fallback or inspect locale parts before choosing a supported locale." +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "Localized view files" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "Use message translation for labels, headings, buttons, validation messages, and short paragraphs. Use localized view files when a page needs different markup or a different amount of text for each locale." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "`yiisoft/view` looks for localized files in a locale subdirectory next to the original view file. For example, when `src/Web/HomePage/template.php` is rendered with locale `de-DE`, Yii checks:" +msgstr "" + +#. type: Bullet: '1. ' +#: ../src/guide/tutorial/i18n.md +msgid "`src/Web/HomePage/de-DE/template.php`" +msgstr "" + +#. type: Bullet: '2. ' +#: ../src/guide/tutorial/i18n.md +msgid "`src/Web/HomePage/de/template.php`" +msgstr "" + +#. type: Bullet: '3. ' +#: ../src/guide/tutorial/i18n.md +msgid "`src/Web/HomePage/template.php`" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "The fallback to the two-letter language code is automatic." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "You can set the locale for a single render call:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "" +"return $this->viewRenderer\n" +" ->withLocale('de-DE')\n" +" ->render(__DIR__ . '/template');\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "When the locale is set on `WebView` in middleware, the same locale is applied to views rendered by `WebViewRenderer`." +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "Extract messages" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "Configure the extractor so it can read existing messages and write new IDs to the same message storage." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "Create `config/common/di/translator-extractor.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "" +" [\n" +" '__construct()' => [\n" +" [\n" +" DynamicReference::to([\n" +" 'class' => ExtractorCategorySource::class,\n" +" '__construct()' => [\n" +" $params['yiisoft/translator']['defaultCategory'],\n" +" DynamicReference::to(\n" +" static fn (Aliases $aliases): MessageSource => new MessageSource($aliases->get('@root/messages')),\n" +" ),\n" +" DynamicReference::to(\n" +" static fn (Aliases $aliases): MessageSource => new MessageSource($aliases->get('@root/messages')),\n" +" ),\n" +" ],\n" +" ]),\n" +" ],\n" +" ],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "Rebuild config after adding the extractor configuration file:" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "Extract messages from application source files:" +msgstr "" + +#. type: Fenced code block (sh) +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "./yii translator/extract src --languages=en-US,de\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "The command scans calls such as:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "" +"$translator->translate('home.welcome');\n" +"$translator->translate('cart.items', ['count' => $itemCount]);\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "It writes missing IDs to:" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "" +"messages/en-US/app.php\n" +"messages/de/app.php\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "After extraction, edit target language files and replace source IDs with translated text." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "Use `--category` when a call belongs to another category:" +msgstr "" + +#. type: Fenced code block (sh) +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "./yii translator/extract src --languages=en-US,de --category=shop\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "The extractor excludes `vendor/` by default. Use `--only` or `--except` when you need a narrower scan:" +msgstr "" + +#. type: Fenced code block (sh) +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "./yii translator/extract src --languages=en-US,de --only=**/*.php --except=**/runtime/**\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "Working with categories" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "The default `app` category is enough for most application messages. Add categories when a package or a large feature owns its own message files." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "For a `shop` category, create another tagged category source:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "" +"'translation.shop' => [\n" +" 'definition' => static function (Aliases $aliases): CategorySource {\n" +" $messageSource = new MessageSource($aliases->get('@root/messages'));\n" +"\n" +" return new CategorySource(\n" +" 'shop',\n" +" $messageSource,\n" +" new IntlMessageFormatter(),\n" +" $messageSource,\n" +" );\n" +" },\n" +" 'tags' => ['translation.categorySource'],\n" +"],\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "Translate with the category name:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "$translator->translate('checkout.submit', category: 'shop');\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "The message files are stored as:" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/tutorial/i18n.md +#, no-wrap +msgid "" +"messages/de/shop.php\n" +"messages/en-US/shop.php\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/i18n.md +msgid "Keep message IDs stable. Changing an ID creates a new translation task for every locale." +msgstr "" diff --git a/_translations/po/pt-BR/guide_tutorial_mailing.md.po b/_translations/po/pt-BR/guide_tutorial_mailing.md.po new file mode 100644 index 00000000..458d56bd --- /dev/null +++ b/_translations/po/pt-BR/guide_tutorial_mailing.md.po @@ -0,0 +1,606 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-04 11:19+0500\n" +"PO-Revision-Date: 2025-09-04 11:19+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: en/tutorial/mailing.md +#, no-wrap +msgid "Mailing" +msgstr "" + +#. type: Plain text +#: en/tutorial/mailing.md +msgid "Yii simplifies the composition and sending of email messages using the [yiisoft/mailer](https://github.com/yiisoft/mailer) package. This package provides content composition functionality and a basic interface for sending emails. By default, the package includes a file mailer that writes email contents into a file instead of sending them. This is particularly useful during the initial stages of application development." +msgstr "" + +#. type: Plain text +#: en/tutorial/mailing.md +msgid "To send actual emails, you can use the [Symfony Mailer](https://github.com/yiisoft/mailer-symfony) implementation, which is used in the examples below." +msgstr "" + +#. type: Title ## +#: en/tutorial/mailing.md +#, no-wrap +msgid "Configuring the Mailer" +msgstr "" + +#. type: Plain text +#: en/tutorial/mailing.md +msgid "The mailer service allows you to create a message instance, populate it with data, and send it. Typically, you get an instance from the DI container as `Yiisoft\\Mailer\\MailerInterface`." +msgstr "" + +#. type: Plain text +#: en/tutorial/mailing.md +msgid "You can also create an instance manually as follows:" +msgstr "" + +#. type: Fenced code block (php) +#: en/tutorial/mailing.md +#, no-wrap +msgid "" +"\n" +"use Yiisoft\\Mailer\\Symfony\\Mailer;\n" +"\n" +"/**\n" +" * @var \\Symfony\\Component\\Mailer\\Transport\\TransportInterface $transport\n" +" */\n" +"\n" +"$mailer = new \\Yiisoft\\Mailer\\Symfony\\Mailer(\n" +" $transport,\n" +");\n" +msgstr "" + +#. type: Plain text +#: en/tutorial/mailing.md +msgid "The `Yiisoft\\Mailer\\MailerInterface` provides two main methods:" +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`send()` - Sends the given email message." +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`sendMultiple()` - Sends many messages at once." +msgstr "" + +#. type: Title ## +#: en/tutorial/mailing.md +#, no-wrap +msgid "Creating a Message" +msgstr "" + +#. type: Title ### +#: en/tutorial/mailing.md +#, no-wrap +msgid "Simple Text Message" +msgstr "" + +#. type: Plain text +#: en/tutorial/mailing.md +msgid "To create a simple message with a text body, use `Yiisoft\\Mailer\\Message`:" +msgstr "" + +#. type: Fenced code block (php) +#: en/tutorial/mailing.md +#, no-wrap +msgid "" +"$message = new \\Yiisoft\\Mailer\\Message(\n" +" from: 'from@domain.com',\n" +" to: 'to@domain.com',\n" +" subject: 'Message subject',\n" +" textBody: 'Plain text content'\n" +");\n" +msgstr "" + +#. type: Title ### +#: en/tutorial/mailing.md +#, no-wrap +msgid "Simple HTML Message" +msgstr "" + +#. type: Fenced code block (php) +#: en/tutorial/mailing.md +#, no-wrap +msgid "" +"$message = new \\Yiisoft\\Mailer\\Message(\n" +" from: 'from@domain.com',\n" +" to: 'to@domain.com',\n" +" subject: 'Message subject',\n" +" htmlBody: 'HTML content'\n" +");\n" +msgstr "" + +#. type: Title ### +#: en/tutorial/mailing.md +#, no-wrap +msgid "HTML Message from template" +msgstr "" + +#. type: Plain text +#: en/tutorial/mailing.md +msgid "For this example, we will use package rendering package [view](https://github.com/yiisoft/view)." +msgstr "" + +#. type: Fenced code block (php) +#: en/tutorial/mailing.md +#, no-wrap +msgid "" +"/**\n" +" * @var \\Yiisoft\\View\\View $view\n" +" */\n" +"\n" +"$content = $view->render('path/to/view.php', [\n" +" 'name' => 'name',\n" +" 'code' => 'code',\n" +"]);\n" +"\n" +"$message = new \\Yiisoft\\Mailer\\Message(\n" +" from: 'from@domain.com',\n" +" to: 'to@domain.com',\n" +" subject: 'Subject',\n" +" htmlBody: $content\n" +");\n" +msgstr "" + +#. type: Title ### +#: en/tutorial/mailing.md +#, no-wrap +msgid "Using Layouts" +msgstr "" + +#. type: Plain text +#: en/tutorial/mailing.md +msgid "You can also pass parameters to layouts from your template message:" +msgstr "" + +#. type: Fenced code block (php) +#: en/tutorial/mailing.md +#, no-wrap +msgid "" +"/**\n" +" * @var \\Yiisoft\\View\\View $view\n" +" * @var array $layoutParameters\n" +" */\n" +"\n" +"$messageBody = $view->render('path/to/view.php', [\n" +" 'name' => 'name',\n" +" 'code' => 'code',\n" +"]);\n" +"\n" +"$layoutParameters['content'] = $messageBody;\n" +"\n" +"$content = $view->render('path/to/layout.php', $layoutParameters);\n" +"\n" +"$message = new \\Yiisoft\\Mailer\\Message(\n" +" from: 'from@domain.com',\n" +" to: 'to@domain.com',\n" +" subject: 'Subject',\n" +" htmlBody: $content\n" +");\n" +msgstr "" + +#. type: Title ### +#: en/tutorial/mailing.md +#, no-wrap +msgid "Layout Example" +msgstr "" + +#. type: Plain text +#: en/tutorial/mailing.md +msgid "You can wrap the view rendering result in a layout, similar to how layouts work in web applications. This is useful for setting up shared content like CSS styles:" +msgstr "" + +#. type: Fenced code block (php) +#: en/tutorial/mailing.md +#, no-wrap +msgid "" +"\n" +"\n" +"\n" +"\n" +" \n" +"\n" +"\n" +"\n" +"\n" +"\n" +"
\n" +"--
\n" +"Mailed by Yii\n" +"
\n" +"\n" +"\n" +"\n" +msgstr "" + +#. type: Title ## +#: en/tutorial/mailing.md +#, no-wrap +msgid "Adding More Data" +msgstr "" + +#. type: Plain text +#: en/tutorial/mailing.md +msgid "The `Yiisoft\\Mailer\\MessageInterface` provides several methods to customize your message:" +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`withCharset()` - Returns a new instance with the specified charset." +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`withFrom()` - Returns a new instance with the specified sender email address." +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`withTo()` - Returns a new instance with the specified recipient(s) email address." +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`withReplyTo()` - Returns a new instance with the specified reply-to address." +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`withCc()` - Returns a new instance with the specified Cc (extra copy receiver) addresses." +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`withBcc()` - Returns a new instance with the specified Bcc (hidden copy receiver) addresses." +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`withSubject()` - Returns a new instance with the specified message subject." +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`withDate()` - Returns a new instance with the specified date when the message was sent." +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`withPriority()` - Returns a new instance with the specified priority of this message." +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`withReturnPath()` - Returns a new instance with the specified return-path (the bounce address) of this message." +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`withSender()` - Returns a new instance with the specified actual sender email address." +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`withHtmlBody()` - Returns a new instance with the specified message HTML content." +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`withTextBody()` - Returns a new instance with the specified message plain text content." +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`withAddedHeader()` - Returns a new instance with the specified added custom header value." +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`withHeader()` - Returns a new instance with the specified custom header value." +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`withHeaders()` - Returns a new instance with the specified custom header values." +msgstr "" + +#. type: Plain text +#: en/tutorial/mailing.md +msgid "These methods are immutable, meaning they return a new instance of the message with the updated data." +msgstr "" + +#. type: Plain text +#: en/tutorial/mailing.md +msgid "Note `with` prefix. It indicates that the method is immutable and returns a new instance of the class with the changed data." +msgstr "" + +#. type: Title ### +#: en/tutorial/mailing.md +#, no-wrap +msgid "Getters" +msgstr "" + +#. type: Plain text +#: en/tutorial/mailing.md +msgid "The following getters are available to retrieve message data:" +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`getCharset()` - Returns the charset of this message." +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`getFrom()` - Returns the message sender email address." +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`getTo()` - Returns the message recipient(s) email address." +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`getReplyTo()` - Returns the reply-to address of this message." +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`getCc()` - Returns the Cc (extra copy receiver) addresses of this message." +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`getBcc()` - Returns the Bcc (hidden copy receiver) addresses of this message." +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`getSubject()` - Returns the message subject." +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`getDate()` - Returns the date when the message was sent, or null if it wasn't set." +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`getPriority()` - Returns the priority of this message." +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`getReturnPath()` - Returns the return-path (the bounce address) of this message." +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`getSender()` - Returns the message actual sender email address." +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`getHtmlBody()` - Returns the message HTML body." +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`getTextBody()` - Returns the message text body." +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`getHeader()` - Returns all values for the specified header." +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`__toString()` - Returns string representation of this message." +msgstr "" + +#. type: Title ## +#: en/tutorial/mailing.md +#, no-wrap +msgid "Attaching Files" +msgstr "" + +#. type: Plain text +#: en/tutorial/mailing.md +msgid "You can attach files to your message using the `withAttached()` method:" +msgstr "" + +#. type: Fenced code block (php) +#: en/tutorial/mailing.md +#, no-wrap +msgid "" +"use Yiisoft\\Mailer\\File;\n" +"\n" +"// Attach a file from the local file system\n" +"$message = $message->withAttached(\n" +" File::fromPath('/path/to/source/file.pdf'),\n" +");\n" +"\n" +"// Create an attachment on-the-fly\n" +"$message = $message->withAttached(\n" +" File::fromContent('Attachment content', 'attach.txt', 'text/plain'),\n" +");\n" +msgstr "" + +#. type: Title ## +#: en/tutorial/mailing.md +#, no-wrap +msgid "Embedding Images" +msgstr "" + +#. type: Plain text +#: en/tutorial/mailing.md +msgid "You can embed images into the message content using the `withEmbedded()` method. This is particularly useful when composing messages with views:" +msgstr "" + +#. type: Fenced code block (php) +#: en/tutorial/mailing.md +#, no-wrap +msgid "" +"$logo = 'path/to/logo';\n" +"$htmlBody = $this->view->render(\n" +" __DIR__ . 'template.php',\n" +" [\n" +" 'content' => $content,\n" +" 'logoCid' => $logo->cid(),\n" +" ],\n" +");\n" +"return new \\Yiisoft\\Mailer\\Message(\n" +" from: 'from@domain.com',\n" +" to: 'to@domain.com',\n" +" subject: 'Message subject',\n" +" htmlBody: $htmlBody,\n" +" embeddings: $logo\n" +" );\n" +msgstr "" + +#. type: Plain text +#: en/tutorial/mailing.md +msgid "In your view or layout template, you can reference the embedded image using its CID:" +msgstr "" + +#. type: Fenced code block (php) +#: en/tutorial/mailing.md +#, no-wrap +msgid "\">\n" +msgstr "" + +#. type: Title ## +#: en/tutorial/mailing.md +#, no-wrap +msgid "Sending a Message" +msgstr "" + +#. type: Plain text +#: en/tutorial/mailing.md +msgid "To send an email message:" +msgstr "" + +#. type: Fenced code block (php) +#: en/tutorial/mailing.md +#, no-wrap +msgid "" +"/**\n" +" * @var \\Yiisoft\\View\\View $view\n" +" */\n" +"\n" +"$content = $view->render('path/to/view.php', [\n" +" 'name' => 'name',\n" +" 'code' => 'code',\n" +"]);\n" +"\n" +"$message = new \\Yiisoft\\Mailer\\Message(\n" +" from: 'from@domain.com',\n" +" to: 'to@domain.com',\n" +" subject: 'Subject',\n" +" htmlBody: $content\n" +");\n" +"\n" +"$mailer->send($message);\n" +msgstr "" + +#. type: Title ## +#: en/tutorial/mailing.md +#, no-wrap +msgid "Sending Multiple Messages" +msgstr "" + +#. type: Plain text +#: en/tutorial/mailing.md +msgid "You can send multiple messages at once:" +msgstr "" + +#. type: Fenced code block (php) +#: en/tutorial/mailing.md +#, no-wrap +msgid "" +"$messages = [];\n" +"\n" +"foreach ($users as $user) {\n" +" $messages[] = (new \\Yiisoft\\Mailer\\Message())\n" +" // ...\n" +" ->withTo($user->email);\n" +"}\n" +"\n" +"$result = $mailer->sendMultiple($messages);\n" +msgstr "" + +#. type: Plain text +#: en/tutorial/mailing.md +msgid "The `sendMultiple()` method returns a `Yiisoft\\Mailer\\SendResults` object containing arrays of successfully sent and failed messages." +msgstr "" + +#. type: Title ## +#: en/tutorial/mailing.md +#, no-wrap +msgid "Implementing your own mail driver" +msgstr "" + +#. type: Plain text +#: en/tutorial/mailing.md +msgid "To create a custom mail solution, implement the `Yiisoft\\Mailer\\MailerInterface` and `Yiisoft\\Mailer\\MessageInterface` interfaces." +msgstr "" + +#. type: Title ## +#: en/tutorial/mailing.md +#, no-wrap +msgid "For Development" +msgstr "" + +#. type: Plain text +#: en/tutorial/mailing.md +msgid "For local or test development, you can use simplified implementations of the mailer that does not send emails. The package provides these implementations:" +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`Yiisoft\\Mailer\\StubMailer` - A simple mailer that stores messages in a local array." +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`Yiisoft\\Mailer\\FileMailer` - A mock mailer that saves email messages as files instead of sending them." +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/mailing.md +msgid "`Yiisoft\\Mailer\\NullMailer` - A mailer that discards messages without sending or storing them." +msgstr "" + +#. type: Plain text +#: en/tutorial/mailing.md +msgid "To use one of these mailers, configure it in your development environment file Example: `environments/local/di.php`" +msgstr "" + +#. type: Fenced code block (php) +#: en/tutorial/mailing.md +#, no-wrap +msgid "" +"return [\n" +" Yiisoft\\Mailer\\MailerInterface::class => Yiisoft\\Mailer\\StubMailer::class, //or any other\n" +"];\n" +"\n" +msgstr "" diff --git a/_translations/po/pt-BR/guide_tutorial_performance-tuning.md.po b/_translations/po/pt-BR/guide_tutorial_performance-tuning.md.po new file mode 100644 index 00000000..fa738a44 --- /dev/null +++ b/_translations/po/pt-BR/guide_tutorial_performance-tuning.md.po @@ -0,0 +1,344 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-06-05 20:33+0000\n" +"PO-Revision-Date: 2026-06-05 20:33+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/guide/tutorial/performance-tuning.md +#, no-wrap +msgid "Performance tuning" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/performance-tuning.md +msgid "There are many factors affecting the performance of your application. Some are environmental, some are related to your code, while some others are related to Yii itself. In this section, we will count most of these factors and explain how you can improve your application performance by adjusting these factors." +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/performance-tuning.md +#, no-wrap +msgid "Optimizing your PHP Environment" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/performance-tuning.md +msgid "A well-configured PHP environment is important. To get maximum performance:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/performance-tuning.md +msgid "Use the latest stable PHP version. Major releases of PHP may bring significant performance improvements." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/performance-tuning.md +msgid "Enable bytecode caching with [Opcache](https://secure.php.net/opcache). Bytecode caching avoids the time spent on parsing and including PHP scripts for every incoming request." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/performance-tuning.md +msgid "[Tune `realpath()` cache](https://github.com/samdark/realpath_cache_tuner)." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/performance-tuning.md +msgid "Make sure [XDebug](https://xdebug.org/) isn't installed in the production environment." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/performance-tuning.md +msgid "Try [PHP 7 preloading](https://wiki.php.net/rfc/preload)." +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/performance-tuning.md +#, no-wrap +msgid "Optimizing your code" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/performance-tuning.md +msgid "Beyond environment configuration, there are code-level optimizations that can improve your application's performance:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/performance-tuning.md +msgid "Look out for [algorithm complexity](https://en.wikipedia.org/wiki/Time_complexity). Especially give attention to `foreach` within `foreach` loops but look out for using [heavy PHP functions](https://stackoverflow.com/questions/2473989/list-of-big-o-for-php-functions) in loops as well." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/performance-tuning.md +msgid "[Speeding up array_merge()](https://www.exakat.io/speeding-up-array_merge/)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/performance-tuning.md +msgid "[Move that foreach() inside the method](https://www.exakat.io/move-that-foreach-inside-the-method/)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/performance-tuning.md +msgid "[Array, classes and anonymous classes memory usage](https://www.exakat.io/array-classes-and-anonymous-memory-usage/)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/performance-tuning.md +msgid "Use fully qualified function names with leading backslashes to optimize opcache performance. When calling [certain global functions](https://github.com/php/php-src/blob/944b6b6bbd6f05ad905f5f4ad07445792bee4027/Zend/zend_compile.c#L4291-L4353) from within a namespace, PHP first searches in the current namespace before falling back to the global namespace. Adding a leading backslash (e.g., `\\count()` instead of `count()`) tells PHP to directly use the global function, avoiding the namespace lookup and improving opcache efficiency. This optimization is best implemented automatically using tools like [PHP-CS-Fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer) with the `native_function_invocation` rule." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/performance-tuning.md +msgid "The above optimizations would give you a significant performance boost only if the code in question is executed frequently. That is usually the case for big loops or batch processing." +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/performance-tuning.md +#, no-wrap +msgid "Using caching techniques" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/performance-tuning.md +msgid "You can use various caching techniques to significantly improve the performance of your application. For example, if your application allows users to enter text in Markdown format, you may consider caching the parsed Markdown content to avoid parsing the same Markdown text repeatedly in every request. Please refer to the [Caching](../caching/overview.md) section to learn about the caching support provided by Yii." +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/performance-tuning.md +#, no-wrap +msgid "Optimizing session storage" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/performance-tuning.md +#, no-wrap +msgid "" +"By default, session data is stored in files. The implementation is locking a file from opening a session to the point it's\n" +"closed either by `$session->close()` or at the end of request.\n" +"While the session file is locked, all other requests that are trying to use the same session are blocked. That's waiting for the\n" +"initial request to release a session file. This is fine for development and probably small projects. But when it comes \n" +"to handling massive concurrent requests, it's better to use more sophisticated storage, such as Redis.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/performance-tuning.md +msgid "It could be done either by [configuring PHP via php.ini](https://www.digitalocean.com/community/tutorials/how-to-set-up-a-redis-server-as-a-session-handler-for-php-on-ubuntu-14-04) or [implementing SessionHandlerInterface](https://www.sitepoint.com/saving-php-sessions-in-redis/) and configuring session service as follows:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/tutorial/performance-tuning.md +#, no-wrap +msgid "" +"\\Yiisoft\\Session\\SessionInterface::class => [\n" +" 'class' => \\Yiisoft\\Session\\Session::class,\n" +" '__construct()' => [[], $myCustomSessionHandler],\n" +"],\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/performance-tuning.md +#, no-wrap +msgid "Optimizing databases" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/performance-tuning.md +msgid "Executing DB queries and fetching data from databases are often the main performance bottleneck in a Web application. Although using [data caching](../caching/data.md) techniques may ease the performance hit, it doesn't fully solve the problem. When the database has enormous amounts of data and the cached data are invalid, fetching the latest data could be prohibitively expensive without a proper database and query design." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/performance-tuning.md +msgid "A general technique to improve the performance of DB queries is to create indices for table columns that need to be filtered by. For example, if you need to look for a user record by `username`, you should create an index on `username`. Note that while indexing can make SELECT queries much faster, it will slow down INSERT, UPDATE and DELETE queries." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/performance-tuning.md +msgid "For complex DB queries, it's recommended that you create database views to save the query parsing and preparation time." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/performance-tuning.md +msgid "Last but not least, use `LIMIT` in your `SELECT` queries. This avoids fetching an overwhelming amount of data from the database and exhausting the memory allocated to PHP." +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/performance-tuning.md +#, no-wrap +msgid "Optimizing composer autoloader" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/performance-tuning.md +msgid "Because Composer autoloader is used to include most third-party class files, you should consider optimizing it by executing the following command:" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/tutorial/performance-tuning.md +#, no-wrap +msgid "composer dumpautoload -o\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/performance-tuning.md +msgid "Additionally, you may consider using [authoritative class maps](https://getcomposer.org/doc/articles/autoloader-optimization.md#optimization-level-2-a-authoritative-class-maps) and [APCu cache](https://getcomposer.org/doc/articles/autoloader-optimization.md#optimization-level-2-b-apcu-cache). Note that both optimizations may or may not be suitable for your particular case." +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/performance-tuning.md +#, no-wrap +msgid "Processing data offline" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/performance-tuning.md +msgid "When a request involves some resource-intensive operations, you should think of ways to perform those operations in offline mode without having users wait for them to finish." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/performance-tuning.md +msgid "There are two methods to process data offline: pull and push." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/performance-tuning.md +msgid "In the pull method, whenever a request involves some complex operation, you create a task and save it in a persistent storage, such as a database. You then use a separate process (such as a cron job) to pull the tasks and process them. This method is straightforward to implement, but it has some drawbacks. For example, the task process needs to periodically pull from the task storage. If the pull frequency is too low, the tasks may be processed with great delay, but if the frequency is too high, it will introduce high overhead." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/performance-tuning.md +msgid "In the push method, you would use a message queue (e.g., RabbitMQ, ActiveMQ, Amazon SQS, etc.) to manage the tasks. Whenever a new task is put in the queue, it will initiate or notify the task handling process to trigger the task processing." +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/performance-tuning.md +#, no-wrap +msgid "Using preloading" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/performance-tuning.md +msgid "As of PHP 7.4.0, PHP can be configured to preload scripts into the opcache when the engine starts. You can read more in the [documentation](https://www.php.net/manual/en/opcache.preloading.php) and the corresponding [RFC](https://wiki.php.net/rfc/preload)." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/performance-tuning.md +msgid "Note that the optimal tradeoff between performance and memory may vary with the application. \"Preload everything\" may be the easiest strategy, but not necessarily the best strategy." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/performance-tuning.md +msgid "For example, we conducted a simple [yiisoft/app](https://github.com/yiisoft/app) application template benchmark. Without preloading and with preloading of the entire composer class map." +msgstr "" + +#. type: Title ### +#: ../src/guide/tutorial/performance-tuning.md +#, no-wrap +msgid "Preloading benchmarks" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/performance-tuning.md +msgid "The application template benchmark includes configuring classes to injected dependencies in the bootstrap script." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/performance-tuning.md +msgid "For both variants, [ApacheBench](https://httpd.apache.org/docs/2.4/programs/ab.html) was used with the following run parameters:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/tutorial/performance-tuning.md +#, no-wrap +msgid "ab -n 1000 -c 10 -t 10\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/performance-tuning.md +msgid "Also, the debug mode was disabled. And an optimized autoloader of the [Composer](https://getcomposer.org) was used, and development dependencies weren't used:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/tutorial/performance-tuning.md +#, no-wrap +msgid "composer install --optimize-autoloader --no-dev\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/performance-tuning.md +msgid "With preloading enabled, the entire composer class map (825 files) was used:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/tutorial/performance-tuning.md +#, no-wrap +msgid "" +"$files = require 'vendor/composer/autoload_classmap.php';\n" +"\n" +"foreach (array_unique($files) as $file) {\n" +" opcache_compile_file($file);\n" +"}\n" +msgstr "" + +#. type: Title #### +#: ../src/guide/tutorial/performance-tuning.md +#, no-wrap +msgid "Test results" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/performance-tuning.md +#, no-wrap +msgid "" +"| Benchmark | Preloaded files | Opcache memory used | Per request memory used | Time per request | Requests per second |\n" +"|--------------------|-----------------|---------------------|-------------------------|------------------|---------------------|\n" +"| Without preloading | 0 | 12.32 mb | 1.71 mb | 27.63 ms | 36.55 rq/s |\n" +"| With preloading | 825 | 17.86 mb | 1.82 mb | 26.21 ms | 38.42 rq/s |\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/performance-tuning.md +msgid "As you can see, the test results aren't much different, since this is just a clean application template that contains a few classes. More discussion of preloading, including benchmarks, can be found in the [composer's issue](https://github.com/composer/composer/issues/7777)." +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/performance-tuning.md +#, no-wrap +msgid "Performance profiling" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/performance-tuning.md +msgid "You should profile your code to find out the performance bottlenecks and take appropriate measures accordingly. The following profiling tools may be useful:" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/performance-tuning.md +#, no-wrap +msgid "\n" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/performance-tuning.md +msgid "[Blackfire](https://blackfire.io/)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/performance-tuning.md +msgid "[XHProf](https://secure.php.net/manual/en/book.xhprof.php)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/performance-tuning.md +msgid "[XDebug profiler](https://xdebug.org/docs/profiler)" +msgstr "" diff --git a/_translations/po/pt-BR/guide_tutorial_using-with-event-loop.md.po b/_translations/po/pt-BR/guide_tutorial_using-with-event-loop.md.po new file mode 100644 index 00000000..527f548c --- /dev/null +++ b/_translations/po/pt-BR/guide_tutorial_using-with-event-loop.md.po @@ -0,0 +1,141 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-10-07 15:22+0000\n" +"PO-Revision-Date: 2026-10-07 15:22+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/guide/tutorial/using-with-event-loop.md +#, no-wrap +msgid "Using Yii with event loop" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-with-event-loop.md +#, no-wrap +msgid "" +"A normal PHP web request execution cycle consists of setting up an environment, getting a request, processing it to form a response\n" +"and sending the result. After the response is sent, execution is terminated and its context is lost. So, for the further \n" +" request, the whole sequence is repeated. Such an approach has a big advantage in ease of development since a developer doesn't\n" +"have to take much care about memory leaks or properly clean up context. On the other side, initializing everything for\n" +"every request takes time and overall consumes up to 50% of processing resources.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-with-event-loop.md +msgid "There is an alternative way of running an application. Event loop. The idea is to initialize everything possible at once and then process a number of requests using it. Such an approach is usually called event loop." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-with-event-loop.md +msgid "There are multiple tools that could be used to achieve it. Notably, [FrankenPHP](https://frankenphp.dev/), [Rapira](https://rapira.rs/), [RoadRunner](https://roadrunner.dev/) and [Swoole](https://www.swoole.com/)." +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/using-with-event-loop.md +#, no-wrap +msgid "Event loop implications" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-with-event-loop.md +msgid "Event loop worker basically looks like the following:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/tutorial/using-with-event-loop.md +#, no-wrap +msgid "" +"initializeContext();\n" +"while ($request = getRequest()) {\n" +" $response = process($request);\n" +" emit($response);\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-with-event-loop.md +msgid "Usually, there are multiple workers processing requests at the same time as with traditional php-fpm." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-with-event-loop.md +msgid "That means that there's more to consider when developing applications." +msgstr "" + +#. type: Title ### +#: ../src/guide/tutorial/using-with-event-loop.md +#, no-wrap +msgid "Processing is blocking" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-with-event-loop.md +msgid "Worker process requests one by one that's current processing is blocking processing next request. That means that long-running processes, same as in general PHP applications, should be put into a background via using a queue." +msgstr "" + +#. type: Title ### +#: ../src/guide/tutorial/using-with-event-loop.md +#, no-wrap +msgid "Services and state" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-with-event-loop.md +msgid "Since the context in the event loop is shared between all request-responses processed by a single worker, all changes in the state of a service made by the previous request may affect the current request. Moreover, it can be a security problem if data from one user is available to another user." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-with-event-loop.md +msgid "There are two ways of dealing with it. First, you can avoid having state by making services stateless. PHP's `readonly` keyword may be handy for it. Second, you can reset the services' state at the end of the request processing. In this case, a state resetter will help you:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/tutorial/using-with-event-loop.md +#, no-wrap +msgid "" +"initializeContext();\n" +"$resetter = $container->get(\\Yiisoft\\Di\\StateResetter::class);\n" +"while ($request = getRequest()) {\n" +" $response = process($request);\n" +" emit($response);\n" +" $resetter->reset(); // We should reset the state of such services on every request.\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/using-with-event-loop.md +#, no-wrap +msgid "Integrations" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/using-with-event-loop.md +msgid "[FrankenPHP](using-yii-with-frankenphp.md)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/using-with-event-loop.md +msgid "[Rapira](using-yii-with-rapira.md)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/using-with-event-loop.md +msgid "[RoadRunner](using-yii-with-roadrunner.md)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/using-with-event-loop.md +msgid "[Swoole](using-yii-with-swoole.md)" +msgstr "" diff --git a/_translations/po/pt-BR/guide_tutorial_using-yii-with-frankenphp.md.po b/_translations/po/pt-BR/guide_tutorial_using-yii-with-frankenphp.md.po new file mode 100644 index 00000000..cd472d30 --- /dev/null +++ b/_translations/po/pt-BR/guide_tutorial_using-yii-with-frankenphp.md.po @@ -0,0 +1,370 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-10-07 15:22+0000\n" +"PO-Revision-Date: 2026-10-07 15:22+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/cookbook/making-http-requests.md +#: ../src/cookbook/sentry-integration.md +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#: ../src/guide/tutorial/using-yii-with-rapira.md +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#: ../src/guide/tutorial/using-yii-with-swoole.md ../src/guide/views/asset.md +#: ../src/guide/views/view.md ../src/guide/views/widget.md +#, no-wrap +msgid "Installation" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/sentry-integration.md ../src/guide/concept/configuration.md +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#: ../src/guide/tutorial/using-yii-with-rapira.md +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#: ../src/guide/views/view-injections.md +#, no-wrap +msgid "Configuration" +msgstr "" + +#. type: Title # +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#, no-wrap +msgid "Using Yii with FrankenPHP" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#, no-wrap +msgid "" +"[FrankenPHP](https://frankenphp.dev/) is an application server for PHP with Caddy built in. It can run Yii in \n" +"[worker mode](using-with-event-loop.md), allowing the framework bootstrap to happen once per worker instead of\n" +"once per request.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +msgid "The [FrankenPHP runner](https://github.com/yiisoft/yii-runner-frankenphp) requires PHP 8.1–8.5. Install FrankenPHP using its [installation instructions](https://frankenphp.dev/docs/), or use the Docker setup in the Yii application templates described below." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +msgid "Install the runner package with Composer:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#, no-wrap +msgid "composer require yiisoft/yii-runner-frankenphp\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +msgid "FrankenPHP works especially well in containerized deployments and is the runtime used by the Yii application templates Docker setup described in [Docker in application templates](docker.md)." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> This runner is for worker mode. To use FrankenPHP in classic mode, keep `public/index.php` and\n" +"> [yiisoft/yii-runner-http](https://github.com/yiisoft/yii-runner-http), the default HTTP runner in the templates.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +msgid "First, configure the worker entry script." +msgstr "" + +#. type: Title ### +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#: ../src/guide/tutorial/using-yii-with-rapira.md +#, no-wrap +msgid "Worker entry script" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +msgid "Create `/worker.php` in the project root:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#, no-wrap +msgid "" +"setLevels([\n" +" LogLevel::EMERGENCY,\n" +" LogLevel::ERROR,\n" +" LogLevel::WARNING,\n" +" ]),\n" +" ],\n" +" ),\n" +" new PlainTextRenderer(),\n" +" ),\n" +");\n" +"$runner->run();\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +msgid "The runner bootstraps the application once and then keeps processing requests in worker mode. Unlike classic `public/index.php`, this script is not executed per request." +msgstr "" + +#. type: Title ### +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#: ../src/guide/tutorial/using-yii-with-rapira.md +#, no-wrap +msgid "Server configuration" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +msgid "FrankenPHP is configured through a `Caddyfile`. For production, it may look like the following:" +msgstr "" + +#. type: Fenced code block (caddyfile) +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#, no-wrap +msgid "" +"{\n" +" skip_install_trust\n" +"\n" +" frankenphp {\n" +"\n" +" }\n" +"}\n" +"\n" +"{$SERVER_NAME::80} {\n" +" encode zstd br gzip\n" +" php_server {\n" +" root /app/public\n" +" worker {\n" +" match *\n" +" file /app/worker.php\n" +" }\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +msgid "This configuration tells FrankenPHP to serve the `public` directory and handle all requests with `worker.php`. Static assets are still served from `public`, while PHP requests are processed through the long-running worker." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +msgid "For development, add `watch` so FrankenPHP reloads workers when PHP files change:" +msgstr "" + +#. type: Fenced code block (caddyfile) +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#, no-wrap +msgid "" +"{\n" +" skip_install_trust\n" +"\n" +" frankenphp {\n" +"\n" +" }\n" +"}\n" +"\n" +"{$SERVER_NAME::80} {\n" +" encode zstd br gzip\n" +" php_server {\n" +" root /app/public\n" +" worker {\n" +" match *\n" +" file /app/worker.php\n" +" watch /app/**/*.php\n" +" }\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#, no-wrap +msgid "Docker setup in Yii application templates" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +msgid "Yii application templates already ship with a FrankenPHP-based Docker setup. To switch the application to worker mode, update the files inside the Docker layout instead of relying on `public/index.php`." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +msgid "Create `/worker.php` in the project root as shown above, then update the Caddy configuration used by the container. For development, edit `docker/dev/Caddyfile`:" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +msgid "For production, use the same configuration without `watch` in `docker/Caddyfile`:" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +msgid "The templates use `dunglas/frankenphp` as the base image in `docker/Dockerfile`, mount the project into `/app` in development, and pass runtime configuration through environment files such as `docker/dev/.env` and `docker/prod/.env`. The default value of `SERVER_NAME` in these files is `:80`, which matches the examples above." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +msgid "After changing `worker.php` and the relevant `Caddyfile`, rebuild the image and restart the environment:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#, no-wrap +msgid "" +"make build\n" +"make up\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +msgid "In production, rebuild and deploy the production image using the project's production Docker workflow." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +msgid "If you switch fully to worker mode, `public/index.php` and `yiisoft/yii-runner-http` are no longer needed." +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#: ../src/guide/tutorial/using-yii-with-rapira.md +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#: ../src/guide/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "Starting a server" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +msgid "The exact start command depends on how you run FrankenPHP:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +msgid "In the Yii application templates, run `make build` and `make up` after updating `worker.php` and the relevant `Caddyfile`." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +msgid "With the standalone binary, run the following command from the directory containing your `Caddyfile`:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#, no-wrap +msgid "frankenphp run --config Caddyfile\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +msgid "The example configuration uses `/app` as the application root. Adjust `/app/public`, `/app/worker.php`, and the watch path to match your installation. See the [FrankenPHP configuration reference](https://frankenphp.dev/docs/config/) for other deployment options." +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#: ../src/guide/tutorial/using-yii-with-rapira.md +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#, no-wrap +msgid "On worker scope" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +msgid "Each worker's memory is isolated from other workers." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +msgid "A single worker handles multiple requests, so services created inside it may keep state between requests." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +msgid "At each iteration of the event loop, every stateful service should be reset." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +msgid "For the general implications of long-running workers, see [Using Yii with event loop](using-with-event-loop.md)." +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#, no-wrap +msgid "Worker mode notes" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +msgid "Use the `MAX_REQUESTS` environment variable to limit how many requests a worker handles before restart." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +msgid "The runner calls `Yiisoft\\Di\\StateResetter::reset()` after each request. Register resetters for your stateful services as described in the [Yii DI documentation](https://github.com/yiisoft/di#resetting-services-state)." +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#: ../src/guide/tutorial/using-yii-with-rapira.md +#, no-wrap +msgid "Additional configuration" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +msgid "`FrankenPHPApplicationRunner` is configured by default for Yii application templates and follows the [dependency container configuration](../concept/configuration.md#container-configuration) concept." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +msgid "The constructor allows overriding the default bootstrap, events, DI, params, and error-handler configuration. You can also provide a custom config instance with `withConfig()` and a custom container with `withContainer()`." +msgstr "" diff --git a/_translations/po/pt-BR/guide_tutorial_using-yii-with-rapira.md.po b/_translations/po/pt-BR/guide_tutorial_using-yii-with-rapira.md.po new file mode 100644 index 00000000..19374038 --- /dev/null +++ b/_translations/po/pt-BR/guide_tutorial_using-yii-with-rapira.md.po @@ -0,0 +1,256 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-10-07 20:23+0000\n" +"PO-Revision-Date: 2026-10-07 20:23+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/cookbook/making-http-requests.md +#: ../src/cookbook/sentry-integration.md +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#: ../src/guide/tutorial/using-yii-with-rapira.md +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#: ../src/guide/tutorial/using-yii-with-swoole.md ../src/guide/views/asset.md +#: ../src/guide/views/view.md ../src/guide/views/widget.md +#, no-wrap +msgid "Installation" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/sentry-integration.md ../src/guide/concept/configuration.md +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#: ../src/guide/tutorial/using-yii-with-rapira.md +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#: ../src/guide/views/view-injections.md +#, no-wrap +msgid "Configuration" +msgstr "" + +#. type: Title ### +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#: ../src/guide/tutorial/using-yii-with-rapira.md +#, no-wrap +msgid "Worker entry script" +msgstr "" + +#. type: Title ### +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#: ../src/guide/tutorial/using-yii-with-rapira.md +#, no-wrap +msgid "Server configuration" +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#: ../src/guide/tutorial/using-yii-with-rapira.md +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#: ../src/guide/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "Starting a server" +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#: ../src/guide/tutorial/using-yii-with-rapira.md +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#, no-wrap +msgid "On worker scope" +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#: ../src/guide/tutorial/using-yii-with-rapira.md +#, no-wrap +msgid "Additional configuration" +msgstr "" + +#. type: Title # +#: ../src/guide/tutorial/using-yii-with-rapira.md +#, no-wrap +msgid "Using Yii with Rapira" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-rapira.md +#, no-wrap +msgid "" +"[Rapira](https://rapira.rs/) is a PHP application server written in Rust that embeds the PHP interpreter.\n" +"The [Yii Rapira runner](https://github.com/yiisoft/yii-runner-rapira) supports its classic, worker, and dispatcher modes.\n" +"Worker and dispatcher modes initialize the application once per worker and reuse it for subsequent requests.\n" +"See [Using Yii with event loop](using-with-event-loop.md) for the implications of keeping the application in memory.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-rapira.md +msgid "The runner requires PHP 8.4–8.5. Install the Rapira binary following the [Rapira installation instructions](https://rapira.rs/docs/intro/installation), using a PHP version supported by the runner. The Composer packages provide the Yii integration; the server binary must be installed separately." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-rapira.md +msgid "Install the runner and its contract package in your Yii application:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/tutorial/using-yii-with-rapira.md +#, no-wrap +msgid "composer require yiisoft/yii-runner-rapira:@dev rapira/contract:@dev\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-rapira.md +msgid "These stability flags allow the development versions used by the runner's installation instructions." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-rapira.md +msgid "The following example assumes an application based on `yiisoft/app` or `yiisoft/app-api`, with `App\\Environment` and `src/bootstrap.php` provided by the template." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-rapira.md +msgid "Create `worker.php` in the application root:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/tutorial/using-yii-with-rapira.md +#, no-wrap +msgid "" +"setLevels([\n" +" LogLevel::EMERGENCY,\n" +" LogLevel::ERROR,\n" +" LogLevel::WARNING,\n" +" ]),\n" +" ],\n" +" ),\n" +" new PlainTextRenderer(),\n" +" ),\n" +");\n" +"$runner->run();\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-rapira.md +msgid "The runner creates the container, starts the application, converts incoming requests to PSR-7 requests, and emits responses. It detects the Rapira execution mode, so the same entry script can be used with all three modes." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-rapira.md +msgid "Create `rapira.toml` next to `worker.php`:" +msgstr "" + +#. type: Fenced code block (toml) +#: ../src/guide/tutorial/using-yii-with-rapira.md +#, no-wrap +msgid "" +"[http]\n" +"listen = \"127.0.0.1:8000\"\n" +"\n" +"[http.pool]\n" +"entrypoint = \"worker.php\"\n" +"mode = \"worker\"\n" +"max_requests = 1000\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-rapira.md +msgid "This configuration listens on the loopback interface and recycles each worker after 1,000 requests. For serving files from `public`, follow Rapira's [static file configuration](https://rapira.rs/docs/static-files). See the [configuration reference](https://rapira.rs/docs/configuration) for the other server and pool settings." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-rapira.md +msgid "Run the following command from the application root:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/tutorial/using-yii-with-rapira.md +#, no-wrap +msgid "rapira serve rapira.toml\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-rapira.md +msgid "Open `http://127.0.0.1:8000` to access the application. Restart the server after changing application code or configuration." +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/using-yii-with-rapira.md +#, no-wrap +msgid "Execution modes" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-rapira.md +msgid "Set `mode` in the `[http.pool]` section of `rapira.toml` to choose how requests are processed:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/using-yii-with-rapira.md +msgid "`classic` initializes the application for each request, similarly to PHP-FPM." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/using-yii-with-rapira.md +msgid "`worker` keeps the application in memory and receives requests through PHP's SAPI superglobals." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/using-yii-with-rapira.md +msgid "`dispatcher` keeps the application in memory and receives request objects through Rapira's dispatcher API. The Yii runner processes these requests sequentially within each worker." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-rapira.md +msgid "See [Rapira execution modes](https://rapira.rs/docs/execution-modes) for details." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-rapira.md +msgid "In worker and dispatcher modes, services may retain state between requests. The runner calls `Yiisoft\\Di\\StateResetter::reset()` after each request, but you must configure resetters for your own stateful services. See the [Yii DI documentation](https://github.com/yiisoft/di#resetting-services-state)." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-rapira.md +msgid "The `max_requests` setting limits how long a worker lives; it does not replace resetting request-specific state." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-rapira.md +msgid "`RapiraApplicationRunner` uses the application templates' web configuration groups by default. Its constructor accepts alternative groups, configuration directories, and a temporary error handler. Use `withConfig()` to supply a custom configuration instance or `withContainer()` to supply a PSR-11 container. See the [runner documentation](https://github.com/yiisoft/yii-runner-rapira#configuration) for examples." +msgstr "" diff --git a/_translations/po/pt-BR/guide_tutorial_using-yii-with-roadrunner.md.po b/_translations/po/pt-BR/guide_tutorial_using-yii-with-roadrunner.md.po new file mode 100644 index 00000000..ec4518b1 --- /dev/null +++ b/_translations/po/pt-BR/guide_tutorial_using-yii-with-roadrunner.md.po @@ -0,0 +1,304 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-09-25 14:35+0000\n" +"PO-Revision-Date: 2026-09-25 14:35+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/cookbook/making-http-requests.md +#: ../src/cookbook/sentry-integration.md +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#: ../src/guide/tutorial/using-yii-with-swoole.md ../src/guide/views/asset.md +#: ../src/guide/views/view.md ../src/guide/views/widget.md +#, no-wrap +msgid "Installation" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/sentry-integration.md ../src/guide/concept/configuration.md +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#: ../src/guide/views/view-injections.md +#, no-wrap +msgid "Configuration" +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#: ../src/guide/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "Starting a server" +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#, no-wrap +msgid "On worker scope" +msgstr "" + +#. type: Title # +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#, no-wrap +msgid "Using Yii with RoadRunner" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#, no-wrap +msgid "" +"[RoadRunner](https://roadrunner.dev/) is a Golang-powered application server that integrates well with PHP. It runs\n" +"it as workers and each worker may handle multiple requests. Such an operation mode is often called\n" +"[event loop](using-with-event-loop.md) and allows not re-initializing a framework for each request that improves\n" +"performance significantly.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +msgid "RoadRunner works on Linux, macOS and Windows. The best way to install it is to use a Composer:" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#, no-wrap +msgid "composer require yiisoft/yii-runner-roadrunner\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +msgid "After installation is done, run" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#, no-wrap +msgid "./vendor/bin/rr get\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +msgid "That would download ready to use RoadRunner server `rr` binary." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +msgid "First, we need to configure the server itself. Create `/.rr.yaml` and add the following config:" +msgstr "" + +#. type: Fenced code block (yaml) +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#, no-wrap +msgid "" +"version: '3'\n" +"\n" +"server:\n" +" command: \"php worker.php\"\n" +"\n" +"rpc:\n" +" listen: tcp://127.0.0.1:6001\n" +"\n" +"http:\n" +" address: :8080\n" +" pool:\n" +" debug: false # set to true for local development only\n" +" supervisor:\n" +" max_worker_memory: 192\n" +" middleware: [static, gzip, headers, sendfile]\n" +" static:\n" +" dir: \"public\"\n" +" forbid: [\".php\", \".htaccess\"]\n" +" headers:\n" +" response:\n" +" \"Cache-Control\": \"no-cache\"\n" +"\n" +"logs:\n" +" mode: production\n" +" level: warn\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#, no-wrap +msgid "" +"> [!INFO]\n" +"> Read more about TLS, HTTP/2, HTTP/3 configuration and other middleware [on the RoadRunner docs](https://docs.roadrunner.dev/docs/http/http).\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +msgid "We're specifying that the entry script is `worker.php`, the server listens on port 8080, `public` directory files are served statically except `.php` and `.htaccess`. The `max_worker_memory` is a soft limit: if a worker exceeds 192 MB, it will restart after finishing its current request. Also, we're sending an additional header." +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#, no-wrap +msgid "KV cache" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +msgid "RoadRunner has a [KV plugin](https://docs.roadrunner.dev/docs/key-value/overview-kv) that can be used as a PSR-16 cache storage. It is useful when the application already runs under RoadRunner and needs a cache shared by workers." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +msgid "Install the PHP bridge and Yii cache package:" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#, no-wrap +msgid "composer require spiral/roadrunner-kv yiisoft/cache\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +msgid "Add a KV storage to `.rr.yaml`:" +msgstr "" + +#. type: Fenced code block (yaml) +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#, no-wrap +msgid "" +"kv:\n" +" cache:\n" +" driver: memory\n" +" config:\n" +" interval: 60\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +msgid "The `memory` driver stores values inside the RoadRunner process, so its data is lost when RoadRunner stops. For persistent cache storage, use another KV driver from the RoadRunner documentation." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +msgid "Create `config/common/di/roadrunner-kv.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#, no-wrap +msgid "" +" static function (): StorageInterface {\n" +" $factory = new Factory(RPC::create('tcp://127.0.0.1:6001'));\n" +"\n" +" return $factory->select('cache');\n" +" },\n" +"\n" +" SimpleCacheInterface::class => StorageInterface::class,\n" +" YiiCacheInterface::class => Cache::class,\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +msgid "Now services can use `Yiisoft\\Cache\\CacheInterface` the same way as with other cache backends:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#, no-wrap +msgid "" +"use Yiisoft\\Cache\\CacheInterface;\n" +"\n" +"final readonly class FeedService\n" +"{\n" +" public function __construct(\n" +" private CacheInterface $cache,\n" +" ) {\n" +" }\n" +"\n" +" public function latest(): array\n" +" {\n" +" return $this->cache->getOrSet('feed-latest', fn (): array => $this->loadLatest(), 60);\n" +" }\n" +"\n" +" private function loadLatest(): array\n" +" {\n" +" return [];\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +msgid "Create `/worker.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#, no-wrap +msgid "" +"run();\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#: ../src/guide/tutorial/using-yii-with-swoole.md +msgid "To start a server, execute the following command:" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#, no-wrap +msgid "./rr serve\n" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +msgid "Each worker's scope is isolated from other workers. Memory isn't shared." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +msgid "A single worker serves multiple requests where the scope is shared." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +msgid "At each iteration of the event loop, every service that depends on state should be reset." +msgstr "" diff --git a/_translations/po/pt-BR/guide_tutorial_using-yii-with-swoole.md.po b/_translations/po/pt-BR/guide_tutorial_using-yii-with-swoole.md.po new file mode 100644 index 00000000..52e3e0f8 --- /dev/null +++ b/_translations/po/pt-BR/guide_tutorial_using-yii-with-swoole.md.po @@ -0,0 +1,262 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-10-07 20:23+0000\n" +"PO-Revision-Date: 2026-10-07 20:23+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/cookbook/making-http-requests.md +#: ../src/cookbook/sentry-integration.md +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md +#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#: ../src/guide/tutorial/using-yii-with-rapira.md +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#: ../src/guide/tutorial/using-yii-with-swoole.md ../src/guide/views/asset.md +#: ../src/guide/views/view.md ../src/guide/views/widget.md +#, no-wrap +msgid "Installation" +msgstr "" + +#. type: Title ## +#: ../src/guide/runtime/sessions.md +#: ../src/guide/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "Sessions" +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#: ../src/guide/tutorial/using-yii-with-rapira.md +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#: ../src/guide/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "Starting a server" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#: ../src/guide/tutorial/using-yii-with-swoole.md +msgid "To start a server, execute the following command:" +msgstr "" + +#. type: Title # +#: ../src/guide/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "Using Yii with Swoole" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "" +"[Swoole](https://www.swoole.com/) is a PHP extension for event-driven, coroutine-based network applications. It\n" +"includes an HTTP server, coroutine APIs, and runtime hooks for common blocking I/O functions.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-swoole.md +msgid "Swoole allows Yii request handlers to run as workers. Each worker may handle multiple requests. Such an operation mode is often called [event loop](using-with-event-loop.md) and allows not re-initializing a framework for each request that improves performance significantly." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-swoole.md +msgid "Swoole supports Linux, macOS, Cygwin, and WSL. Install the extension through PECL:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/guide/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "pecl install swoole\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-swoole.md +msgid "If PECL doesn't enable the extension automatically, add it to your `php.ini`:" +msgstr "" + +#. type: Fenced code block (ini) +#: ../src/guide/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "extension=swoole.so\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-swoole.md +msgid "Check that PHP loads the extension:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/guide/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "php --ri swoole\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-swoole.md +msgid "The Swoole project also provides a [Docker image](https://github.com/swoole/docker-swoole) and documents source builds with optional features such as OpenSSL, sockets, MySQL, PostgreSQL, and curl hooks." +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "Putting up a server" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-swoole.md +msgid "Swoole passes `Swoole\\Http\\Request` and `Swoole\\Http\\Response` objects to request callbacks. Yii handles PSR-7 requests and responses, so add a converter package:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/guide/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "composer require ilexn/swoole-convert-psr7\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-swoole.md +msgid "Create an entry script, `server.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "" +"setLevels([\n" +" LogLevel::EMERGENCY,\n" +" LogLevel::ERROR,\n" +" LogLevel::WARNING,\n" +" ]),\n" +" ],\n" +" ),\n" +" new HtmlRenderer(),\n" +" ),\n" +");\n" +"\n" +"$container = $runner->getContainer();\n" +"$application = $container->get(Application::class);\n" +"$errorCatcher = $container->get(ErrorCatcher::class);\n" +"\n" +"$serverRequestFactory = new SwooleServerRequestConverter(\n" +" $container->get(ServerRequestFactoryInterface::class),\n" +" $container->get(UriFactoryInterface::class),\n" +" $container->get(UploadedFileFactoryInterface::class),\n" +" $container->get(StreamFactoryInterface::class)\n" +");\n" +"\n" +"$server = new Server('0.0.0.0', 9501);\n" +"\n" +"$server->on('start', static function (Server $server) use ($application) {\n" +" $application->start();\n" +" echo \"Swoole http server is started at http://127.0.0.1:9501\\n\";\n" +"});\n" +"\n" +"$server->on('request', static function (\n" +" Request $request,\n" +" Response $response\n" +") use ($serverRequestFactory, $application, $errorCatcher, $container) {\n" +" try {\n" +" $psr7Request = $serverRequestFactory->createFromSwoole($request);\n" +" $psr7Response = $application->handle($psr7Request);\n" +" (new SwooleResponseConverter($response))->send($psr7Response);\n" +" } catch (Throwable $throwable) {\n" +" $handler = new ThrowableHandler($throwable);\n" +" $psr7Response = $errorCatcher->process($request, $handler);\n" +" (new SwooleResponseConverter($response))->send($psr7Response);\n" +" }\n" +" $application->afterEmit($psr7Response);\n" +" $container->get(StateResetter::class)->reset();\n" +"});\n" +"\n" +"$server->on('shutdown', static function (Server $server) use ($application) {\n" +" $application->shutdown();\n" +"});\n" +"\n" +"$server->start();\n" +msgstr "" + +#. type: Fenced code block +#: ../src/guide/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "php server.php\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "On scope" +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-swoole.md +msgid "A scope is shared, so at each iteration of the event loop every service that depends on state should be reset." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-swoole.md +msgid "Avoid native PHP sessions, including `Yiisoft\\Session\\Session`, when Swoole coroutines handle overlapping requests within one worker: they share session state and can expose one user's data to another request." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-swoole.md +msgid "For requests handled one at a time, close the session and reset services between requests. `yiisoft/session` prevents stale session ID reuse, but does not isolate overlapping coroutines." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-swoole.md +msgid "For authentication, consider tokens such as [JWT](https://jwt.io/introduction) instead of native sessions, especially for APIs. If you need session features, use an implementation that isolates each coroutine's session data; changing the native storage handler to Redis is not enough." +msgstr "" + +#. type: Plain text +#: ../src/guide/tutorial/using-yii-with-swoole.md +msgid "See the [Swoole guidance](https://github.com/swoole/swoole-src/issues/4478#issuecomment-962840796) and [Yii session discussion](https://github.com/yiisoft/session/issues/25)." +msgstr "" diff --git a/_translations/po/pt-BR/guide_views_asset.md.po b/_translations/po/pt-BR/guide_views_asset.md.po new file mode 100644 index 00000000..d4fc1fc1 --- /dev/null +++ b/_translations/po/pt-BR/guide_views_asset.md.po @@ -0,0 +1,997 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-05-05 22:01+0000\n" +"PO-Revision-Date: 2026-05-05 22:01+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/cookbook/deployment/docker-swarm-caddy.md +#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/guide/views/asset.md +#, no-wrap +msgid "Troubleshooting" +msgstr "" + +#. type: Title ## +#: ../src/cookbook/making-http-requests.md +#: ../src/cookbook/sentry-integration.md +#: ../src/guide/tutorial/using-yii-with-frankenphp.md +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#: ../src/guide/tutorial/using-yii-with-swoole.md ../src/guide/views/asset.md +#: ../src/guide/views/view.md ../src/guide/views/widget.md +#, no-wrap +msgid "Installation" +msgstr "" + +#. type: Title # +#: ../src/guide/views/asset.md +#, no-wrap +msgid "Assets" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/asset.md +msgid "Asset management is crucial for modern web applications. Assets include CSS stylesheets, JavaScript files, images, fonts, and other static resources. Yii3 provides a comprehensive asset management system through the `yiisoft/assets` package that handles dependencies, optimization, and deployment of these resources." +msgstr "" + +#. type: Plain text +#: ../src/guide/views/asset.md +msgid "The asset management functionality is provided by the `yiisoft/assets` package:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/guide/views/asset.md +#, no-wrap +msgid "composer require yiisoft/assets\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/asset.md +msgid "This package is included by default in the `yiisoft/app` application template." +msgstr "" + +#. type: Title ## +#: ../src/guide/views/asset.md ../src/guide/views/view.md +#: ../src/guide/views/widget.md +#, no-wrap +msgid "Basic Concepts" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/asset.md +#, no-wrap +msgid "Asset Bundles" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/asset.md +msgid "An asset bundle is a collection of related asset files (CSS, JavaScript, images) that are logically grouped together. Asset bundles can depend on other bundles, allowing for proper dependency management." +msgstr "" + +#. type: Title ### +#: ../src/guide/views/asset.md +#, no-wrap +msgid "Asset Manager" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/asset.md +msgid "The Asset Manager is responsible for: - Resolving asset bundle dependencies - Publishing assets from protected directories to web-accessible locations - Combining and minifying assets (when configured) - Generating proper URLs for assets" +msgstr "" + +#. type: Title ## +#: ../src/guide/views/asset.md +#, no-wrap +msgid "Creating Asset Bundles" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/asset.md +#, no-wrap +msgid "Basic Asset Bundle" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/asset.md +msgid "Here's a simple asset bundle definition:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/asset.md +#, no-wrap +msgid "" +" 'print'],\n" +" ['css/admin/mobile.css', 'media' => 'screen and (max-width: 768px)'],\n" +" ];\n" +" \n" +" // JavaScript files with attributes\n" +" public array $js = [\n" +" 'js/admin/core.js',\n" +" ['js/admin/charts.js', 'defer' => true],\n" +" ['js/admin/analytics.js', 'async' => true],\n" +" ];\n" +" \n" +" // Global options for all JS files in this bundle\n" +" public array $jsOptions = [\n" +" 'data-admin' => 'true',\n" +" ];\n" +" \n" +" // Global options for all CSS files in this bundle\n" +" public array $cssOptions = [\n" +" 'data-bundle' => 'admin',\n" +" ];\n" +" \n" +" public array $depends = [\n" +" MainAsset::class,\n" +" ChartJsAsset::class,\n" +" ];\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/views/asset.md +#, no-wrap +msgid "Using Asset Bundles" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/asset.md +#, no-wrap +msgid "In Controllers" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/asset.md +msgid "Register asset bundles in your controllers or views:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/asset.md +#, no-wrap +msgid "" +"assetManager->register(MainAsset::class);\n" +" \n" +" return $this->viewRenderer->render('index', [\n" +" 'title' => 'Home Page',\n" +" ]);\n" +" }\n" +" \n" +" public function admin(): ResponseInterface\n" +" {\n" +" // Register multiple asset bundles\n" +" $this->assetManager->registerMany([\n" +" MainAsset::class,\n" +" AdminAsset::class,\n" +" ]);\n" +" \n" +" return $this->viewRenderer->render('admin/dashboard');\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/asset.md +#, no-wrap +msgid "In Views" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/asset.md +msgid "You can also register assets directly in views:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/asset.md +#, no-wrap +msgid "" +"register(ProductAsset::class);\n" +"?>\n" +"\n" +"
\n" +"

\n" +" \n" +"
\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/asset.md +#, no-wrap +msgid "With WebView Integration" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/asset.md +msgid "The recommended approach is to integrate with WebView for automatic asset rendering:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/asset.md +#, no-wrap +msgid "" +"register(MainAsset::class);\n" +"\n" +"// Add all registered assets to the view\n" +"$this->addCssFiles($assetManager->getCssFiles());\n" +"$this->addCssStrings($assetManager->getCssStrings());\n" +"$this->addJsFiles($assetManager->getJsFiles());\n" +"$this->addJsStrings($assetManager->getJsStrings());\n" +"$this->addJsVars($assetManager->getJsVars());\n" +"?>\n" +"\n" +"
\n" +" \n" +"
\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/views/asset.md +#, no-wrap +msgid "Asset Publishing" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/asset.md +#, no-wrap +msgid "Source Path Publishing" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/asset.md +msgid "When assets are located in non-web-accessible directories (like vendor packages), they need to be published:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/asset.md +#, no-wrap +msgid "" +"publish('@vendor/company/package/assets');\n" +"\n" +"// Get the published URL\n" +"$publishedUrl = $assetManager->getPublishedUrl('@vendor/company/package/assets');\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/views/asset.md +#, no-wrap +msgid "Third-party Library Assets" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/asset.md +#, no-wrap +msgid "jQuery Asset Bundle" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/asset.md +#, no-wrap +msgid "" +" 'sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3',\n" +" 'crossorigin' => 'anonymous',\n" +" ];\n" +"\n" +" public array $js = [\n" +" 'https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js',\n" +" ];\n" +"\n" +" public array $jsOptions = [\n" +" 'integrity' => 'sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p',\n" +" 'crossorigin' => 'anonymous',\n" +" ];\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/views/asset.md +#, no-wrap +msgid "Asset Configuration" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/asset.md +#, no-wrap +msgid "Application Configuration" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/asset.md +msgid "Configure asset management in your application configuration:" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/asset.md +#, no-wrap +msgid "**config/web/params.php**\n" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/asset.md +#, no-wrap +msgid "" +"return [\n" +" 'yiisoft/assets' => [\n" +" // Base path for published assets\n" +" 'basePath' => '@webroot/assets',\n" +" \n" +" // Base URL for assets\n" +" 'baseUrl' => '@web/assets',\n" +" \n" +" // Asset converter configuration\n" +" 'converter' => [\n" +" 'commands' => [\n" +" 'scss' => ['sass', '{from}', '{to}', '--style=compressed'],\n" +" 'ts' => ['tsc', '{from}', '--outFile', '{to}'],\n" +" ],\n" +" ],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/asset.md +#, no-wrap +msgid "Environment-specific Assets" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/asset.md +msgid "Configure different assets for different environments:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/asset.md +#, no-wrap +msgid "" +"css = ['css/main.css', 'css/debug.css'];\n" +" $this->js = ['js/main.js', 'js/debug.js'];\n" +" } else {\n" +" // Production assets (minified)\n" +" $this->css = ['css/main.min.css'];\n" +" $this->js = ['js/main.min.js'];\n" +" }\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/views/asset.md +#, no-wrap +msgid "Asset Optimization" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/asset.md +#, no-wrap +msgid "Asset Combination" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/asset.md +msgid "Combine multiple CSS or JavaScript files into single files:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/asset.md +#, no-wrap +msgid "" +"/**\n" +" * @var \\Yiisoft\\Assets\\AssetManager $assetManager\n" +" */\n" +"\n" +"// Enable asset combination\n" +"$assetManager->setCombine(true);\n" +"\n" +"// Set combination options\n" +"$assetManager->setCombineOptions([\n" +" 'css' => true, // Combine CSS files\n" +" 'js' => true, // Combine JavaScript files\n" +"]);\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/asset.md +#, no-wrap +msgid "Asset Compression" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/asset.md +msgid "Configure asset compression for production:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/asset.md +#, no-wrap +msgid "" +"// In your asset manager configuration\n" +"'converter' => [\n" +" 'commands' => [\n" +" 'css' => ['cleancss', '{from}', '-o', '{to}'],\n" +" 'js' => ['uglifyjs', '{from}', '-o', '{to}', '--compress', '--mangle'],\n" +" ],\n" +"],\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/views/asset.md +#, no-wrap +msgid "Working with Asset Converter" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/asset.md +#, no-wrap +msgid "SCSS/SASS Compilation" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/asset.md +#, no-wrap +msgid "" +" 'screen and (max-width: 768px)'],\n" +" ];\n" +" \n" +" public array $depends = [\n" +" AppAsset::class,\n" +" ];\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/views/asset.md ../src/guide/views/script-style-meta.md +#: ../src/guide/views/template-engines.md +#, no-wrap +msgid "Best Practices" +msgstr "" + +#. type: Bullet: '1. ' +#: ../src/guide/views/asset.md +msgid "**Organize by functionality**: Group related assets into logical bundles" +msgstr "" + +#. type: Bullet: '2. ' +#: ../src/guide/views/asset.md +msgid "**Manage dependencies**: Properly declare dependencies between bundles" +msgstr "" + +#. type: Bullet: '3. ' +#: ../src/guide/views/asset.md +msgid "**Use meaningful names**: Name your asset bundles clearly" +msgstr "" + +#. type: Bullet: '4. ' +#: ../src/guide/views/asset.md +msgid "**Environment optimization**: Use minified assets in production" +msgstr "" + +#. type: Bullet: '5. ' +#: ../src/guide/views/asset.md +msgid "**CDN consideration**: Use CDN for popular libraries when appropriate" +msgstr "" + +#. type: Bullet: '6. ' +#: ../src/guide/views/asset.md +msgid "**Version your assets**: Include version numbers in filenames for cache busting" +msgstr "" + +#. type: Bullet: '7. ' +#: ../src/guide/views/asset.md +msgid "**Minimize HTTP requests**: Combine related assets when possible" +msgstr "" + +#. type: Bullet: '8. ' +#: ../src/guide/views/asset.md +msgid "**Optimize file sizes**: Compress and minify assets for production" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/asset.md +#, no-wrap +msgid "Common Issues" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/asset.md +#, no-wrap +msgid "" +"**Asset not found:**\n" +"- Check that the asset file exists in the specified path\n" +"- Verify `$basePath` and `$baseUrl` are configured correctly\n" +"- Ensure assets are published if using `$sourcePath`\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/asset.md +#, no-wrap +msgid "" +"**Dependencies not loading:**\n" +"- Verify the dependency bundles are properly registered\n" +"- Check for circular dependencies\n" +"- Ensure dependency bundles are correctly configured\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/asset.md +#, no-wrap +msgid "" +"**Assets not appearing in HTML:**\n" +"- Make sure you're calling `$this->addCssFiles()` and `$this->addJsFiles()` in your layout\n" +"- Verify that `$this->head()`, `$this->beginBody()`, and `$this->endBody()` are called in the layout\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/asset.md +#, no-wrap +msgid "" +"**Permission issues:**\n" +"- Check that the web server has write permissions to the assets directory\n" +"- Verify the published assets directory is web-accessible\n" +msgstr "" diff --git a/_translations/po/pt-BR/guide_views_script-style-meta.md.po b/_translations/po/pt-BR/guide_views_script-style-meta.md.po new file mode 100644 index 00000000..f77827bf --- /dev/null +++ b/_translations/po/pt-BR/guide_views_script-style-meta.md.po @@ -0,0 +1,783 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-12-24 13:00+0000\n" +"PO-Revision-Date: 2025-12-24 13:00+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/guide/structure/overview.md ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "Overview" +msgstr "" + +#. type: Title ## +#: ../src/guide/views/asset.md ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "Practical Examples" +msgstr "" + +#. type: Title ## +#: ../src/guide/views/asset.md ../src/guide/views/script-style-meta.md +#: ../src/guide/views/template-engines.md +#, no-wrap +msgid "Best Practices" +msgstr "" + +#. type: Title # +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "Scripts, styles and meta tags" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/script-style-meta.md +msgid "Modern web applications require careful management of CSS styles, JavaScript code, and HTML meta tags. Yii3 provides a comprehensive system for registering and organizing these resources through the `WebView` class, which is part of the `yiisoft/view` package." +msgstr "" + +#. type: Plain text +#: ../src/guide/views/script-style-meta.md +msgid "The `WebView` class extends the basic `View` class with web-specific functionality, allowing you to:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/views/script-style-meta.md +msgid "Register CSS files and inline styles" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/views/script-style-meta.md +msgid "Register JavaScript files and inline scripts" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/views/script-style-meta.md +msgid "Manage HTML meta tags and link tags" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/views/script-style-meta.md +msgid "Control the position where resources are rendered" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/guide/views/script-style-meta.md +msgid "Handle dependencies between resources" +msgstr "" + +#. type: Title ## +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "CSS management" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "Registering CSS Files" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/script-style-meta.md +msgid "You can register CSS files to be included in your HTML pages:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "" +"registerCssFile('/css/styles.css');\n" +"\n" +"// Register CSS file with attributes\n" +"$this->registerCssFile('/css/print.css', WebView::POSITION_HEAD, [\n" +" 'media' => 'print',\n" +"]);\n" +"\n" +"// Register CSS file with custom key to avoid duplicates\n" +"$this->registerCssFile('/css/theme.css', WebView::POSITION_HEAD, [], 'theme-css');\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "Registering Inline CSS" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/script-style-meta.md +msgid "For inline CSS styles, use the `registerCss()` method:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "" +"// Register inline CSS\n" +"$this->registerCss('\n" +" .highlight {\n" +" background-color: yellow;\n" +" font-weight: bold;\n" +" }\n" +" .error {\n" +" color: red;\n" +" border: 1px solid red;\n" +" }\n" +"', WebView::POSITION_HEAD);\n" +"\n" +"// With custom attributes\n" +"$this->registerCss('\n" +" @media print {\n" +" .no-print { display: none; }\n" +" }\n" +"', WebView::POSITION_HEAD, ['id' => 'print-styles']);\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "CSS from Files" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/script-style-meta.md +msgid "You can also register CSS content from external files:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "" +"// Read CSS from a file and register as inline CSS\n" +"$this->registerCssFromFile('/path/to/dynamic-styles.css', WebView::POSITION_HEAD, [\n" +" 'id' => 'dynamic-styles',\n" +"]);\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "Using Style Tags" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/script-style-meta.md +msgid "For more control, you can use HTML style tags directly:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "" +"use Yiisoft\\Html\\Html;\n" +"\n" +"$styleTag = Html::style('\n" +" .custom-button {\n" +" background: linear-gradient(45deg, #blue, #purple);\n" +" border: none;\n" +" color: white;\n" +" padding: 10px 20px;\n" +" }\n" +"', ['id' => 'custom-button-styles']);\n" +"\n" +"$this->registerStyleTag($styleTag, WebView::POSITION_HEAD);\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "JavaScript management" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "Registering JavaScript Files" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/script-style-meta.md +msgid "Include external JavaScript files using `registerJsFile()`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "" +"// Register a JavaScript file\n" +"$this->registerJsFile('/js/main.js');\n" +"\n" +"// Register with attributes (async loading)\n" +"$this->registerJsFile('/js/analytics.js', WebView::POSITION_END, [\n" +" 'async' => true,\n" +"]);\n" +"\n" +"// Register with defer attribute\n" +"$this->registerJsFile('/js/interactive.js', WebView::POSITION_END, [\n" +" 'defer' => true,\n" +"]);\n" +"\n" +"// Register from CDN\n" +"$this->registerJsFile('https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js', \n" +" WebView::POSITION_END, [], 'jquery');\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "Registering Inline JavaScript" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/script-style-meta.md +msgid "Add inline JavaScript code with `registerJs()`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "" +"// Register inline JavaScript\n" +"$this->registerJs('\n" +" document.addEventListener(\"DOMContentLoaded\", function() {\n" +" console.log(\"Page loaded!\");\n" +" initializeComponents();\n" +" });\n" +"', WebView::POSITION_END);\n" +"\n" +"// Register JavaScript that should run when DOM is ready\n" +"$this->registerJs('\n" +" function showAlert(message) {\n" +" alert(message);\n" +" }\n" +"', WebView::POSITION_READY);\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "JavaScript Variables" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/script-style-meta.md +msgid "Pass PHP data to JavaScript using `registerJsVar()`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "" +"// Register JavaScript variables\n" +"$this->registerJsVar('apiUrl', 'https://api.example.com');\n" +"$this->registerJsVar('currentUser', [\n" +" 'id' => $user->getId(),\n" +" 'name' => $user->getName(),\n" +" 'isAdmin' => $user->isAdmin(),\n" +"]);\n" +"$this->registerJsVar('config', [\n" +" 'debug' => $this->isDebugMode(),\n" +" 'locale' => $this->getLocale(),\n" +"]);\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/script-style-meta.md +msgid "This generates JavaScript code like:" +msgstr "" + +#. type: Fenced code block (html) +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "" +"\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "Using Script Tags" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/script-style-meta.md +msgid "For more control over script tags:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "" +"use Yiisoft\\Html\\Html;\n" +"\n" +"$scriptTag = Html::script('\n" +" window.myApp = {\n" +" init: function() {\n" +" console.log(\"App initialized\");\n" +" }\n" +" };\n" +"', ['type' => 'module']);\n" +"\n" +"$this->registerScriptTag($scriptTag, WebView::POSITION_END);\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "Position Constants" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/script-style-meta.md +msgid "Resources can be positioned at different locations in the HTML document:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "" +"use Yiisoft\\View\\WebView;\n" +"\n" +"// In the section\n" +"WebView::POSITION_HEAD\n" +"\n" +"// At the beginning of \n" +"WebView::POSITION_BEGIN \n" +"\n" +"// At the end of (before )\n" +"WebView::POSITION_END\n" +"\n" +"// When DOM is ready (jQuery document.ready equivalent)\n" +"WebView::POSITION_READY\n" +"\n" +"// When page is fully loaded (window.onload equivalent)\n" +"WebView::POSITION_LOAD\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/script-style-meta.md +msgid "Example layout showing where each position is rendered:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "" +"\n" +"beginPage() ?>\n" +"\n" +"\n" +"\n" +" \n" +" head() ?>\n" +"\n" +"\n" +" \n" +" beginBody() ?>\n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" endBody() ?>\n" +"\n" +"\n" +"endPage() ?>\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "Meta tags" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "Basic Meta Tags" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/script-style-meta.md +msgid "Register meta tags for SEO and page information:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "" +"// Register meta tags using array syntax\n" +"$this->registerMeta(['name' => 'description', 'content' => 'Page description']);\n" +"$this->registerMeta(['name' => 'keywords', 'content' => 'yii, php, framework']);\n" +"$this->registerMeta(['name' => 'author', 'content' => 'John Doe']);\n" +"$this->registerMeta(['name' => 'robots', 'content' => 'index, follow']);\n" +"\n" +"// Viewport for responsive design\n" +"$this->registerMeta(['name' => 'viewport', 'content' => 'width=device-width, initial-scale=1']);\n" +"\n" +"// Open Graph tags for social media\n" +"$this->registerMeta(['property' => 'og:title', 'content' => 'Page Title']);\n" +"$this->registerMeta(['property' => 'og:description', 'content' => 'Page description']);\n" +"$this->registerMeta(['property' => 'og:image', 'content' => 'https://example.com/image.jpg']);\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "Using Meta Tag Objects" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/script-style-meta.md +msgid "For more control, use the `Html::meta()` helper:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "" +"use Yiisoft\\Html\\Html;\n" +"\n" +"// Create meta tags with the Html helper\n" +"$this->registerMetaTag(\n" +" Html::meta()\n" +" ->name('description')\n" +" ->content('This is a comprehensive guide to Yii3 views')\n" +");\n" +"\n" +"$this->registerMetaTag(\n" +" Html::meta()\n" +" ->httpEquiv('refresh')\n" +" ->content('300') // Refresh every 5 minutes\n" +");\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "Preventing Duplicate Meta Tags" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/script-style-meta.md +msgid "Use keys to prevent duplicate meta tags:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "" +"// First registration\n" +"$this->registerMeta([\n" +" 'name' => 'description',\n" +" 'content' => 'Original description'\n" +"], 'description');\n" +"\n" +"// This will override the previous one\n" +"$this->registerMeta([\n" +" 'name' => 'description', \n" +" 'content' => 'Updated description'\n" +"], 'description');\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "Link tags" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "Basic Link Tags" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/script-style-meta.md +msgid "Register various types of link tags:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "" +"// Favicon\n" +"$this->registerLink([\n" +" 'rel' => 'icon',\n" +" 'type' => 'image/png',\n" +" 'href' => '/favicon.png',\n" +"]);\n" +"\n" +"// RSS feed\n" +"$this->registerLink([\n" +" 'rel' => 'alternate',\n" +" 'type' => 'application/rss+xml',\n" +" 'title' => 'RSS Feed',\n" +" 'href' => '/feed.rss',\n" +"]);\n" +"\n" +"// Canonical URL\n" +"$this->registerLink([\n" +" 'rel' => 'canonical',\n" +" 'href' => 'https://example.com/canonical-url',\n" +"]);\n" +"\n" +"// Preload resources\n" +"$this->registerLink([\n" +" 'rel' => 'preload',\n" +" 'href' => '/fonts/main.woff2',\n" +" 'as' => 'font',\n" +" 'type' => 'font/woff2',\n" +" 'crossorigin' => 'anonymous',\n" +"]);\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "Using Link Tag Objects" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "" +"use Yiisoft\\Html\\Html;\n" +"\n" +"// CSS stylesheet\n" +"$this->registerLinkTag(\n" +" Html::link('/css/main.css', [\n" +" 'rel' => 'stylesheet',\n" +" ])\n" +");\n" +"\n" +"// DNS prefetch\n" +"$this->registerLinkTag(\n" +" Html::link('https://fonts.googleapis.com', [\n" +" 'rel' => 'dns-prefetch',\n" +" ])\n" +");\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "Complete Page Setup" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/script-style-meta.md +msgid "Here's how you might set up a complete page with all types of resources:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "" +"setTitle($title);\n" +"\n" +"// Meta tags\n" +"$this->registerMeta(['name' => 'description', 'content' => $description]);\n" +"$this->registerMeta(['name' => 'keywords', 'content' => 'ecommerce, products, online shop']);\n" +"\n" +"// Open Graph tags\n" +"$this->registerMeta(['property' => 'og:title', 'content' => $title]);\n" +"$this->registerMeta(['property' => 'og:description', 'content' => $description]);\n" +"$this->registerMeta(['property' => 'og:image', 'content' => $product['image']]);\n" +"\n" +"// CSS files\n" +"$this->registerCssFile('/css/product.css');\n" +"$this->registerCssFile('/css/responsive.css', WebView::POSITION_HEAD, [\n" +" 'media' => 'screen and (max-width: 768px)',\n" +"]);\n" +"\n" +"// JavaScript files\n" +"$this->registerJsFile('/js/product-gallery.js', WebView::POSITION_END);\n" +"$this->registerJsFile('/js/shopping-cart.js', WebView::POSITION_END);\n" +"\n" +"// JavaScript variables\n" +"$this->registerJsVar('productData', $product);\n" +"$this->registerJsVar('cartApiUrl', '/api/cart');\n" +"\n" +"// Inline JavaScript\n" +"$this->registerJs('\n" +" document.addEventListener(\"DOMContentLoaded\", function() {\n" +" initProductGallery();\n" +" initShoppingCart();\n" +" });\n" +"', WebView::POSITION_END);\n" +"\n" +"// Page-specific styles\n" +"$this->registerCss('\n" +" .product-special {\n" +" background: linear-gradient(45deg, #ff6b6b, #4ecdc4);\n" +" padding: 20px;\n" +" border-radius: 10px;\n" +" }\n" +"', WebView::POSITION_HEAD);\n" +"?>\n" +"\n" +"
\n" +" \n" +"
\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "Conditional Resource Loading" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/script-style-meta.md +msgid "Load resources based on conditions:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "" +"registerCssFile('/css/dark-theme.css');\n" +"} else {\n" +" $this->registerCssFile('/css/light-theme.css');\n" +"}\n" +"\n" +"// Admin-specific resources\n" +"if ($isAdmin) {\n" +" $this->registerCssFile('/css/admin-toolbar.css');\n" +" $this->registerJsFile('/js/admin-functions.js');\n" +"}\n" +"\n" +"// Role-based JavaScript configuration\n" +"$this->registerJsVar('userPermissions', [\n" +" 'canEdit' => in_array($userRole, ['admin', 'editor']),\n" +" 'canDelete' => $userRole === 'admin',\n" +" 'canPublish' => in_array($userRole, ['admin', 'publisher']),\n" +"]);\n" +"?>\n" +msgstr "" + +#. type: Bullet: '1. ' +#: ../src/guide/views/script-style-meta.md +msgid "**Use appropriate positions**: Place CSS in `POSITION_HEAD`, JavaScript at `POSITION_END`" +msgstr "" + +#. type: Bullet: '2. ' +#: ../src/guide/views/script-style-meta.md +msgid "**Minimize inline resources**: Prefer external files for better caching" +msgstr "" + +#. type: Bullet: '3. ' +#: ../src/guide/views/script-style-meta.md +msgid "**Use keys for duplicates**: Prevent duplicate resources with meaningful keys" +msgstr "" + +#. type: Bullet: '4. ' +#: ../src/guide/views/script-style-meta.md +msgid "**Optimize loading**: Use `async` and `defer` attributes for non-critical JavaScript" +msgstr "" + +#. type: Bullet: '5. ' +#: ../src/guide/views/script-style-meta.md +msgid "**Group related resources**: Keep related CSS and JS files together" +msgstr "" + +#. type: Bullet: '6. ' +#: ../src/guide/views/script-style-meta.md +msgid "**Use CDNs wisely**: Balance performance with reliability" +msgstr "" + +#. type: Bullet: '7. ' +#: ../src/guide/views/script-style-meta.md +msgid "**Validate meta tags**: Ensure proper SEO meta tags are set" +msgstr "" + +#. type: Bullet: '8. ' +#: ../src/guide/views/script-style-meta.md +msgid "**Consider security**: Be careful with inline scripts and CSP policies" +msgstr "" + +#. type: Title ## +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "Working with Asset Bundles" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/script-style-meta.md +msgid "For more complex asset management, consider using asset bundles:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/script-style-meta.md +#, no-wrap +msgid "" +"// Register an asset bundle (covered in detail in the Assets guide)\n" +"$assetBundle = $this->assetManager->register(MainAsset::class);\n" +"\n" +"// Add all CSS files from the bundle\n" +"$this->addCssFiles($this->assetManager->getCssFiles());\n" +"\n" +"// Add all JavaScript files from the bundle \n" +"$this->addJsFiles($this->assetManager->getJsFiles());\n" +msgstr "" diff --git a/_translations/po/pt-BR/guide_views_template-engines.md.po b/_translations/po/pt-BR/guide_views_template-engines.md.po new file mode 100644 index 00000000..9df94dc9 --- /dev/null +++ b/_translations/po/pt-BR/guide_views_template-engines.md.po @@ -0,0 +1,363 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-01-26 18:48+0000\n" +"PO-Revision-Date: 2026-01-26 18:48+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/guide/views/asset.md ../src/guide/views/script-style-meta.md +#: ../src/guide/views/template-engines.md +#, no-wrap +msgid "Best Practices" +msgstr "" + +#. type: Title # +#: ../src/guide/views/template-engines.md +#, no-wrap +msgid "Template engines" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/template-engines.md +msgid "Yii3 supports multiple template engines through a flexible renderer system. By default, PHP is used as the template engine, but you can easily add support for other engines like Twig and [Blade](https://github.com/lee-to/yii-blade), or create your own custom renderers." +msgstr "" + +#. type: Plain text +#: ../src/guide/views/template-engines.md +msgid "PHP templates were described in the \"[View](view.md)\" guide section." +msgstr "" + +#. type: Title ## +#: ../src/guide/views/template-engines.md +#, no-wrap +msgid "Twig Template Engine" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/template-engines.md +msgid "Twig is a modern template engine that provides a more designer-friendly syntax. To use Twig in your Yii3 application, you need to install the Twig extension." +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/guide/views/template-engines.md +#, no-wrap +msgid "composer require yiisoft/view-twig\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/template-engines.md +msgid "Now you can use `.twig` templates. For example, `views/site/about.twig`:" +msgstr "" + +#. type: Fenced code block (twig) +#: ../src/guide/views/template-engines.md +#, no-wrap +msgid "" +"{# Variable type hints for IDE support #}\n" +"{# @var user \\App\\Entity\\User #}\n" +"{# @var posts \\App\\Entity\\Post[] #}\n" +"\n" +"
\n" +"

{{ user.name }}

\n" +"

Email: {{ user.email }}

\n" +" \n" +" {% if posts is not empty %}\n" +"

Recent Posts

\n" +"
    \n" +" {% for post in posts %}\n" +"
  • \n" +"

    {{ post.title }}

    \n" +"

    {{ post.excerpt }}

    \n" +" \n" +"
  • \n" +" {% endfor %}\n" +"
\n" +" {% else %}\n" +"

No posts available.

\n" +" {% endif %}\n" +"
\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/template-engines.md +#, no-wrap +msgid "Twig Features" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/template-engines.md +#, no-wrap +msgid "**Automatic Escaping**: Twig automatically escapes variables for HTML context:\n" +msgstr "" + +#. type: Fenced code block (twig) +#: ../src/guide/views/template-engines.md +#, no-wrap +msgid "" +"{# Automatically escaped #}\n" +"

{{ title }}

\n" +"\n" +"{# Raw output (use carefully) #}\n" +"
{{ content|raw }}
\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/template-engines.md +#, no-wrap +msgid "**Filters and Functions**: Twig provides many built-in filters and functions:\n" +msgstr "" + +#. type: Fenced code block (twig) +#: ../src/guide/views/template-engines.md +#, no-wrap +msgid "" +"{# Date formatting #}\n" +"\n" +"\n" +"{# String manipulation #}\n" +"

{{ description|truncate(100) }}

\n" +"\n" +"{# URL generation #}\n" +"Profile\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/template-engines.md +#, no-wrap +msgid "**Template Inheritance**: Twig supports template inheritance:\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/template-engines.md +#, no-wrap +msgid "**views/layout/main.twig**\n" +msgstr "" + +#. type: Fenced code block (twig) +#: ../src/guide/views/template-engines.md +#, no-wrap +msgid "" +"\n" +"\n" +"\n" +" {% block title %}Default Title{% endblock %}\n" +"\n" +"\n" +"
\n" +" {% block content %}{% endblock %}\n" +"
\n" +"\n" +"\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/template-engines.md +#, no-wrap +msgid "**views/site/about.twig**\n" +msgstr "" + +#. type: Fenced code block (twig) +#: ../src/guide/views/template-engines.md +#, no-wrap +msgid "" +"{% extends \"layout/main.twig\" %}\n" +"\n" +"{% block title %}About Us{% endblock %}\n" +"\n" +"{% block content %}\n" +"

About Our Company

\n" +"

Welcome to our website!

\n" +"{% endblock %}\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/template-engines.md +#, no-wrap +msgid "Rendering Twig Templates" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/template-engines.md +msgid "Use Twig templates the same way as PHP templates:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/template-engines.md +#, no-wrap +msgid "" +"// In your controller\n" +"public function about(): ResponseInterface\n" +"{\n" +" return $this->viewRenderer->render('about.twig', [\n" +" 'user' => $this->getCurrentUser(),\n" +" 'posts' => $this->getRecentPosts(),\n" +" ]);\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/views/template-engines.md +#, no-wrap +msgid "Custom Template Engines" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/template-engines.md +msgid "You can create custom template engines by implementing the `TemplateRendererInterface`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/template-engines.md +#, no-wrap +msgid "" +" $value) {\n" +" $content = str_replace(\"{{$key}}\", (string) $value, $content);\n" +" }\n" +" \n" +" return $this->parser->parse($content);\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/template-engines.md +msgid "Register your custom renderer:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/template-engines.md +#, no-wrap +msgid "" +"use Yiisoft\\Container\\Reference;\n" +"\n" +"// In configuration\n" +"'yiisoft/view' => [\n" +" 'renderers' => [\n" +" 'md' => Reference::to(App\\View\\MarkdownRenderer::class),\n" +" ],\n" +"],\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/template-engines.md +msgid "Now you can use `.md` template files:" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/template-engines.md +#, no-wrap +msgid "**views/content/help.md**\n" +msgstr "" + +#. type: Fenced code block (markdown) +#: ../src/guide/views/template-engines.md +#, no-wrap +msgid "" +"# Help: {{title}}\n" +"\n" +"Welcome, {{username}}!\n" +"\n" +"This is a Markdown template with **bold** and *italic* text.\n" +"\n" +"- Feature 1\n" +"- Feature 2\n" +"- Feature 3\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/views/template-engines.md +#, no-wrap +msgid "Choosing the Right Template Engine" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/template-engines.md +#, no-wrap +msgid "" +"**Use PHP templates when:**\n" +"- You need maximum flexibility and performance\n" +"- Your team is comfortable with PHP\n" +"- You want to leverage existing PHP knowledge\n" +"- You need complex logic in templates (though this should be minimized)\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/template-engines.md +#, no-wrap +msgid "" +"**Use Twig templates when:**\n" +"- You want stricter separation between logic and presentation\n" +"- You work with designers who prefer cleaner syntax\n" +"- You need automatic escaping and security features\n" +"- You want template inheritance and advanced features\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/template-engines.md +#, no-wrap +msgid "" +"**Use custom templates when:**\n" +"- You have specific requirements not met by PHP or Twig\n" +"- You're working with specialized content formats\n" +"- You need integration with external template systems\n" +msgstr "" + +#. type: Bullet: '1. ' +#: ../src/guide/views/template-engines.md +msgid "**Keep templates simple**: Move complex logic to controllers or services" +msgstr "" + +#. type: Bullet: '2. ' +#: ../src/guide/views/template-engines.md +msgid "**Always escape output**: Prevent XSS attacks by properly escaping variables" +msgstr "" + +#. type: Bullet: '3. ' +#: ../src/guide/views/template-engines.md +msgid "**Use meaningful names**: Name your templates and variables clearly" +msgstr "" + +#. type: Bullet: '4. ' +#: ../src/guide/views/template-engines.md +msgid "**Organize templates**: Group related templates in subdirectories" +msgstr "" + +#. type: Bullet: '5. ' +#: ../src/guide/views/template-engines.md +msgid "**Document variables**: Always add type hints for better IDE support" +msgstr "" + +#. type: Bullet: '6. ' +#: ../src/guide/views/template-engines.md +msgid "**Avoid business logic**: Keep business logic in models and services" +msgstr "" diff --git a/_translations/po/pt-BR/guide_views_view-injections.md.po b/_translations/po/pt-BR/guide_views_view-injections.md.po new file mode 100644 index 00000000..0f074a2f --- /dev/null +++ b/_translations/po/pt-BR/guide_views_view-injections.md.po @@ -0,0 +1,179 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-12-24 13:00+0000\n" +"PO-Revision-Date: 2025-12-24 13:00+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/cookbook/sentry-integration.md ../src/guide/concept/configuration.md +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#: ../src/guide/views/view-injections.md +#, no-wrap +msgid "Configuration" +msgstr "" + +#. type: Title # +#: ../src/guide/views/view-injections.md +#, no-wrap +msgid "View injections" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/view-injections.md +msgid "The view injections are designed to provide a standardized way to pass parameters to the common layer of views in an application. It allows developers to manage the data that will be available across various views, ensuring flexibility and reusability of code." +msgstr "" + +#. type: Plain text +#: ../src/guide/views/view-injections.md +msgid "The view injections could be used if you require `yiisoft/yii-view-renderer` package:" +msgstr "" + +#. type: Fenced code block (sh) +#: ../src/guide/views/view-injections.md ../src/guide/views/view.md +#, no-wrap +msgid "composer require yiisoft/yii-view-renderer\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/view-injections.md +msgid "In config `params.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/view-injections.md +#, no-wrap +msgid "" +"...\n" +"'yiisoft/yii-view' => [\n" +" 'injections' => [\n" +" Reference::to(ContentViewInjection::class),\n" +" Reference::to(CsrfViewInjection::class),\n" +" Reference::to(LayoutViewInjection::class),\n" +" ],\n" +" ],\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/views/view-injections.md +#, no-wrap +msgid "New injections" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/view-injections.md +msgid "Start by defining a class that will implement the `Yiisoft\\Yii\\View\\Renderer\\CommonParametersInjectionInterface`. This class will be responsible for providing the parameters you want to inject into your view templates and layouts." +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/view-injections.md +#, no-wrap +msgid "" +"class MyCustomParametersInjection implements Yiisoft\\Yii\\View\\Renderer\\CommonParametersInjectionInterface\n" +"{\n" +" // Class properties and methods will go here\n" +"\n" +" public function __construct(UserService $userService)\n" +" {\n" +" $this->userService = $userService;\n" +" }\n" +"\n" +" public function getCommonParameters(): array\n" +" {\n" +" return [\n" +" 'siteName' => 'My Awesome Site',\n" +" 'currentYear' => date('Y'),\n" +" 'user' => $this->userService->getCurrentUser(),\n" +" ];\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/view-injections.md +msgid "Add your new Injection to `params.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/view-injections.md +#, no-wrap +msgid "" +"'yiisoft/yii-view' => [\n" +" 'injections' => [\n" +" ...,\n" +" Reference::to(MyCustomParametersInjection::class),\n" +" ],\n" +" ],\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/views/view-injections.md +#, no-wrap +msgid "Using Separate Injections for Different Layouts" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/view-injections.md +msgid "If your application has multiple layouts, you can create separate parameter injections for each layout. This approach allows you to tailor the parameters injected into each layout according to its specific needs, enhancing the flexibility and maintainability of your application." +msgstr "" + +#. type: Plain text +#: ../src/guide/views/view-injections.md +msgid "Create your custom ViewInjection for a specific layout:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/view-injections.md +#, no-wrap +msgid "" +"readonly final class CartViewInjection implements CommonParametersInjectionInterface\n" +"{\n" +" public function __construct(private Cart $cart)\n" +" {\n" +" }\n" +"\n" +" public function getCommonParameters(): array\n" +" {\n" +" return [\n" +" 'cart' => $this->cart,\n" +" ];\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/view-injections.md +msgid "Add your new injection to `params.php` under specific layout name. In the following example, it's `@layout/cart`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/view-injections.md +#, no-wrap +msgid "" +"'yiisoft/yii-view' => [\n" +" 'injections' => [\n" +" ...,\n" +" Reference::to(MyCustomParametersInjection::class),\n" +" DynamicReference::to(static function (ContainerInterface $container) {\n" +" $cart = $container\n" +" ->get(Cart::class);\n" +"\n" +" return new LayoutSpecificInjections(\n" +" '@layout/cart', // layout name for injection\n" +"\n" +" new CartViewInjection($cart)\n" +" );\n" +" }),\n" +" ],\n" +" ],\n" +msgstr "" diff --git a/_translations/po/pt-BR/guide_views_view.md.po b/_translations/po/pt-BR/guide_views_view.md.po new file mode 100644 index 00000000..5c3eba68 --- /dev/null +++ b/_translations/po/pt-BR/guide_views_view.md.po @@ -0,0 +1,490 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-02-25 03:25+0000\n" +"PO-Revision-Date: 2026-02-25 03:25+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/cookbook/making-http-requests.md +#: ../src/cookbook/sentry-integration.md +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#: ../src/guide/tutorial/using-yii-with-swoole.md ../src/guide/views/asset.md +#: ../src/guide/views/view.md ../src/guide/views/widget.md +#, no-wrap +msgid "Installation" +msgstr "" + +#. type: Title # +#: ../src/guide/index.md ../src/guide/views/view.md +#, no-wrap +msgid "Views" +msgstr "Views" + +#. type: Fenced code block (php) +#: ../src/guide/start/hello.md ../src/guide/views/view.md +#, no-wrap +msgid "" +"\n" +"\n" +"

The message is:

\n" +msgstr "" +"\n" +"\n" +"

The message is:

\n" + +#. type: Fenced code block (php) +#: ../src/guide/start/hello.md ../src/guide/views/view.md +#, no-wrap +msgid "" +"viewRenderer->render(__DIR__ . '/template', [\n" +" 'message' => $message,\n" +" ]);\n" +" }\n" +"}\n" +msgstr "" +"viewRenderer->render(__DIR__ . '/template', [\n" +" 'message' => $message,\n" +" ]);\n" +" }\n" +"}\n" + +#. type: Title ## +#: ../src/guide/views/asset.md ../src/guide/views/view.md +#: ../src/guide/views/widget.md +#, no-wrap +msgid "Basic Concepts" +msgstr "" + +#. type: Fenced code block (sh) +#: ../src/guide/views/view-injections.md ../src/guide/views/view.md +#, no-wrap +msgid "composer require yiisoft/yii-view-renderer\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/view.md +msgid "View is responsible for presenting data to end users. You give it a template with some placeholders and presentation logic and some data. The view is passing data to the template executing template logic. The end result is ready to be passed to end user, be it a browser, a file to download, an email to send or something else." +msgstr "" + +#. type: Fenced code block (mermaid) +#: ../src/guide/views/view.md +#, no-wrap +msgid "" +"flowchart LR\n" +" A[Data] --> V[View]\n" +" B[Template] --> V\n" +" V --> C[HTML]\n" +" C --> D[Browser]\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/view.md +msgid "In Yii3 views are typically PHP files that contain presentation logic and HTML markup. The view system provides a flexible way to organize your presentation layer and supports features like layouts and partial views. Instead of using plain PHP templates, you can leverage one of the template engines such as [Twig](template-engines.md) or [Blade](https://github.com/lee-to/yii-blade)." +msgstr "" + +#. type: Plain text +#: ../src/guide/views/view.md +msgid "For basic view functionality, you need the `yiisoft/view` package:" +msgstr "" + +#. type: Fenced code block (sh) +#: ../src/guide/views/view.md +#, no-wrap +msgid "composer require yiisoft/view\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/view.md +msgid "For web applications, you should also install the `yiisoft/yii-view-renderer` package which provides [PSR-7](https://www.php-fig.org/psr/psr-7/) compatibility and web-specific features:" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/view.md ../src/guide/views/widget.md +msgid "These packages are included by default in the `yiisoft/app` application template." +msgstr "" + +#. type: Plain text +#: ../src/guide/views/view.md +msgid "A view template file contains presentation logic. In the `yiisoft/app` template, view files are typically stored alongside their controllers (e.g., `src/Web/Echo/Action.php`). Here's a simple view file example, `src/Web/Echo/template.php`:" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/view.md +msgid "Here `$message` is a view data that is passed when you render a template with the help of `WebViewRenderer`. For example, `src/Web/Echo/Action.php`:" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/view.md +msgid "First argument of the `render()` method is a path to the template file. In the `yiisoft/app`, template files are typically stored alongside their actions. The result is ready to be rendered to the browser so we return it immediately." +msgstr "" + +#. type: Title ## +#: ../src/guide/views/view.md +#, no-wrap +msgid "Working with layouts" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/view.md +msgid "Most web applications use a common layout for all pages. In the `yiisoft/app` template, layouts are stored in `src/Web/Shared/Layout/Main/` directory. You can set a default layout in `config/common/params.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/view.md +#, no-wrap +msgid "" +"return [\n" +" 'yiisoft/yii-view-renderer' => [\n" +" 'viewPath' => null,\n" +" 'layout' => '@src/Web/Shared/Layout/Main/layout.php',\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/view.md +msgid "A typical layout file such as `src/Web/Shared/Layout/Main/layout.php` looks like this:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/view.md +#, no-wrap +msgid "" +"register(MainAsset::class);\n" +"\n" +"$this->addCssFiles($assetManager->getCssFiles());\n" +"$this->addCssStrings($assetManager->getCssStrings());\n" +"$this->addJsFiles($assetManager->getJsFiles());\n" +"$this->addJsStrings($assetManager->getJsStrings());\n" +"$this->addJsVars($assetManager->getJsVars());\n" +"\n" +"$this->beginPage()\n" +"?>\n" +"\n" +"locale) ?>\">\n" +"\n" +" charset) ?>\">\n" +" \n" +" get('@baseUrl/favicon.svg') ?>\" type=\"image/svg+xml\">\n" +" <?= Html::encode($this->getTitle()) ?>\n" +" head() ?>\n" +"\n" +"\n" +"beginBody() ?>\n" +"\n" +"\n" +"\n" +"
\n" +" \n" +"
\n" +"\n" +"
\n" +" © name) ?> \n" +"
\n" +"\n" +"endBody() ?>\n" +"\n" +"\n" +"endPage() ?>\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/view.md +msgid "In the template above `$applicationParams` is an array of parameters from `config/common/application.php`." +msgstr "" + +#. type: Plain text +#: ../src/guide/views/view.md +msgid "`$aliases` refers to [aliases component](../concept/aliases.md) that is used to get the base URL of the application at the server for URLs." +msgstr "" + +#. type: Plain text +#: ../src/guide/views/view.md +msgid "`$this` is an instance of the view that we use to get page title and output assets. Both standard and custom." +msgstr "" + +#. type: Plain text +#: ../src/guide/views/view.md +#, no-wrap +msgid "" +"With `$assetManager->register(MainAsset::class);` we register an asset that defines `css` to include to the page. It is\n" +"automatically copied to `public/assets` on first use. It is not very useful for a single CSS file but becomes handy as\n" +"the number of assets grows.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/view.md +#, no-wrap +msgid "" +"> [!IMPORTANT]\n" +"> No output in plain PHP templates is encoded you should not forget to use `Html::encode()` to prevent\n" +"XSS security vulnerabilities.\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/view.md +msgid "More about what's available in layout could be read in [yiisoft/view](https://github.com/yiisoft/view) documentation." +msgstr "" + +#. type: Title ### +#: ../src/guide/views/view.md +#, no-wrap +msgid "Rendering without layout" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/view.md +msgid "Sometimes you need to render a view without a layout (for example, for AJAX responses):" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/view.md +#, no-wrap +msgid "" +"public function ajaxContent(): ResponseInterface\n" +"{\n" +" return $this->viewRenderer\n" +" ->withLayout(null)\n" +" ->render('ajax-content', ['data' => $data]);\n" +"}\n" +"\n" +"// Or use the renderPartial method\n" +"public function ajaxContent(): ResponseInterface\n" +"{\n" +" return $this->viewRenderer->renderPartial('ajax-content', ['data' => $data]);\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/views/view.md +#, no-wrap +msgid "Nested Views and Partials" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/view.md +#, no-wrap +msgid "Rendering Sub-views" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/view.md +#, no-wrap +msgid "You can render other views from within a view using the `$this->render()` method:\n" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/view.md +#, no-wrap +msgid "" +"\n" +"
\n" +" \n" +" render('_post_item', ['post' => $post]) ?>\n" +" \n" +"
\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/view.md +#, no-wrap +msgid "**src/Web/Post/_item.php**\n" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/view.md +#, no-wrap +msgid "" +"\n" +"
\n" +"

getTitle()) ?>

\n" +"

getExcerpt()) ?>

\n" +" \n" +"
\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/view.md +#, no-wrap +msgid "Using Blocks" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/view.md +msgid "Blocks allow you to define content in one view and display it in another, typically in layouts:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/view.md +#, no-wrap +msgid "" +"// In a view file\n" +"setBlock('sidebar', $this->render('_sidebar', ['items' => $sidebarItems])) ?>\n" +"\n" +"// In the layout file\n" +"hasBlock('sidebar')): ?>\n" +" \n" +"\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/views/view.md +#, no-wrap +msgid "Rendering as String" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/view.md +msgid "If you need the rendered content as a string instead of a PSR-7 response:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/view.md +#, no-wrap +msgid "" +"public function getEmailContent(): string\n" +"{\n" +" return $this->viewRenderer->renderAsString('email/welcome', [\n" +" 'user' => $user,\n" +" ]);\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/views/view.md +#, no-wrap +msgid "View Events" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/view.md +msgid "The view system triggers events during the rendering process that you can listen to:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/view.md +#, no-wrap +msgid "" +"use Yiisoft\\View\\Event\\WebView\\BeforeRender;\n" +"use Yiisoft\\View\\Event\\WebView\\AfterRender;\n" +"\n" +"// Example event listener\n" +"final class ViewEventListener\n" +"{\n" +" public function onBeforeRender(BeforeRender $event): void\n" +" {\n" +" // Add global CSS class based on view name\n" +" if (str_contains($event->getFile(), 'admin/')) {\n" +" $event->getView()->registerCssClass('admin-view');\n" +" }\n" +" }\n" +"\n" +" public function onAfterRender(AfterRender $event): void\n" +" {\n" +" // Log rendering time\n" +" $this->logger->info('View rendered', [\n" +" 'view' => $event->getFile(),\n" +" 'time' => $event->getRenderTime(),\n" +" ]);\n" +" }\n" +"}\n" +msgstr "" diff --git a/_translations/po/pt-BR/guide_views_widget.md.po b/_translations/po/pt-BR/guide_views_widget.md.po new file mode 100644 index 00000000..5835a096 --- /dev/null +++ b/_translations/po/pt-BR/guide_views_widget.md.po @@ -0,0 +1,1032 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-12-24 13:00+0000\n" +"PO-Revision-Date: 2025-12-24 13:00+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/cookbook/making-http-requests.md +#: ../src/cookbook/sentry-integration.md +#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#: ../src/guide/tutorial/using-yii-with-swoole.md ../src/guide/views/asset.md +#: ../src/guide/views/view.md ../src/guide/views/widget.md +#, no-wrap +msgid "Installation" +msgstr "" + +#. type: Title ## +#: ../src/guide/views/asset.md ../src/guide/views/view.md +#: ../src/guide/views/widget.md +#, no-wrap +msgid "Basic Concepts" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/view.md ../src/guide/views/widget.md +msgid "These packages are included by default in the `yiisoft/app` application template." +msgstr "" + +#. type: Title # +#: ../src/guide/views/widget.md +#, no-wrap +msgid "Widgets" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/widget.md +msgid "Widgets are reusable, self-contained components that encapsulate complex HTML generation logic. They provide a clean way to create configurable UI elements that can be used across different views and applications. Yii3 provides a flexible widget system through the `yiisoft/widget` package." +msgstr "" + +#. type: Plain text +#: ../src/guide/views/widget.md +msgid "The widget functionality is provided by the `yiisoft/widget` package:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/guide/views/widget.md +#, no-wrap +msgid "composer require yiisoft/widget\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/widget.md +msgid "For ready-made widgets (like forms, navigation, etc.), you can also install:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../src/guide/views/widget.md +#, no-wrap +msgid "composer require yiisoft/yii-widgets\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/widget.md +#, no-wrap +msgid "Widget Class" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/widget.md +msgid "A widget is a PHP class that extends the abstract `Widget` class and implements a `render()` method that returns HTML content as a string." +msgstr "" + +#. type: Title ### +#: ../src/guide/views/widget.md +#, no-wrap +msgid "Widget Factory" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/widget.md +msgid "The `WidgetFactory` is responsible for creating widget instances and can inject dependencies through the DI container." +msgstr "" + +#. type: Title ### +#: ../src/guide/views/widget.md +#, no-wrap +msgid "Widget Configuration" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/widget.md +msgid "Widgets can be configured with properties and methods, making them highly customizable and reusable across different contexts." +msgstr "" + +#. type: Title ## +#: ../src/guide/views/widget.md +#, no-wrap +msgid "Creating Custom Widgets" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/widget.md +#, no-wrap +msgid "Simple Widget" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/widget.md +msgid "Here's a basic widget that displays an alert message:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/widget.md +#, no-wrap +msgid "" +"message = $message;\n" +" return $new;\n" +" }\n" +"\n" +" public function type(string $type): self\n" +" {\n" +" $new = clone $this;\n" +" $new->type = $type;\n" +" return $new;\n" +" }\n" +"\n" +" public function closeable(bool $closeable = true): self\n" +" {\n" +" $new = clone $this;\n" +" $new->closeable = $closeable;\n" +" return $new;\n" +" }\n" +"\n" +" protected function render(): string\n" +" {\n" +" if (empty($this->message)) {\n" +" return '';\n" +" }\n" +"\n" +" $classes = ['alert', 'alert-' . $this->type];\n" +" \n" +" if ($this->closeable) {\n" +" $classes[] = 'alert-dismissible';\n" +" }\n" +"\n" +" $content = Html::encode($this->message);\n" +" \n" +" if ($this->closeable) {\n" +" $content .= Html::button('×', [\n" +" 'type' => 'button',\n" +" 'class' => 'btn-close',\n" +" 'data-bs-dismiss' => 'alert',\n" +" ]);\n" +" }\n" +"\n" +" return Html::div($content, ['class' => implode(' ', $classes)]);\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/widget.md +#, no-wrap +msgid "Using the Widget" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/widget.md +#, no-wrap +msgid "" +"\n" +"\n" +"
\n" +" message('Operation completed successfully!')\n" +" ->type('success')\n" +" ->closeable() ?>\n" +" \n" +" message('Please review the form errors below.')\n" +" ->type('danger') ?>\n" +"
\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/widget.md +#, no-wrap +msgid "Widget with Dependencies" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/widget.md +msgid "Widgets can use dependency injection for services:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/widget.md +#, no-wrap +msgid "" +"userService->getCurrentUser();\n" +" \n" +" if ($currentUser === null) {\n" +" return $this->renderLoginLink();\n" +" }\n" +"\n" +" return $this->renderUserMenu($currentUser);\n" +" }\n" +"\n" +" private function renderLoginLink(): string\n" +" {\n" +" return Html::a('Login', $this->urlGenerator->generate('login'), [\n" +" 'class' => 'btn btn-primary',\n" +" ]);\n" +" }\n" +"\n" +" private function renderUserMenu($user): string\n" +" {\n" +" $items = [\n" +" Html::a('Profile', $this->urlGenerator->generate('user.profile'), [\n" +" 'class' => 'dropdown-item',\n" +" ]),\n" +" Html::a('Settings', $this->urlGenerator->generate('user.settings'), [\n" +" 'class' => 'dropdown-item',\n" +" ]),\n" +" '
',\n" +" Html::a('Logout', $this->urlGenerator->generate('logout'), [\n" +" 'class' => 'dropdown-item',\n" +" ]),\n" +" ];\n" +"\n" +" return Html::div(\n" +" Html::button(\n" +" Html::encode($user->getName()) . ' ',\n" +" [\n" +" 'class' => 'btn btn-secondary dropdown-toggle',\n" +" 'type' => 'button',\n" +" 'data-bs-toggle' => 'dropdown',\n" +" ]\n" +" ) .\n" +" Html::div(implode('', $items), ['class' => 'dropdown-menu']),\n" +" ['class' => 'dropdown']\n" +" );\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/views/widget.md +#, no-wrap +msgid "Widget Factory Setup" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/widget.md +#, no-wrap +msgid "Bootstrap Configuration" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/widget.md +msgid "Initialize the widget factory in your application bootstrap:" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/widget.md +#, no-wrap +msgid "**config/bootstrap.php**\n" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/widget.md +#, no-wrap +msgid "" +" [\n" +" 'type()' => ['info'],\n" +" 'closeable()' => [true],\n" +" ],\n" +" App\\Widget\\CardWidget::class => [\n" +" 'headerClass()' => ['card-header bg-primary text-white'],\n" +" ],\n" +"];\n" +"\n" +"WidgetFactory::initialize($container, $widgetDefaults);\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/widget.md +#, no-wrap +msgid "DI Container Configuration" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/widget.md +#, no-wrap +msgid "**config/web/di.php**\n" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/widget.md +#, no-wrap +msgid "" +"use App\\Widget\\AlertWidget;\n" +"use App\\Widget\\UserMenuWidget;\n" +"\n" +"return [\n" +" // Widget configurations can be defined here if needed\n" +" AlertWidget::class => static fn() => new AlertWidget(),\n" +" \n" +" UserMenuWidget::class => static fn(\n" +" App\\Service\\UserService $userService,\n" +" Yiisoft\\Router\\UrlGeneratorInterface $urlGenerator\n" +" ) => new UserMenuWidget($userService, $urlGenerator),\n" +"];\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/views/widget.md +#, no-wrap +msgid "Advanced Widget Examples" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/widget.md +#, no-wrap +msgid "Data List Widget" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/widget.md +msgid "A widget that displays a list of items with pagination:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/widget.md +#, no-wrap +msgid "" +"paginator = $paginator;\n" +" return $new;\n" +" }\n" +"\n" +" public function itemRenderer(callable $renderer): self\n" +" {\n" +" $new = clone $this;\n" +" $new->itemRenderer = $renderer;\n" +" return $new;\n" +" }\n" +"\n" +" public function containerClass(string $class): self\n" +" {\n" +" $new = clone $this;\n" +" $new->containerClass = $class;\n" +" return $new;\n" +" }\n" +"\n" +" public function itemClass(string $class): self\n" +" {\n" +" $new = clone $this;\n" +" $new->itemClass = $class;\n" +" return $new;\n" +" }\n" +"\n" +" public function emptyText(string $text): self\n" +" {\n" +" $new = clone $this;\n" +" $new->emptyText = $text;\n" +" return $new;\n" +" }\n" +"\n" +" protected function render(): string\n" +" {\n" +" if ($this->paginator === null) {\n" +" return '';\n" +" }\n" +"\n" +" $items = $this->paginator->read();\n" +" \n" +" if (empty($items)) {\n" +" return Html::div($this->emptyText, ['class' => 'empty-message']);\n" +" }\n" +"\n" +" $itemsHtml = '';\n" +" foreach ($items as $item) {\n" +" $content = $this->itemRenderer \n" +" ? ($this->itemRenderer)($item)\n" +" : Html::encode((string) $item);\n" +" \n" +" $itemsHtml .= Html::div($content, ['class' => $this->itemClass]);\n" +" }\n" +"\n" +" return Html::div($itemsHtml, ['class' => $this->containerClass]);\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/widget.md +msgid "Usage:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/widget.md +#, no-wrap +msgid "" +"\n" +"\n" +"paginator($postPaginator)\n" +" ->containerClass('posts-list row')\n" +" ->itemClass('col-md-4 mb-3')\n" +" ->itemRenderer(function ($post) {\n" +" return $this->render('_post_card', ['post' => $post]);\n" +" }) ?>\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/widget.md +#, no-wrap +msgid "Form Widget" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/widget.md +msgid "A widget that simplifies form rendering:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/widget.md +#, no-wrap +msgid "" +"model = $model;\n" +" return $new;\n" +" }\n" +"\n" +" public function action(string $action): self\n" +" {\n" +" $new = clone $this;\n" +" $new->action = $action;\n" +" return $new;\n" +" }\n" +"\n" +" public function method(string $method): self\n" +" {\n" +" $new = clone $this;\n" +" $new->method = $method;\n" +" return $new;\n" +" }\n" +"\n" +" public function options(array $options): self\n" +" {\n" +" $new = clone $this;\n" +" $new->options = $options;\n" +" return $new;\n" +" }\n" +"\n" +" public function field(string $attribute, array $options = []): self\n" +" {\n" +" $new = clone $this;\n" +" $new->fields[$attribute] = $options;\n" +" return $new;\n" +" }\n" +"\n" +" protected function render(): string\n" +" {\n" +" if ($this->model === null) {\n" +" return '';\n" +" }\n" +"\n" +" $formOptions = array_merge([\n" +" 'action' => $this->action,\n" +" 'method' => $this->method,\n" +" 'class' => 'form',\n" +" ], $this->options);\n" +"\n" +" $content = '';\n" +" foreach ($this->fields as $attribute => $options) {\n" +" $content .= $this->renderField($attribute, $options);\n" +" }\n" +"\n" +" return Html::form($content, $formOptions);\n" +" }\n" +"\n" +" private function renderField(string $attribute, array $options): string\n" +" {\n" +" $label = $options['label'] ?? ucfirst($attribute);\n" +" $type = $options['type'] ?? 'text';\n" +" $class = $options['class'] ?? 'form-control';\n" +"\n" +" $field = Html::div(\n" +" Html::label($label, null, ['class' => 'form-label']) .\n" +" Html::input($type, $attribute, $this->getModelValue($attribute), [\n" +" 'class' => $class,\n" +" 'id' => $attribute,\n" +" ]),\n" +" ['class' => 'mb-3']\n" +" );\n" +"\n" +" return $field;\n" +" }\n" +"\n" +" private function getModelValue(string $attribute): mixed\n" +" {\n" +" return $this->model->getAttributeValue($attribute);\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/widget.md +#, no-wrap +msgid "Breadcrumb Widget" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/widget.md +msgid "A widget for navigation breadcrumbs:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/widget.md +#, no-wrap +msgid "" +"items = $items;\n" +" return $new;\n" +" }\n" +"\n" +" public function separator(string $separator): self\n" +" {\n" +" $new = clone $this;\n" +" $new->separator = $separator;\n" +" return $new;\n" +" }\n" +"\n" +" public function options(array $options): self\n" +" {\n" +" $new = clone $this;\n" +" $new->options = $options;\n" +" return $new;\n" +" }\n" +"\n" +" protected function render(): string\n" +" {\n" +" if (empty($this->items)) {\n" +" return '';\n" +" }\n" +"\n" +" $links = [];\n" +" $itemCount = count($this->items);\n" +" \n" +" foreach ($this->items as $index => $item) {\n" +" if ($index === $itemCount - 1) {\n" +" // Last item (current page) - no link\n" +" $links[] = Html::span($item['label'], ['class' => 'breadcrumb-item active']);\n" +" } else {\n" +" // Regular breadcrumb item with link\n" +" $url = isset($item['url']) \n" +" ? (is_array($item['url']) \n" +" ? $this->urlGenerator->generate($item['url'][0], $item['url'][1] ?? [])\n" +" : $item['url'])\n" +" : '#';\n" +" \n" +" $links[] = Html::span(\n" +" Html::a($item['label'], $url),\n" +" ['class' => 'breadcrumb-item']\n" +" );\n" +" }\n" +" }\n" +"\n" +" $options = array_merge(['class' => 'breadcrumb'], $this->options);\n" +"\n" +" return Html::nav(\n" +" Html::ol(implode('', $links), ['class' => 'breadcrumb']),\n" +" $options\n" +" );\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/views/widget.md +#, no-wrap +msgid "Widget Best Practices" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/widget.md +#, no-wrap +msgid "Configuration Pattern" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/widget.md +msgid "Use immutable configuration methods:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/widget.md +#, no-wrap +msgid "" +"public function someProperty($value): self\n" +"{\n" +" $new = clone $this;\n" +" $new->someProperty = $value;\n" +" return $new;\n" +"}\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/widget.md +#, no-wrap +msgid "Validation" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/widget.md +msgid "Validate widget configuration in the render method:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/widget.md +#, no-wrap +msgid "" +"protected function render(): string\n" +"{\n" +" if (empty($this->items)) {\n" +" throw new InvalidArgumentException('Items cannot be empty.');\n" +" }\n" +" \n" +" // ... render logic\n" +"}\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/widget.md +#, no-wrap +msgid "HTML Encoding" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/widget.md +msgid "Always encode user data:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/widget.md +#, no-wrap +msgid "" +"protected function render(): string\n" +"{\n" +" return Html::div(Html::encode($this->userContent), [\n" +" 'class' => 'user-content',\n" +" ]);\n" +"}\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/widget.md +#, no-wrap +msgid "Asset Management" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/widget.md +msgid "Register widget-specific assets:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/widget.md +#, no-wrap +msgid "" +"assetManager->register(ChartWidgetAsset::class);\n" +" \n" +" // Render widget content\n" +" return $this->renderChart();\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/views/widget.md +#, no-wrap +msgid "Using Widgets in Layouts" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/widget.md +msgid "Widgets are particularly useful in layouts for common UI elements:" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/widget.md +#, no-wrap +msgid "**views/layout/main.php**\n" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/widget.md +#, no-wrap +msgid "" +"\n" +"\n" +"\n" +"\n" +" \n" +"\n" +"\n" +"
\n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +"
\n" +"\n" +"\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/views/widget.md +#, no-wrap +msgid "Testing Widgets" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/widget.md +#, no-wrap +msgid "Unit Testing" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/widget.md +msgid "Test widget rendering logic:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/widget.md +#, no-wrap +msgid "" +"message('Test message')\n" +" ->type('success');\n" +" \n" +" $output = $widget->render();\n" +" \n" +" $this->assertStringContainsString('Test message', $output);\n" +" $this->assertStringContainsString('alert-success', $output);\n" +" }\n" +" \n" +" public function testRenderEmpty(): void\n" +" {\n" +" $widget = AlertWidget::widget();\n" +" $output = $widget->render();\n" +" \n" +" $this->assertEmpty($output);\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../src/guide/views/widget.md +#, no-wrap +msgid "Common Widget Patterns" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/widget.md +#, no-wrap +msgid "Conditional Rendering" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/widget.md +#, no-wrap +msgid "" +"protected function render(): string\n" +"{\n" +" if (!$this->shouldRender()) {\n" +" return '';\n" +" }\n" +" \n" +" return $this->doRender();\n" +"}\n" +"\n" +"private function shouldRender(): bool\n" +"{\n" +" return !empty($this->items) && $this->isVisible;\n" +"}\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/widget.md +#, no-wrap +msgid "Template-based Rendering" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/widget.md +#, no-wrap +msgid "" +"protected function render(): string\n" +"{\n" +" return $this->renderTemplate('widget-template', [\n" +" 'items' => $this->items,\n" +" 'options' => $this->options,\n" +" ]);\n" +"}\n" +"\n" +"private function renderTemplate(string $template, array $data): string\n" +"{\n" +" // Use a view renderer to render template files\n" +" return $this->viewRenderer->renderPartialAsString($template, $data);\n" +"}\n" +msgstr "" + +#. type: Title ### +#: ../src/guide/views/widget.md +#, no-wrap +msgid "Event Integration" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/guide/views/widget.md +#, no-wrap +msgid "" +"protected function render(): string\n" +"{\n" +" $event = new BeforeWidgetRender($this);\n" +" $this->eventDispatcher->dispatch($event);\n" +" \n" +" $content = $this->doRender();\n" +" \n" +" $afterEvent = new AfterWidgetRender($this, $content);\n" +" $this->eventDispatcher->dispatch($afterEvent);\n" +" \n" +" return $afterEvent->getContent();\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/guide/views/widget.md +msgid "Widgets provide a powerful way to create reusable, configurable UI components in Yii3 applications. They help maintain clean separation of concerns and make your views more maintainable and testable." +msgstr "" diff --git a/_translations/po/pt-BR/index.md.po b/_translations/po/pt-BR/index.md.po new file mode 100644 index 00000000..0957e486 --- /dev/null +++ b/_translations/po/pt-BR/index.md.po @@ -0,0 +1,97 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-01-13 11:06+0000\n" +"PO-Revision-Date: 2026-01-13 11:06+0000\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Yaml Front Matter Hash Value: features details +#: ../src/index.md +#, no-wrap +msgid "Yii gives you the maximum functionality by adding the least possible overhead." +msgstr "O Yii oferece o máximo de funcionalidade com o mínimo possível de sobrecarga." + +#. type: Yaml Front Matter Hash Value: features title +#: ../src/index.md +#, no-wrap +msgid "Fast" +msgstr "Rápido" + +#. type: Yaml Front Matter Hash Value: features details +#: ../src/index.md +#, no-wrap +msgid "Sane defaults and built-in tools helps you write solid and secure code." +msgstr "Padrões sensatos e ferramentas embutidas ajudam você a escrever código sólido e seguro." + +#. type: Yaml Front Matter Hash Value: features title +#: ../src/index.md +#, no-wrap +msgid "Secure" +msgstr "Seguro" + +#. type: Yaml Front Matter Hash Value: features details +#: ../src/index.md +#, no-wrap +msgid "Write more code in less time with simple, yet powerful APIs and code generation." +msgstr "Escreva mais código em menos tempo com APIs simples e poderosas e com geração de código." + +#. type: Yaml Front Matter Hash Value: features title +#: ../src/index.md +#, no-wrap +msgid "Efficient" +msgstr "Eficiente" + +#. type: Yaml Front Matter Hash Value: hero actions text +#: ../src/index.md +#, no-wrap +msgid "Get Started" +msgstr "Comece agora" + +#. type: Yaml Front Matter Hash Value: hero name +#: ../src/index.md +#, no-wrap +msgid "Yii3 Framework" +msgstr "Yii3 Framework" + +#. type: Yaml Front Matter Hash Value: hero tagline +#: ../src/index.md +#, no-wrap +msgid "A simple, powerful and fast framework. Meet the modern, definitive guide to Yii you've always wanted." +msgstr "Um framework simples, poderoso e rápido. Conheça o guia definitivo e moderno do Yii que você sempre quis." + +#. type: Title ## +#: ../src/index.md ../src/internals/003-roadmap.md +#, no-wrap +msgid "Documentation" +msgstr "Documentação" + +#. type: Plain text +#: ../src/index.md +#, no-wrap +msgid "

\n" +msgstr "

\n" + +#. type: Bullet: '- ' +#: ../src/index.md +msgid "[The Definitive Guide](guide/) — the comprehensive guide covering all aspects of the framework." +msgstr "[Guia definitivo](guide/) — o guia completo que cobre todos os aspectos do framework." + +#. type: Bullet: '- ' +#: ../src/index.md +msgid "[Community Cookbook](cookbook/) — a collection of community-contributed tips, tricks, and solutions for common Yii development tasks." +msgstr "[Cookbook da comunidade](cookbook/) — uma coleção de dicas, truques e soluções da comunidade para tarefas comuns no desenvolvimento com Yii." + +#. type: Bullet: '- ' +#: ../src/index.md +msgid "[Internals](internals/) — documentation for developers contributing to the Yii framework itself, including guidelines, workflows, and best practices." +msgstr "[Detalhes internos](internals/) — documentação para quem contribui com o próprio framework Yii, incluindo diretrizes, fluxos de trabalho e boas práticas." diff --git a/_translations/po/pt-BR/internals_000-packages.md.po b/_translations/po/pt-BR/internals_000-packages.md.po new file mode 100644 index 00000000..fdee20da --- /dev/null +++ b/_translations/po/pt-BR/internals_000-packages.md.po @@ -0,0 +1,236 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-12-24 08:02+0000\n" +"PO-Revision-Date: 2025-12-24 08:02+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Bullet: ' - ' +#: ../src/en/guide/start/databases.md ../src/en/internals/000-packages.md +msgid "..." +msgstr "" + +#. type: Title # +#: ../src/en/internals/000-packages.md +#, no-wrap +msgid "000 — Packages" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/000-packages.md +msgid "Yii3 team divided the framework into several packages that conform to the following agreements." +msgstr "" + +#. type: Plain text +#: ../src/en/internals/000-packages.md +msgid "For all packages, the GitHub repository name exactly matches the Packagist package name." +msgstr "" + +#. type: Plain text +#: ../src/en/internals/000-packages.md +msgid "For a full list of packages and their building status, see [status page at yiiframework.com](https://www.yiiframework.com/status/3.0)." +msgstr "" + +#. type: Title ## +#: ../src/en/internals/000-packages.md +#, no-wrap +msgid "Yii-specific packages (framework and extensions)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/000-packages.md +msgid "named `yiisoft/yii-something` or more specific: `yii-type-something` e.g.:" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/en/internals/000-packages.md +msgid "modules: `yii-module-users`, `yii-module-pages`" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/en/internals/000-packages.md +msgid "themes: `yii-theme-adminlte`, `yii-theme-hyde`" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/en/internals/000-packages.md +msgid "widgets: `yii-widget-datepicker`" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/000-packages.md +msgid "titled as \"Yii Framework ...\"" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/000-packages.md +msgid "may have any dependencies and Yii-specific code" +msgstr "" + +#. type: Title ## +#: ../src/en/internals/000-packages.md +#, no-wrap +msgid "General purpose packages (libraries)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/000-packages.md +msgid "you can use these independently of Yii Framework" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/000-packages.md +msgid "named as `yiisoft/something` without yii-prefix" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/000-packages.md +msgid "titled as \"Yii ...\"" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/000-packages.md +msgid "must not have dependencies on any Yii-specific packages" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/000-packages.md +msgid "should have as fewer dependencies as possible" +msgstr "" + +#. type: Title ## +#: ../src/en/internals/000-packages.md +#, no-wrap +msgid "Configs and defaults" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/000-packages.md +msgid "The following applies to both Yii-specific packages and general purpose packages:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/000-packages.md +msgid "Package may have `config` directory with Yii-specific defaults." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/000-packages.md +msgid "Package may have \"config-plugin\" in \"extra\" section of `composer.json`." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/000-packages.md +msgid "Package mustn't have dependencies in `require` section of `composer.json` that are used in `config` only." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/000-packages.md +msgid "You should namespace parameters with `vendor/package-name`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/en/internals/000-packages.md +#, no-wrap +msgid "" +"return [\n" +" 'vendor/package-name' => [\n" +" 'param1' => 1,\n" +" 'param2' => 2,\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Title ## +#: ../src/en/internals/000-packages.md +#, no-wrap +msgid "Versions" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/000-packages.md +msgid "All packages follow [SemVer](https://semver.org/) versioning:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/000-packages.md +msgid "`x.*.*` - incompatible API changes." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/000-packages.md +msgid "`*.x.*` - add functionality (backwards-compatible)." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/000-packages.md +msgid "`*.*.x` - bug fixes (backwards-compatible)." +msgstr "" + +#. type: Plain text +#: ../src/en/internals/000-packages.md +msgid "The first stable version should be 1.0.0." +msgstr "" + +#. type: Plain text +#: ../src/en/internals/000-packages.md +msgid "Each package version number doesn't depend on any other package version or framework name/version, only on its own public contract. The framework as a whole has the \"Yii3\" name." +msgstr "" + +#. type: Plain text +#: ../src/en/internals/000-packages.md +msgid "It's alright to use packages with different major versions together, as long as they're compatible." +msgstr "" + +#. type: Title ## +#: ../src/en/internals/000-packages.md +#, no-wrap +msgid "PHP versions support" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/000-packages.md +msgid "The support of PHP versions supported for a package depends on [PHP versions life cycle](https://www.php.net/supported-versions.php)." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/000-packages.md +msgid "Package versions with active support MUST support all PHP versions that have active support." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/000-packages.md +msgid "Both packages and application templates MUST have supported versions that receive bug and security fixes. These SHOULD correspond to PHP versions receiving security fixes." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/000-packages.md +msgid "Packages and application templates MIGHT have supported versions that work with unsupported PHP versions." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/000-packages.md +msgid "Bumping the minimal PHP version in a package or an application template is a minor change." +msgstr "" + +#. type: Title ## +#: ../src/en/internals/000-packages.md +#, no-wrap +msgid "composer.json" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/000-packages.md +#, no-wrap +msgid "A logical OR operator in version ranges MUST use double pipe (`||`). For example: `\"yiisoft/arrays\": \"^1.0 || ^2.0\"`. \n" +msgstr "" diff --git a/_translations/po/pt-BR/internals_001-yii-values.md.po b/_translations/po/pt-BR/internals_001-yii-values.md.po new file mode 100644 index 00000000..4517234d --- /dev/null +++ b/_translations/po/pt-BR/internals_001-yii-values.md.po @@ -0,0 +1,242 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-12-24 08:02+0000\n" +"PO-Revision-Date: 2025-12-24 08:02+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/en/internals/001-yii-values.md +#, no-wrap +msgid "001 — Yii goal and values" +msgstr "" + +#. type: Title ## +#: ../src/en/internals/001-yii-values.md +#, no-wrap +msgid "Goal" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/001-yii-values.md +msgid "The Yii project aims to build and support _practical_ and _helpful_ tools and community." +msgstr "" + +#. type: Title ## +#: ../src/en/internals/001-yii-values.md +#, no-wrap +msgid "Values" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/001-yii-values.md +msgid "The values we express in our work support the goal. We try to" +msgstr "" + +#. type: Title ## +#: ../src/en/internals/001-yii-values.md +#, no-wrap +msgid "Be practical" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/en/internals/001-yii-values.md +msgid "[High performance](#high-performance)" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/en/internals/001-yii-values.md +msgid "[Sensible defaults and flexibility](#sensible-defaults-and-flexibility)" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/en/internals/001-yii-values.md +msgid "[Be practice-oriented](#be-practice-oriented)" +msgstr "" + +#. type: Title ## +#: ../src/en/internals/001-yii-values.md +#, no-wrap +msgid "Be helpful" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/en/internals/001-yii-values.md +msgid "[Be simple](#be-simple)" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/en/internals/001-yii-values.md +msgid "[Be explicit](#be-explicit)" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/en/internals/001-yii-values.md +msgid "[Be consistent](#be-consistent)" +msgstr "" + +#. type: Title ### +#: ../src/en/internals/001-yii-values.md +#, no-wrap +msgid "High performance" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/001-yii-values.md +msgid "Performance is a necessary condition of practicality. Software shouldn't waste machine resources or human resources." +msgstr "" + +#. type: Title ### +#: ../src/en/internals/001-yii-values.md +#, no-wrap +msgid "Sensible defaults and flexibility" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/001-yii-values.md +msgid "We prefer sensible defaults and conventions that users can customize. We seek a balance between flexibility, discipline and simplicity that meets common needs." +msgstr "" + +#. type: Title ### +#: ../src/en/internals/001-yii-values.md +#, no-wrap +msgid "Be practice-oriented" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/001-yii-values.md +msgid "We prefer practice to theory. For example:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/001-yii-values.md +msgid "Solutions for known use cases should avoid excess complexity by providing only necessary flexibility." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/001-yii-values.md +msgid "Standard implementations should take practical use into account." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/001-yii-values.md +msgid "Experience is at least as useful as theory in guiding design." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/001-yii-values.md +msgid "Context is critical in determining appropriateness." +msgstr "" + +#. type: Plain text +#: ../src/en/internals/001-yii-values.md +msgid "This value guides technical decisions as well as community activity. Consideration of how software features help users should guide development. Community-wise, we value any helpful contribution, be it a pull request or an answer in the forum." +msgstr "" + +#. type: Plain text +#: ../src/en/internals/001-yii-values.md +msgid "When the other principles conflict, we choose a solution that's more helpful to the community." +msgstr "" + +#. type: Title ### +#: ../src/en/internals/001-yii-values.md +#, no-wrap +msgid "Be simple" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/001-yii-values.md +msgid "Solutions should be simple and expressive:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/001-yii-values.md +msgid "We use as much complexity as needed and no more." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/001-yii-values.md +msgid "We avoid ugly solutions unless there is no alternative." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/001-yii-values.md +msgid "Fewer rules are better than more rules." +msgstr "" + +#. type: Title ### +#: ../src/en/internals/001-yii-values.md +#, no-wrap +msgid "Be Explicit" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/001-yii-values.md +msgid "We prefer explicit, obvious solutions and code. Solutions should clearly express exactly what they do. For example:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/001-yii-values.md +msgid "A straightforward solution is better than an abstract one unless the abstraction has a practical purpose." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/001-yii-values.md +msgid "Loud fails are better than silent fails or masking errors." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/001-yii-values.md +msgid "Explicit casts are better than PHP type juggling, type hints are good." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/001-yii-values.md +msgid "No magic unless necessary." +msgstr "" + +#. type: Title ### +#: ../src/en/internals/001-yii-values.md +#, no-wrap +msgid "Be consistent" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/001-yii-values.md +msgid "We try to be consistent in:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/001-yii-values.md +msgid "Code style" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/001-yii-values.md +msgid "Naming" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/001-yii-values.md +msgid "Design" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/001-yii-values.md +msgid "Structure" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/001-yii-values.md +msgid "Values and goals" +msgstr "" diff --git a/_translations/po/pt-BR/internals_002-issue-workflow.md.po b/_translations/po/pt-BR/internals_002-issue-workflow.md.po new file mode 100644 index 00000000..5b8fca50 --- /dev/null +++ b/_translations/po/pt-BR/internals_002-issue-workflow.md.po @@ -0,0 +1,95 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-12-24 10:12+0000\n" +"PO-Revision-Date: 2025-12-24 10:12+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/internals/002-issue-workflow.md +#, no-wrap +msgid "002 — Issue workflow" +msgstr "" + +#. type: Plain text +#: ../src/internals/002-issue-workflow.md +msgid "The process of handing incoming issues is the following:" +msgstr "" + +#. type: Plain text +#: ../src/internals/002-issue-workflow.md +msgid "![Issue workflow schema](/images/internals/002-issue-workflow.svg)" +msgstr "" + +#. type: Title ## +#: ../src/internals/002-issue-workflow.md +#, no-wrap +msgid "Roles" +msgstr "" + +#. type: Plain text +#: ../src/internals/002-issue-workflow.md +msgid "We've many roles:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/002-issue-workflow.md +msgid "Process managers - initially triage issues and manage labels." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/002-issue-workflow.md +msgid "Decision makers - participate in discussions moving them to resolutions." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/002-issue-workflow.md +msgid "Bug hunters - verifying bugs." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/002-issue-workflow.md +msgid "Contributors - create code for pull requests." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/002-issue-workflow.md +msgid "Code reviewers - review pull requests." +msgstr "" + +#. type: Plain text +#: ../src/internals/002-issue-workflow.md +msgid "A single person may take one or more roles in the issue-resolving process." +msgstr "" + +#. type: Title ## +#: ../src/internals/002-issue-workflow.md +#, no-wrap +msgid "Labels" +msgstr "" + +#. type: Plain text +#: ../src/internals/002-issue-workflow.md +msgid "We label issues to mark many things: current status, issue type, component affected. Status labels speak for themselves." +msgstr "" + +#. type: Title ## +#: ../src/internals/002-issue-workflow.md +#, no-wrap +msgid "Milestones" +msgstr "" + +#. type: Plain text +#: ../src/internals/002-issue-workflow.md +msgid "Issues aren't assigned to milestones unless they're critical or there is a likely good pull request exists." +msgstr "" diff --git a/_translations/po/pt-BR/internals_003-roadmap.md.po b/_translations/po/pt-BR/internals_003-roadmap.md.po new file mode 100644 index 00000000..309d4855 --- /dev/null +++ b/_translations/po/pt-BR/internals_003-roadmap.md.po @@ -0,0 +1,598 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-01-10 15:51+0000\n" +"PO-Revision-Date: 2026-01-10 15:51+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/index.md ../src/internals/003-roadmap.md +#, no-wrap +msgid "Documentation" +msgstr "Documentação" + +#. type: Title ## +#: ../src/cookbook/sentry-integration.md ../src/internals/003-roadmap.md +#, no-wrap +msgid "Console" +msgstr "" + +#. type: Title # +#: ../src/internals/003-roadmap.md +#, no-wrap +msgid "003 — Roadmap" +msgstr "" + +#. type: Plain text +#: ../src/internals/003-roadmap.md +msgid "We want Yii 3 to:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "Not limit a developer to choosing architecture. Allow anything from \"classic\" MVC to DDD." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "Be based on the best practices such as SOLID, GRASP, etc. and teach them to the community." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "Keep the most good things from Yii 2." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "Be more open to the global PHP community and infrastructure." +msgstr "" + +#. type: Title ## +#: ../src/internals/003-roadmap.md +#, no-wrap +msgid "PSRs compliance" +msgstr "" + +#. type: Plain text +#: ../src/internals/003-roadmap.md +msgid "PSR compliance helps with customizability, the ability to use general PHP libraries and implement fewer wrappers. Here's the list of PSRs we want to implement." +msgstr "" + +#. type: Title ### +#: ../src/internals/003-roadmap.md +#, no-wrap +msgid "PSR-3 Logger" +msgstr "" + +#. type: Plain text +#: ../src/internals/003-roadmap.md +msgid "Implemented as a [separate package that isn't dependent on a framework](https://github.com/yiisoft/log)." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Framework packages should depend on interface only." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Split drivers into packages." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Clean-up code." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] [Fix email target](https://github.com/yiisoft/log-target-email)." +msgstr "" + +#. type: Title ### +#: ../src/internals/003-roadmap.md +#, no-wrap +msgid "PSR-4 Autoloading" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Autoloading is fine already." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Document on how it works." +msgstr "" + +#. type: Title ### +#: ../src/internals/003-roadmap.md +#, no-wrap +msgid "PSR-7 HTTP message" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Remove our own implementation. At least for now." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Framework packages should depend on interfaces only." +msgstr "" + +#. type: Title ### +#: ../src/internals/003-roadmap.md +#, no-wrap +msgid "PSR-11 Container" +msgstr "" + +#. type: Plain text +#: ../src/internals/003-roadmap.md +msgid "Implemented as a [separate package that isn't dependent on a framework](https://github.com/yiisoft/di)." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Framework packages shouldn't use container directly. One should be able to instantiate everything manually." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Finish refactoring." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Remove all framework-specific implementations from the package. Move to a framework." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] [Implement autoloader fallback](https://github.com/yiisoft/di/issues/88)" +msgstr "" + +#. type: Title ### +#: ../src/internals/003-roadmap.md +#, no-wrap +msgid "PSR-12 Code style" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Make sure the code follows it." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Automate fixing style before release." +msgstr "" + +#. type: Title ### +#: ../src/internals/003-roadmap.md +#, no-wrap +msgid "PSR-14 Event dispatcher" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] [Implement as a separate library](https://github.com/yiisoft/event-dispatcher)." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Use in other packages." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Polish." +msgstr "" + +#. type: Title ### +#: ../src/internals/003-roadmap.md +#, no-wrap +msgid "PSR-15 HTTP handlers" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Rewrite HTTP flow to PSR-7 request-response + formatting response via emitter." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Offer SAPI emitter out of the box." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Make it possible to use alternative emitters such as RoadRunner." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Support middleware." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Implement filters as middleware:" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/internals/003-roadmap.md +msgid "[x] [Rate limiting](https://github.com/yiisoft/yii-web/issues/63)" +msgstr "" + +#. type: Bullet: ' - ' +#: ../src/internals/003-roadmap.md +msgid "[x] [Authentication](https://github.com/yiisoft/yii-web/issues/114)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Re-implement router w/ middleware support for route groups." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Filters should be middlewares." +msgstr "" + +#. type: Title ### +#: ../src/internals/003-roadmap.md +#, no-wrap +msgid "PSR-16 Simple cache" +msgstr "" + +#. type: Plain text +#: ../src/internals/003-roadmap.md +msgid "Implemented as a [separate package that isn't dependent on a framework](https://github.com/yiisoft/cache)." +msgstr "" + +#. type: Title ### +#: ../src/internals/003-roadmap.md +#, no-wrap +msgid "PSR-17 HTTP factories" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Use PSR factories." +msgstr "" + +#. type: Title ### +#: ../src/internals/003-roadmap.md +#, no-wrap +msgid "PSR-18 HTTP client" +msgstr "" + +#. type: Title ## +#: ../src/internals/003-roadmap.md +#, no-wrap +msgid "Stricter types" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Make sure type hinting is used everywhere." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Make sure types are as definitive as possible. Avoid varying types if possible." +msgstr "" + +#. type: Title ## +#: ../src/internals/003-roadmap.md +#, no-wrap +msgid "Single application template" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Drop basic/advanced." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Create a [single application template that works out of the box](https://github.com/yiisoft/app)." +msgstr "" + +#. type: Title ## +#: ../src/internals/003-roadmap.md +#, no-wrap +msgid "Router" +msgstr "" + +#. type: Plain text +#: ../src/internals/003-roadmap.md +msgid "Implemented as a [separate package that isn't dependent on a framework](https://github.com/yiisoft/router)." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] DSL for configuration." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Ability to route to any callable." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Named routes." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Route groups w/ middleware support." +msgstr "" + +#. type: Title ## +#: ../src/internals/003-roadmap.md +#, no-wrap +msgid "Best practices and SOLID compliance of all classes/packages" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Make sure interfaces follow the \"interface segregation\" principle." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Don't use public properties." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Don't use `init()`." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Don't inherit from `BaseObject` or `Component`. Remove these." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] No globals." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] No static calls except helpers that are final." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Prefer throwing exceptions to fixing input." +msgstr "" + +#. type: Title ## +#: ../src/internals/003-roadmap.md +#, no-wrap +msgid "Development toolkit" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Release command line tool" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Development command line tool (symlinks packages into usable application)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Separate web and console application" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Possibly eliminate base application (still needed)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Create an interface for the console (using Symfony one)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Implementation may be one of the popular ones (using Symfony one)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Ensure application can add commands via config" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[ ] Follow best practices." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[ ] Don't use the \"MVC\" term." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[ ] Upgrading from Yii 2." +msgstr "" + +#. type: Title ## +#: ../src/internals/003-roadmap.md +#, no-wrap +msgid "RBAC" +msgstr "" + +#. type: Plain text +#: ../src/internals/003-roadmap.md +msgid "RBAC is implemented as [a framework-independent package](https://github.com/yiisoft/rbac)." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Make sure it follows best practices." +msgstr "" + +#. type: Title ## +#: ../src/internals/003-roadmap.md +#, no-wrap +msgid "View" +msgstr "" + +#. type: Plain text +#: ../src/internals/003-roadmap.md +msgid "View is implemented as [framework-independent package](https://github.com/yiisoft/view)." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Finish refactoring ([see issues](https://github.com/yiisoft/view/issues))." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Port widgets." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Rethink and implement active form widgets." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Implement caching widgets." +msgstr "" + +#. type: Title ## +#: ../src/internals/003-roadmap.md +#, no-wrap +msgid "Data abstractions and grid" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Finish [data abstractions](https://github.com/yiisoft/data)." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Port sort, use data abstractions. Should be part of [yii-dataview](https://github.com/yiisoft/yii-dataview)." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Port paging, use data abstractions. Should be part of [yii-dataview](https://github.com/yiisoft/yii-dataview)." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Port grid, use data abstractions. Should be part of [yii-dataview](https://github.com/yiisoft/yii-dataview)." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Port list, use data abstractions. Should be part of [yii-dataview](https://github.com/yiisoft/yii-dataview)." +msgstr "" + +#. type: Title ## +#: ../src/internals/003-roadmap.md +#, no-wrap +msgid "Validators" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Finish [the main package](https://github.com/yiisoft/validator) redesign" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Port necessary validators" +msgstr "" + +#. type: Title ## +#: ../src/internals/003-roadmap.md +#, no-wrap +msgid "Debug toolbar" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Port debug toolbar." +msgstr "" + +#. type: Title ## +#: ../src/internals/003-roadmap.md +#, no-wrap +msgid "Gii" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Port Gii." +msgstr "" + +#. type: Title ## +#: ../src/internals/003-roadmap.md +#, no-wrap +msgid "Infrastructure" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Cover [config](https://github.com/yiisoft/config) with tests." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Release stable [config](https://github.com/yiisoft/config)." +msgstr "" + +#. type: Title ## +#: ../src/internals/003-roadmap.md ../src/internals/022-config-groups.md +#, no-wrap +msgid "Others" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] [Decide on namespaces](https://forum.yiiframework.com/t/lowercase-or-camelcase-namespaces/124983/52)." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] [Clean up error handler](https://github.com/yiisoft/yii2/issues/14348). Make sure the error handler catches fatals and is using response." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] Make validators independent of models to allow reusing them in handlers." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/003-roadmap.md +msgid "[x] [Split IdentityInterface](https://github.com/yiisoft/yii2/issues/13825)." +msgstr "" diff --git a/_translations/po/pt-BR/internals_004-namespaces.md.po b/_translations/po/pt-BR/internals_004-namespaces.md.po new file mode 100644 index 00000000..b53766f2 --- /dev/null +++ b/_translations/po/pt-BR/internals_004-namespaces.md.po @@ -0,0 +1,81 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-12-24 08:02+0000\n" +"PO-Revision-Date: 2025-12-24 08:02+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/en/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md +#: ../src/en/guide/concept/autoloading.md +#: ../src/en/guide/security/best-practices.md +#: ../src/en/guide/structure/domain.md +#: ../src/en/guide/tutorial/console-applications.md +#: ../src/en/internals/004-namespaces.md ../src/en/internals/007-exceptions.md +#: ../src/en/internals/008-interfaces.md +#, no-wrap +msgid "References" +msgstr "" + +#. type: Title # +#: ../src/en/internals/004-namespaces.md +#, no-wrap +msgid "004 — Namespaces" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/004-namespaces.md +msgid "Package namespace rules are the following:" +msgstr "" + +#. type: Bullet: '1. ' +#: ../src/en/internals/004-namespaces.md +msgid "PascalCase is used for namespace parts." +msgstr "" + +#. type: Bullet: '2. ' +#: ../src/en/internals/004-namespaces.md +msgid "Root vendor namespace is `Yiisoft`." +msgstr "" + +#. type: Bullet: '3. ' +#: ../src/en/internals/004-namespaces.md +msgid "Package name parts are used in namespace." +msgstr "" + +#. type: Bullet: '4. ' +#: ../src/en/internals/004-namespaces.md +msgid "Adjective is added to a noun and is a single part." +msgstr "" + +#. type: Plain text +#: ../src/en/internals/004-namespaces.md +msgid "Some examples:" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/004-namespaces.md +#, no-wrap +msgid "" +"| Package | Namespace |\n" +"|----------------------------|---------------------------|\n" +"| yiisoft/yii-web | Yiisoft\\Yii\\Web |\n" +"| yiisoft/di | Yiisoft\\Di |\n" +"| yiisoft/db-mysql | Yiisoft\\Db\\Mysql |\n" +"| yiisoft/friendly-exception | Yiisoft\\FriendlyException |\n" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/004-namespaces.md +msgid "[International forum discussion](https://forum.yiiframework.com/t/use-yiisoft-as-a-root-namespace-instead-of-yii-for-yii-3-packages/125734)" +msgstr "" diff --git a/_translations/po/pt-BR/internals_005-development-tool.md.po b/_translations/po/pt-BR/internals_005-development-tool.md.po new file mode 100644 index 00000000..45eddbd0 --- /dev/null +++ b/_translations/po/pt-BR/internals_005-development-tool.md.po @@ -0,0 +1,83 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-12-24 08:02+0000\n" +"PO-Revision-Date: 2025-12-24 08:02+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/en/internals/005-development-tool.md +#, no-wrap +msgid "005 — Yii development tool" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/005-development-tool.md +msgid "For Yii3, the number of packages increased significantly to achieve more reusability and independent releases. To ease development of the framework itself, we've created a special tool available from [yiisoft/yii-dev-tool](https://github.com/yiisoft/yii-dev-tool)." +msgstr "" + +#. type: Fenced code block +#: ../src/en/internals/005-development-tool.md +#, no-wrap +msgid "" +"$ ./yii-dev\n" +" _ _ _ _\n" +" | | | |(_)(_) Development Tool\n" +" | |_| || || |\n" +" \\__, ||_||_| for Yii 3.0\n" +" |___/\n" +"\n" +"This tool helps with setting up a development environment for Yii 3 packages.\n" +"\n" +"Usage:\n" +" command [options] [arguments]\n" +"\n" +"Options:\n" +" -h, --help Display this help message\n" +"\n" +"Available commands:\n" +" checkout-branch Creates, if not exists, and checkout a git branch\n" +" commit Add and commit changes into each package repository\n" +" install Install packages\n" +" lint Check packages according to PSR12 standard\n" +" pull Pull changes from package repositories\n" +" push Push changes into package repositories\n" +" replicate Copy files specified in replicate.php into each package\n" +" status Show git status of packages\n" +" update Update packages\n" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/005-development-tool.md +msgid "There are many commands available. The most important ones are `install` and `update`. What it does is:" +msgstr "" + +#. type: Bullet: '1. ' +#: ../src/en/internals/005-development-tool.md +msgid "Install/update all packages listed in [`packages.php`](https://github.com/yiisoft/yii-dev-tool/blob/master/packages.php) or individual package from that list if specified." +msgstr "" + +#. type: Bullet: '2. ' +#: ../src/en/internals/005-development-tool.md +msgid "For every package installed check `vendor` directory for packages listed in `packages.php`. If there is any, replace the package directory with a symlink to another package source." +msgstr "" + +#. type: Plain text +#: ../src/en/internals/005-development-tool.md +msgid "As a result, you will have many packages using each other, so there is no need to `git push` and `composer install` / `composer update` during development." +msgstr "" + +#. type: Plain text +#: ../src/en/internals/005-development-tool.md +msgid "A [detailed example](https://github.com/yiisoft/yii-dev-tool#usage-example) of using the tool is available in its README." +msgstr "" diff --git a/_translations/po/pt-BR/internals_006-git-commit-messages.md.po b/_translations/po/pt-BR/internals_006-git-commit-messages.md.po new file mode 100644 index 00000000..44fe0852 --- /dev/null +++ b/_translations/po/pt-BR/internals_006-git-commit-messages.md.po @@ -0,0 +1,75 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-12-24 08:02+0000\n" +"PO-Revision-Date: 2025-12-24 08:02+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/en/guide/runtime/request.md ../src/en/guide/runtime/response.md +#: ../src/en/internals/006-git-commit-messages.md +#, no-wrap +msgid "Body" +msgstr "" + +#. type: Title # +#: ../src/en/internals/006-git-commit-messages.md +#, no-wrap +msgid "006 — Git commit messages" +msgstr "" + +#. type: Title ## +#: ../src/en/internals/006-git-commit-messages.md +#, no-wrap +msgid "Subject line" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/006-git-commit-messages.md +msgid "Use `#123` to reference issue by number" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/006-git-commit-messages.md +msgid "Use imperative mood that's `Fix`, not `Fixed`" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/006-git-commit-messages.md +msgid "Don't add a period at the end" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/006-git-commit-messages.md +msgid "Use `[skip ci]` if there is no need to run unit tests" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/006-git-commit-messages.md +msgid "Start with a capital letter" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/006-git-commit-messages.md +msgid "Limit to 50 characters" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/006-git-commit-messages.md +msgid "Use the message body **if** you need an extra explanation. Explain why, not how." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/006-git-commit-messages.md +msgid "Limit line length to 72 characters" +msgstr "" diff --git a/_translations/po/pt-BR/internals_007-exceptions.md.po b/_translations/po/pt-BR/internals_007-exceptions.md.po new file mode 100644 index 00000000..2fdf70c1 --- /dev/null +++ b/_translations/po/pt-BR/internals_007-exceptions.md.po @@ -0,0 +1,69 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-12-24 08:02+0000\n" +"PO-Revision-Date: 2025-12-24 08:02+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/en/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md +#: ../src/en/guide/concept/autoloading.md +#: ../src/en/guide/security/best-practices.md +#: ../src/en/guide/structure/domain.md +#: ../src/en/guide/tutorial/console-applications.md +#: ../src/en/internals/004-namespaces.md ../src/en/internals/007-exceptions.md +#: ../src/en/internals/008-interfaces.md +#, no-wrap +msgid "References" +msgstr "" + +#. type: Title # +#: ../src/en/internals/007-exceptions.md +#, no-wrap +msgid "007 — Exceptions" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/007-exceptions.md +msgid "Throw exceptions instead of returning an error code." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/007-exceptions.md +msgid "Exception class name must be suffixed with `Exception`." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/007-exceptions.md +msgid "Use grammatically correct error messages including ending punctuation, that's most exceptions must end with a period." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/007-exceptions.md +msgid "`\\InvalidArgumentException` must be used directly. There should be no exceptions inherited from it." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/007-exceptions.md +msgid "`\\InvalidArgumentException` must never be caught." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/007-exceptions.md +msgid "[International community discussion and poll](https://forum.yiiframework.com/t/naming-exceptions/126613/6)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/007-exceptions.md +msgid "[Russian community discussion and poll](https://yiiframework.ru/forum/viewtopic.php?f=39&t=51290)" +msgstr "" diff --git a/_translations/po/pt-BR/internals_008-interfaces.md.po b/_translations/po/pt-BR/internals_008-interfaces.md.po new file mode 100644 index 00000000..57afaa12 --- /dev/null +++ b/_translations/po/pt-BR/internals_008-interfaces.md.po @@ -0,0 +1,49 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-12-24 08:02+0000\n" +"PO-Revision-Date: 2025-12-24 08:02+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/en/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md +#: ../src/en/guide/concept/autoloading.md +#: ../src/en/guide/security/best-practices.md +#: ../src/en/guide/structure/domain.md +#: ../src/en/guide/tutorial/console-applications.md +#: ../src/en/internals/004-namespaces.md ../src/en/internals/007-exceptions.md +#: ../src/en/internals/008-interfaces.md +#, no-wrap +msgid "References" +msgstr "" + +#. type: Title # +#: ../src/en/internals/008-interfaces.md +#, no-wrap +msgid "008 — Interfaces" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/008-interfaces.md +msgid "Interface name should be suffixed with `Interface`." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/008-interfaces.md +msgid "[International community discussion and poll](https://forum.yiiframework.com/t/naming-interfaces/126612/5)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/008-interfaces.md +msgid "[Russian community discussion and poll](https://yiiframework.ru/forum/viewtopic.php?f=39&t=51289)" +msgstr "" diff --git a/_translations/po/pt-BR/internals_009-design-decisions.md.po b/_translations/po/pt-BR/internals_009-design-decisions.md.po new file mode 100644 index 00000000..1e9b7fda --- /dev/null +++ b/_translations/po/pt-BR/internals_009-design-decisions.md.po @@ -0,0 +1,195 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-12-24 08:02+0000\n" +"PO-Revision-Date: 2025-12-24 08:02+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/en/internals/009-design-decisions.md +#, no-wrap +msgid "009 — Design Decisions" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/009-design-decisions.md +msgid "In this document, we list important design decisions taken during Yii3 development." +msgstr "" + +#. type: Title ## +#: ../src/en/internals/009-design-decisions.md +#, no-wrap +msgid "Remove magic properties" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/009-design-decisions.md +msgid "Magic properties in Yii 2 were an interesting idea that allowed a developer to start with public property and then seamlessly migrate to using getter/setter called via magic methods without changing the code." +msgstr "" + +#. type: Plain text +#: ../src/en/internals/009-design-decisions.md +msgid "The main reason for removal in Yii 3 is that it resulted in using public properties everywhere, thus lack of encapsulation and code fragility." +msgstr "" + +#. type: Title ## +#: ../src/en/internals/009-design-decisions.md +#, no-wrap +msgid "Remove the service locator" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/009-design-decisions.md +msgid "Service locator both Yii 1 and Yii 2 was convenient but was also abused a lot. Although a dependency injection container was available in Yii 2, service locator was generally preferred to cause both a dependency on the service locator itself, high coupling, hard to test code." +msgstr "" + +#. type: Plain text +#: ../src/en/internals/009-design-decisions.md +msgid "Yii 3 relies on dependency injection only lowering coupling significantly and making code way more testable." +msgstr "" + +#. type: Title ## +#: ../src/en/internals/009-design-decisions.md +#, no-wrap +msgid "Extract general packages" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/009-design-decisions.md +msgid "Yii 1 and Yii 2 were fully closed communities. All the code we had wasn't useful outside Yii, and most of the \"external\" code wasn't useful in Yii without wrappers. It was noted many times by communities external to Yii that many parts of Yii are well-designed and unique, and they'd use these if these were available as standalone packages." +msgstr "" + +#. type: Plain text +#: ../src/en/internals/009-design-decisions.md +msgid "As part of Yii 3 packages such as cache, RBAC, view, etc. were extracted into framework-independent packages. Benefits are:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/009-design-decisions.md +msgid "Increased usage and contribution" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/009-design-decisions.md +msgid "Yii team could delegate maintenance" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/009-design-decisions.md +msgid "Independent releases are possible" +msgstr "" + +#. type: Title ## +#: ../src/en/internals/009-design-decisions.md +#, no-wrap +msgid "Adopt PSRs" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/009-design-decisions.md +msgid "The team adopted some PSRs in Yii 2, such as PSR-4 and PSR-2. Interfaces in general weren't, although Yii is part of PHP-FIG. Mainly because when Yii 2 was released, these were either in the making or not adopted enough." +msgstr "" + +#. type: Plain text +#: ../src/en/internals/009-design-decisions.md +msgid "Yii3 benefits from PSRs since there are nowadays many ready-to-use libraries that one can get via Composer: cache backends, middleware, loggers, DI containers, etc." +msgstr "" + +#. type: Plain text +#: ../src/en/internals/009-design-decisions.md +msgid "By implementing PSRs in general packages, we allow these to be used in more projects, thus raising the contribution level." +msgstr "" + +#. type: Title ## +#: ../src/en/internals/009-design-decisions.md +#, no-wrap +msgid "Improve DI container" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/009-design-decisions.md +msgid "The problem with the Yii 2 container was that it's tailored to be used with Yii 2 components. API isn't well-designed to be used with general PHP classes." +msgstr "" + +#. type: Plain text +#: ../src/en/internals/009-design-decisions.md +msgid "In Yii3, we ensured that container can be used to conveniently configure any PHP class." +msgstr "" + +#. type: Plain text +#: ../src/en/internals/009-design-decisions.md +msgid "That should result in the absence of Yii-specific wrapper packages and more direct usages of Composer packages." +msgstr "" + +#. type: Title ## +#: ../src/en/internals/009-design-decisions.md +#, no-wrap +msgid "Adopt strict types" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/009-design-decisions.md +msgid "Strict types were introduced because:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/009-design-decisions.md +msgid "PHP 7 is now mainstream" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/009-design-decisions.md +msgid "While they solve no significant Yii 2 problems, they help to avoid many day-to-day development issues" +msgstr "" + +#. type: Title ## +#: ../src/en/internals/009-design-decisions.md +#, no-wrap +msgid "Adopt SemVer" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/009-design-decisions.md +msgid "Yii 2 has its own version policy. Problems:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/009-design-decisions.md +msgid "It wasn't standard" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/009-design-decisions.md +msgid "Composer relies on SemVer" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/009-design-decisions.md +msgid "It's hard to support a framework built on top of packages if the versioning policy isn't strict" +msgstr "" + +#. type: Title ## +#: ../src/en/internals/009-design-decisions.md +#, no-wrap +msgid "Prevent validators mutating data" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/009-design-decisions.md +msgid "In Yii 1 and Yii 2, validators such as \"date\" were mutating data. It was confusing for a validation process not initially meant to mutate data it validates." +msgstr "" + +#. type: Plain text +#: ../src/en/internals/009-design-decisions.md +msgid "[See related discussion](https://forum.yiiframework.com/t/saving-or-killing-non-validation-in-validators/126086)." +msgstr "" diff --git a/_translations/po/pt-BR/internals_010-code-style.md.po b/_translations/po/pt-BR/internals_010-code-style.md.po new file mode 100644 index 00000000..e9421fe1 --- /dev/null +++ b/_translations/po/pt-BR/internals_010-code-style.md.po @@ -0,0 +1,473 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-09-25 14:35+0000\n" +"PO-Revision-Date: 2026-09-25 14:35+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/guide/databases/db-migrations.md ../src/internals/010-code-style.md +#, no-wrap +msgid "Strings" +msgstr "" + +#. type: Title # +#: ../src/internals/010-code-style.md +#, no-wrap +msgid "010 — Code style" +msgstr "" + +#. type: Plain text +#: ../src/internals/010-code-style.md +msgid "Code formatting used in Yii 3 packages is based on [PER Coding Style 3.0](https://www.php-fig.org/per/coding-style/) with extra rules added on top of it." +msgstr "" + +#. type: Title ### +#: ../src/internals/010-code-style.md ../src/internals/017-tags.md +#: ../src/internals/018-widgets.md +#, no-wrap +msgid "Names" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/010-code-style.md +msgid "Use English only." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/010-code-style.md +msgid "Use camelCase notation, including abbreviations (e.g., `enableIdn`)." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/010-code-style.md +msgid "Use the shortest possible, but an explanatory name." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/010-code-style.md +msgid "Never trim or abbreviate a name." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/010-code-style.md +msgid "Postfix classes, interfaces, traits and variables, which is a [collection](https://en.wikipedia.org/wiki/Collection_(abstract_data_type)), with `Collection`." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/010-code-style.md +msgid "Postfix middleware classes with `Middleware`." +msgstr "" + +#. type: Title ## +#: ../src/internals/010-code-style.md +#, no-wrap +msgid "Types" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/010-code-style.md +msgid "Declare [argument and return types](https://www.php.net/manual/en/migration70.new-features.php) where possible." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/010-code-style.md +msgid "[Use types for properties](https://wiki.php.net/rfc/typed_properties_v2)." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/010-code-style.md +msgid "Use strict typing. Avoid mixed and union types where possible except compatible types such as `string|Stringable`." +msgstr "" + +#. type: Title ## +#: ../src/internals/010-code-style.md +#, no-wrap +msgid "Comments" +msgstr "" + +#. type: Plain text +#: ../src/internals/010-code-style.md +msgid "Inline comments are to be avoided unless code couldn't be understood without them. A good example is a workaround for a bug in a certain PHP version." +msgstr "" + +#. type: Plain text +#: ../src/internals/010-code-style.md +msgid "Method comment is necessary except it adds nothing to what method name and signature already has." +msgstr "" + +#. type: Plain text +#: ../src/internals/010-code-style.md +msgid "Class comment should describe the purpose of the class." +msgstr "" + +#. type: Plain text +#: ../src/internals/010-code-style.md +msgid "See [PHPDoc](014-docs.md#phpdoc)." +msgstr "" + +#. type: Title ## +#: ../src/internals/010-code-style.md +#, no-wrap +msgid "Formatting" +msgstr "" + +#. type: Title ### +#: ../src/internals/010-code-style.md +#, no-wrap +msgid "Line length" +msgstr "" + +#. type: Plain text +#: ../src/internals/010-code-style.md +msgid "The maximum line length is 120 characters." +msgstr "" + +#. type: Plain text +#: ../src/internals/010-code-style.md +msgid "When a function or method call exceeds the limit, split arguments into separate lines:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/internals/010-code-style.md +#, no-wrap +msgid "" +"$this->assertSame(\n" +" ['' => ['Value must be no less than 5.']],\n" +" $result->getErrorMessagesIndexedByPath(),\n" +");\n" +msgstr "" + +#. type: Title ### +#: ../src/internals/010-code-style.md +#, no-wrap +msgid "No alignment" +msgstr "" + +#. type: Plain text +#: ../src/internals/010-code-style.md +msgid "Property, variable and constant value assignments shouldn't be aligned. The same applies to phpdoc tags. The reason is that aligned statements often cause larger diff and even conflicts." +msgstr "" + +#. type: Fenced code block (php) +#: ../src/internals/010-code-style.md +#, no-wrap +msgid "" +"final class X\n" +"{\n" +" const A = 'test';\n" +" const BBB = 'test';\n" +" \n" +" private int $property = 42;\n" +" private int $test = 123;\n" +" \n" +" /**\n" +" * @param int $number Just a number.\n" +" * @param array $options Well... options!\n" +" */\n" +" public function doIt(int $number, array $options): void\n" +" {\n" +" $test = 123;\n" +" $anotherTest = 123;\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ### +#: ../src/internals/010-code-style.md +#, no-wrap +msgid "Chain calls" +msgstr "" + +#. type: Plain text +#: ../src/internals/010-code-style.md +msgid "Chained calls should be formatted for better readability. If it's a long chain that doesn't fit the line length of 120 characters, then each call should on a new line:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/internals/010-code-style.md +#, no-wrap +msgid "" +"$object\n" +" ->withName('test')\n" +" ->withValue(87)\n" +" ->withStatus(Status::NEW)\n" +" ->withAuthor($author)\n" +" ->withDeadline($deadline);\n" +msgstr "" + +#. type: Plain text +#: ../src/internals/010-code-style.md +msgid "If it's a short chain, it's alright for it to be on a single line:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/internals/010-code-style.md +#, no-wrap +msgid "$object = $object->withName('test');\n" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/010-code-style.md +msgid "When no variables involved, use `'Hello!'`" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/010-code-style.md +msgid "To get variables into string prefer `\"Hello, $username!\"`" +msgstr "" + +#. type: Title ## +#: ../src/internals/010-code-style.md +#, no-wrap +msgid "Classes and interfaces" +msgstr "" + +#. type: Title ### +#: ../src/internals/010-code-style.md +#, no-wrap +msgid "Final by default" +msgstr "" + +#. type: Plain text +#: ../src/internals/010-code-style.md +msgid "Classes should be `final` by default." +msgstr "" + +#. type: Title ### +#: ../src/internals/010-code-style.md +#, no-wrap +msgid "Private by default" +msgstr "" + +#. type: Plain text +#: ../src/internals/010-code-style.md +msgid "Constants, properties and methods should be private by default." +msgstr "" + +#. type: Title ### +#: ../src/internals/010-code-style.md +#, no-wrap +msgid "Composition over inheritance" +msgstr "" + +#. type: Plain text +#: ../src/internals/010-code-style.md +msgid "Prefer [composition to inheritance](../guide/concept/di-container.md)." +msgstr "" + +#. type: Title ### +#: ../src/internals/010-code-style.md +#, no-wrap +msgid "Property, constant and method order" +msgstr "" + +#. type: Plain text +#: ../src/internals/010-code-style.md +msgid "Order should be the following:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/010-code-style.md +msgid "Constants" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/010-code-style.md +msgid "Properties" +msgstr "" + +#. type: Title ## +#: ../src/internals/010-code-style.md ../src/internals/017-tags.md +#: ../src/internals/018-widgets.md +#, no-wrap +msgid "Methods" +msgstr "" + +#. type: Plain text +#: ../src/internals/010-code-style.md +msgid "Within each category, items should be sorted by visibility:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/010-code-style.md +msgid "public" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/010-code-style.md +msgid "protected" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/010-code-style.md +msgid "private" +msgstr "" + +#. type: Title ### +#: ../src/internals/010-code-style.md +#, no-wrap +msgid "Abstract classes" +msgstr "" + +#. type: Plain text +#: ../src/internals/010-code-style.md +msgid "Abstract classes *shouldn't* be prefixed or postfixed with `Abstract`." +msgstr "" + +#. type: Title #### +#: ../src/internals/010-code-style.md +#, no-wrap +msgid "Immutable methods" +msgstr "" + +#. type: Plain text +#: ../src/internals/010-code-style.md +msgid "Immutable method convention is the following:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/internals/010-code-style.md +#, no-wrap +msgid "" +"public function withName(string $name): self\n" +"{\n" +" $new = clone $this;\n" +" $new->name = $name;\n" +" return $new; \n" +"}\n" +msgstr "" + +#. type: Bullet: '1. ' +#: ../src/internals/010-code-style.md +msgid "Cloned object name is `$new`." +msgstr "" + +#. type: Bullet: '2. ' +#: ../src/internals/010-code-style.md +msgid "Return type is `self`." +msgstr "" + +#. type: Title #### +#: ../src/internals/010-code-style.md +#, no-wrap +msgid "Boolean check methods" +msgstr "" + +#. type: Plain text +#: ../src/internals/010-code-style.md +msgid "Methods that are there to check if something is true should be named like the following:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/internals/010-code-style.md +#, no-wrap +msgid "" +"public function isDeleted(): bool;\n" +"public function hasName(): bool;\n" +"public function canDoIt(): bool;\n" +msgstr "" + +#. type: Title #### +#: ../src/internals/010-code-style.md +#, no-wrap +msgid "Flags in methods " +msgstr "" + +#. type: Plain text +#: ../src/internals/010-code-style.md +msgid "Boolean flags in methods are better to be avoided. It's a sign the method may be doing too much, and there should be two methods instead of one." +msgstr "" + +#. type: Fenced code block (php) +#: ../src/internals/010-code-style.md +#, no-wrap +msgid "public function login(bool $refreshPage = true): void;\n" +msgstr "" + +#. type: Plain text +#: ../src/internals/010-code-style.md +msgid "It is better to be two methods:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/internals/010-code-style.md +#, no-wrap +msgid "" +"public function login(): void;\n" +"public function refreshPage(): void;\n" +msgstr "" + +#. type: Title ## +#: ../src/internals/010-code-style.md +#, no-wrap +msgid "Variables" +msgstr "" + +#. type: Plain text +#: ../src/internals/010-code-style.md +msgid "Add an underscore (`_`) prefix for unused variables. For example:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/internals/010-code-style.md +#, no-wrap +msgid "" +"foreach ($items as $key => $_value) {\n" +" echo $key;\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../src/internals/010-code-style.md +#, no-wrap +msgid "Imports" +msgstr "" + +#. type: Plain text +#: ../src/internals/010-code-style.md +msgid "Prefer importing classes and functions to using fully qualified names:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/internals/010-code-style.md +#, no-wrap +msgid "" +"use Yiisoft\\Arrays\\ArrayHelper;\n" +"use Yiisoft\\Validator\\DataSetInterface;\n" +"use Yiisoft\\Validator\\HasValidationErrorMessage;\n" +"use Yiisoft\\Validator\\Result;\n" +"\n" +"use function is_iterable;\n" +msgstr "" + +#. type: Title ## +#: ../src/internals/010-code-style.md +#, no-wrap +msgid "Additional conventions" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/010-code-style.md +msgid "[Namespaces](004-namespaces.md)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/010-code-style.md +msgid "[Exceptions](007-exceptions.md)" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/010-code-style.md +msgid "[Interfaces](008-interfaces.md)" +msgstr "" diff --git a/_translations/po/pt-BR/internals_011-error-correction.md.po b/_translations/po/pt-BR/internals_011-error-correction.md.po new file mode 100644 index 00000000..a6e07f4c --- /dev/null +++ b/_translations/po/pt-BR/internals_011-error-correction.md.po @@ -0,0 +1,27 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-12-24 08:02+0000\n" +"PO-Revision-Date: 2025-12-24 08:02+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/en/internals/011-error-correction.md +#, no-wrap +msgid "011 — Error correction" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/011-error-correction.md +msgid "If it's unambiguous within a class what the developer who incorrectly used the class meant, it's OK to correct the error. Otherwise, the error MUST NOT be corrected." +msgstr "" diff --git a/_translations/po/pt-BR/internals_012-tests.md.po b/_translations/po/pt-BR/internals_012-tests.md.po new file mode 100644 index 00000000..aa05b977 --- /dev/null +++ b/_translations/po/pt-BR/internals_012-tests.md.po @@ -0,0 +1,72 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-12-24 08:02+0000\n" +"PO-Revision-Date: 2025-12-24 08:02+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/en/internals/012-tests.md +#, no-wrap +msgid "012 — Tests" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/012-tests.md +msgid "For each package, we're adding unit-tests that are run via [PHPUnit](https://phpunit.de/). When designing tests, the following guidelines should be taken into account." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/012-tests.md +msgid "Test class should be marked as `final` by default." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/012-tests.md +msgid "`@test` annotation must not be used, prefix methods with `test`." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/012-tests.md +msgid "The test method name must reflect the purpose of the test." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/012-tests.md +msgid "\"should\" must not be used in the test method name." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/012-tests.md +msgid "If necessary, the test method phpdoc may describe the desired behavior." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/012-tests.md +msgid "The test must follow AAA: first arrange the necessary preconditions, then act, then assert expected results." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/012-tests.md +msgid "There must be one test case per test method that's a single AAA." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/012-tests.md +msgid "Test must use public API. Private properties or methods shouldn't be accessed, assumptions on internals of the class tested shouldn't be made." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/012-tests.md +msgid "Tests shouldn't rely on composer-config-plugin and DI container unless necessary." +msgstr "" diff --git a/_translations/po/pt-BR/internals_013-code-review.md.po b/_translations/po/pt-BR/internals_013-code-review.md.po new file mode 100644 index 00000000..933ec618 --- /dev/null +++ b/_translations/po/pt-BR/internals_013-code-review.md.po @@ -0,0 +1,119 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-12-24 08:02+0000\n" +"PO-Revision-Date: 2025-12-24 08:02+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/en/internals/013-code-review.md +#, no-wrap +msgid "013 — Code review" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/013-code-review.md +msgid "Code reviews are essential for the success of the project and are as important as contributing code." +msgstr "" + +#. type: Plain text +#: ../src/en/internals/013-code-review.md +msgid "Reviews are handled via GitHub pull requests. When the request is ready for review, the \"status: code review\" label is added to it." +msgstr "" + +#. type: Plain text +#: ../src/en/internals/013-code-review.md +msgid "[A full list of pull requests that need review](https://github.com/search?q=org%3Ayiisoft+label%3A\"status%3Acode+review\"&state=open&type=Issues) is available at GitHub." +msgstr "" + +#. type: Title ## +#: ../src/en/internals/013-code-review.md +#, no-wrap +msgid "Guidelines" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/013-code-review.md +msgid "Check out the pull request branch, open the project in the IDE, get a big picture." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/013-code-review.md +msgid "Does the pull request make sense overall?" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/013-code-review.md +msgid "Run tests and/or application using code from the pull request. Are these OK?" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/013-code-review.md +msgid "Read all lines of code in the pull request." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/013-code-review.md +msgid "Could it be done simpler?" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/013-code-review.md +msgid "Are there security issues?" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/013-code-review.md +msgid "Are there performance issues?" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/013-code-review.md +msgid "When leaving comments, be polite." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/013-code-review.md +msgid "Avoid code-formatting comments." +msgstr "" + +#. type: Title ## +#: ../src/en/internals/013-code-review.md +#, no-wrap +msgid "Mandatory parts" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/013-code-review.md +msgid "[ ] Tests that fail without code and pass with code." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/013-code-review.md +msgid "[ ] Type hints." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/013-code-review.md +msgid "[ ] `declare(strict_types=1)`." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/013-code-review.md +msgid "[ ] Documentation: phpdoc, yiisoft/docs." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/013-code-review.md +msgid "[ ] Changelog entry (if package is stable)." +msgstr "" diff --git a/_translations/po/pt-BR/internals_014-docs.md.po b/_translations/po/pt-BR/internals_014-docs.md.po new file mode 100644 index 00000000..06ad4e97 --- /dev/null +++ b/_translations/po/pt-BR/internals_014-docs.md.po @@ -0,0 +1,390 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-05-05 22:22+0000\n" +"PO-Revision-Date: 2026-05-05 22:22+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/internals/014-docs.md +#, no-wrap +msgid "014 — Documentation" +msgstr "" + +#. type: Plain text +#: ../src/internals/014-docs.md +msgid "Documentation is one of the most important parts of Yii." +msgstr "" + +#. type: Title ## +#: ../src/internals/014-docs.md +#, no-wrap +msgid "Package documentation" +msgstr "" + +#. type: Plain text +#: ../src/internals/014-docs.md +msgid "Documentation for a package could either be in `README.md` or `docs/{language}/{type}` where `{language}` is a language code and `{type}` could be \"guide,\" \"cookbook\" or something else. Usually `docs` is there if the package usage or configuration isn't trivial or there's a need for translation." +msgstr "" + +#. type: Plain text +#: ../src/internals/014-docs.md +msgid "Some indicators that it's time to create `docs`:" +msgstr "" + +#. type: Bullet: '1. ' +#: ../src/internals/014-docs.md +msgid "There is a need for translation." +msgstr "" + +#. type: Bullet: '2. ' +#: ../src/internals/014-docs.md +msgid "Many topics exist. Each of these is big by itself." +msgstr "" + +#. type: Plain text +#: ../src/internals/014-docs.md +msgid "If the total length of readme is less than about 200 lines, it's fine to keep documentation in the readme." +msgstr "" + +#. type: Title ## +#: ../src/internals/014-docs.md +#, no-wrap +msgid "Definitive guide" +msgstr "" + +#. type: Plain text +#: ../src/internals/014-docs.md +msgid "The definitive guide, [yiisoft/docs/guide](https://github.com/yiisoft/docs/tree/master/guide/en) aims at covering usage of packages as a whole framework. Unlike package documentation, it isn't focused on a single package but is covering certain use-cases." +msgstr "" + +#. type: Plain text +#: ../src/internals/014-docs.md +msgid "The guide should follow [Microsoft style guide](https://learn.microsoft.com/en-us/style-guide/welcome/)." +msgstr "" + +#. type: Title ### +#: ../src/internals/014-docs.md +#, no-wrap +msgid "Translation" +msgstr "" + +#. type: Plain text +#: ../src/internals/014-docs.md +#, no-wrap +msgid "The definitive guide uses [po4a](https://github.com/mquinson/po4a) in GitHub Action for translations. \n" +msgstr "" + +#. type: Plain text +#: ../src/internals/014-docs.md +msgid "Translation algorithm:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/014-docs.md +msgid "Install an application for working with `.po` translation files. For example, [Poedit](https://poedit.net/), [Lokalize](https://apps.kde.org/ru/lokalize/), [Gtranslator](https://wiki.gnome.org/Apps/Gtranslator) or another." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/014-docs.md +msgid "Find file what you want to translate in `_translations/guide/{lang}`. Note that if the source file is in a subfolder, the subfolder name is appended to the file name and separated by an underscore, for example, for translating `guide/en/concept/aliases.md` file find `_translations/guide/{lang}/concept_aliases.md.po` file." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/014-docs.md +msgid "Open the file with the `.po` extension in `Poedit` from the folder with the desired localization, for example `_translations/guide/ru/intro_what-is-yii.md.po`. If there is no localization yet, create an issue." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/014-docs.md +msgid "Translate necessary strings and push the changes" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/014-docs.md +msgid "Open a pull request to the main repository" +msgstr "" + +#. type: Plain text +#: ../src/internals/014-docs.md +#, no-wrap +msgid "" +"> [!CAUTION]\n" +"> Do not change the translation in files in `/guide/{lang}` manually.\n" +msgstr "" + +#. type: Plain text +#: ../src/internals/014-docs.md +msgid "If you have changed English and want to update translations:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/014-docs.md +msgid "Pull updated branch after successful completion of workflow `Update docs translation` in GitHub Action" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/014-docs.md +msgid "Update translation in `.po` files by `Poedit`" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/014-docs.md +msgid "Push changes" +msgstr "" + +#. type: Title ## +#: ../src/internals/014-docs.md +#, no-wrap +msgid "Blocks" +msgstr "" + +#. type: Plain text +#: ../src/internals/014-docs.md +msgid "Blocks are in the [GitHub Alerts format](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts):" +msgstr "" + +#. type: Fenced code block +#: ../src/internals/014-docs.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> Useful information that users should know, even when skimming content.\n" +"\n" +"> [!TIP]\n" +"> Helpful advice for doing things better or more easily.\n" +"\n" +"> [!IMPORTANT]\n" +"> Key information users need to know to achieve their goal.\n" +"\n" +"> [!WARNING]\n" +"> Urgent info that needs immediate user attention to avoid problems.\n" +"\n" +"> [!CAUTION]\n" +"> Advises about risks or negative outcomes of certain actions.\n" +msgstr "" + +#. type: Plain text +#: ../src/internals/014-docs.md +msgid "When translating documentation, these Block indicators should not be translated. Keeps them intact as they are and only translate the block content. For translating the label for the block, each guide translation should have a `blocktypes.json` file containing the translations. The following shows an example for German:" +msgstr "" + +#. type: Fenced code block (json) +#: ../src/internals/014-docs.md +#, no-wrap +msgid "" +"{\n" +" \"Note\": \"Hinweis\",\n" +" \"Tip\": \"Tipp\",\n" +" \"Important\": \"Wichtig\",\n" +" \"Warning\": \"Achtung\",\n" +" \"Caution\": \"Vorsicht\"\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../src/internals/014-docs.md +#, no-wrap +msgid "PHPDoc" +msgstr "" + +#. type: Plain text +#: ../src/internals/014-docs.md +msgid "PHPDoc mustn't be added if it doesn't add anything to what it describes. The following is a bad example:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/internals/014-docs.md +#, no-wrap +msgid "" +"use Psr\\Log\\LoggerInterface;\n" +"\n" +"/**\n" +" * MyService class\n" +" */\n" +"final class MyService extends MyServiceBase\n" +"{\n" +" /**\n" +" * @var LoggerInterface logger \n" +" */\n" +" private LoggerInterface $logger;\n" +"\n" +" /**\n" +" * MyService constructor.\n" +" * @param LoggerInterface $logger\n" +" */\n" +" public function __construct(LoggerInterface $logger)\n" +" {\n" +" $this->logger = $logger;\n" +" }\n" +"\n" +" /**\n" +" * @inheritDoc\n" +" */\n" +" public function doit(): bool\n" +" {\n" +" return parent::doit(); \n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/internals/014-docs.md +msgid "PHPDoc, if present, should describe the purpose of the element it's added for." +msgstr "" + +#. type: Plain text +#: ../src/internals/014-docs.md +msgid "Skip default values in PHPDoc when PHP already shows them in a parameter default, promoted property default, or property initializer. The declaration is the source of truth, and repeating the value in text can become outdated after code changes." +msgstr "" + +#. type: Plain text +#: ../src/internals/014-docs.md +msgid "Example of incorrect code:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/internals/014-docs.md +#, no-wrap +msgid "" +"/**\n" +" * @param bool $skipOnEmpty Whether to skip validation when the value is empty. Defaults to true.\n" +" */\n" +"public function __construct(\n" +" private bool $skipOnEmpty = true,\n" +") {\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/internals/014-docs.md +msgid "Example of a valid code:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/internals/014-docs.md +#, no-wrap +msgid "" +"/**\n" +" * @param bool $skipOnEmpty Whether to skip validation when the value is empty.\n" +" */\n" +"public function __construct(\n" +" private bool $skipOnEmpty = true,\n" +") {\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../src/internals/014-docs.md +msgid "The `@see` tags must explicitly refer to class methods, properties, and constants. This is necessary for the correct display of links in IDEs, as well as for the correct display of links in API documentation." +msgstr "" + +#. type: Fenced code block (php) +#: ../src/internals/014-docs.md +#, no-wrap +msgid "" +"/**\n" +" * @see SOME_CONST\n" +" * @see $prop\n" +" * @see doSomething()\n" +" */\n" +"final class Example\n" +"{\n" +" public const SOME_CONST = '';\n" +" public int $prop;\n" +" public function doSomething(): void {}\n" +"}\n" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/internals/014-docs.md +#, no-wrap +msgid "" +"/**\n" +" * @see Example::SOME_CONST\n" +" * @see Example::$prop\n" +" * @see Example::doSomething()\n" +" */\n" +"final class Example\n" +"{\n" +" public const SOME_CONST = '';\n" +" public int $prop;\n" +" public function doSomething(): void {}\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../src/internals/014-docs.md +#, no-wrap +msgid "Readme checklist" +msgstr "" + +#. type: Plain text +#: ../src/internals/014-docs.md +msgid "Each package readme should be placed into `README.md` and contain the following:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/014-docs.md +msgid "[ ] Logo." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/014-docs.md +msgid "[ ] Short description of the package. What does it do?" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/014-docs.md +msgid "[ ] Quality badges (build, code coverage)." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/014-docs.md +msgid "[ ] Screenshot (if applicable)." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/014-docs.md +msgid "[ ] Requirements." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/014-docs.md +msgid "[ ] Installation. Usually `composer require`." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/014-docs.md +msgid "[ ] Getting started. One or two common usage examples are demonstrated." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/014-docs.md +msgid "[ ] Configuration." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/014-docs.md +msgid "[ ] Contributing. It should contain a link to guidelines." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/014-docs.md +msgid "[ ] Running tests." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/014-docs.md +msgid "[ ] License." +msgstr "" diff --git a/_translations/po/pt-BR/internals_015-phpstorm.md.po b/_translations/po/pt-BR/internals_015-phpstorm.md.po new file mode 100644 index 00000000..0f78a531 --- /dev/null +++ b/_translations/po/pt-BR/internals_015-phpstorm.md.po @@ -0,0 +1,134 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-12-24 08:02+0000\n" +"PO-Revision-Date: 2025-12-24 08:02+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/en/internals/015-phpstorm.md +#, no-wrap +msgid "015 — PhpStorm metadata and attributes" +msgstr "" + +#. type: Title ## +#: ../src/en/internals/015-phpstorm.md +#, no-wrap +msgid "PhpStorm metadata" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/015-phpstorm.md +msgid "[PhpStorm metadata](https://www.jetbrains.com/help/phpstorm/ide-advanced-metadata.html) helps the IDE to understand code better in cases when regular types and PHPDoc tags don't help." +msgstr "" + +#. type: Plain text +#: ../src/en/internals/015-phpstorm.md +msgid "We use the following set of coding styles for metadata." +msgstr "" + +#. type: Title ### +#: ../src/en/internals/015-phpstorm.md +#, no-wrap +msgid "Metadata location" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/015-phpstorm.md +msgid "Metadata should be placed in `/.phpstorm.meta.php` directory." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/015-phpstorm.md +msgid "Configuration should be split into files. Each file should be named after a class it configures." +msgstr "" + +#. type: Plain text +#: ../src/en/internals/015-phpstorm.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> There is no support for subdirectories in PhpStorm yet.\n" +msgstr "" + +#. type: Title ### +#: ../src/en/internals/015-phpstorm.md +#, no-wrap +msgid "Constants " +msgstr "" + +#. type: Plain text +#: ../src/en/internals/015-phpstorm.md +msgid "All constant dictionaries should be named as `{Class FQN}::{Group name}`. Group name should be short and written in capital letters. Use underscore as a word separator that's `\\Yiisoft\\Http\\Status::STATUSES`. For example:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/en/internals/015-phpstorm.md +#, no-wrap +msgid "" +"expectedReturnValues(\n" +" \\Psr\\Http\\Message\\RequestInterface::getMethod(),\n" +" argumentsSet('\\Yiisoft\\Http\\Method::METHODS'),\n" +");\n" +"\n" +"registerArgumentsSet(\n" +" '\\Yiisoft\\Http\\Method::METHODS',\n" +" \\Yiisoft\\Http\\Method::GET,\n" +" \\Yiisoft\\Http\\Method::POST,\n" +" \\Yiisoft\\Http\\Method::PUT,\n" +" \\Yiisoft\\Http\\Method::DELETE,\n" +" \\Yiisoft\\Http\\Method::PATCH,\n" +" \\Yiisoft\\Http\\Method::HEAD,\n" +" \\Yiisoft\\Http\\Method::OPTIONS,\n" +");\n" +msgstr "" + +#. type: Title ## +#: ../src/en/internals/015-phpstorm.md +#, no-wrap +msgid "PhpStorm attributes" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/015-phpstorm.md +msgid "[PhpStorm attributes](https://github.com/JetBrains/phpstorm-attributes) CAN be used in code, but package `jetbrains/phpstorm-attributes` MUST be added as a dev dependency:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/en/internals/015-phpstorm.md +#, no-wrap +msgid "composer require --dev jetbrains/phpstorm-attributes\n" +msgstr "" + +#. type: Title ### +#: ../src/en/internals/015-phpstorm.md +#, no-wrap +msgid "Using with ComposerRequireChecker" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/015-phpstorm.md +msgid "When [ComposerRequireChecker](https://github.com/maglnet/ComposerRequireChecker) is also used within the same package, add involved attributes' class names to whitelist in config. For example:" +msgstr "" + +#. type: Fenced code block (json) +#: ../src/en/internals/015-phpstorm.md +#, no-wrap +msgid "" +"{\n" +" \"symbol-whitelist\": [\n" +" \"JetBrains\\\\PhpStorm\\\\ExpectedValues\",\n" +" \"JetBrains\\\\PhpStorm\\\\Pure\"\n" +" ]\n" +"}\n" +msgstr "" diff --git a/_translations/po/pt-BR/internals_016-security-workflow.md.po b/_translations/po/pt-BR/internals_016-security-workflow.md.po new file mode 100644 index 00000000..d4e222b2 --- /dev/null +++ b/_translations/po/pt-BR/internals_016-security-workflow.md.po @@ -0,0 +1,159 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-05-09 18:47+0000\n" +"PO-Revision-Date: 2026-05-09 18:47+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/internals/016-security-workflow.md +#, no-wrap +msgid "016 — Security workflow" +msgstr "" + +#. type: Plain text +#: ../src/internals/016-security-workflow.md +msgid "Security issues are typically sent via [a security form](https://www.yiiframework.com/security)." +msgstr "" + +#. type: Plain text +#: ../src/internals/016-security-workflow.md +#, no-wrap +msgid "" +"If an issue is reported directly to a public page such as a repository issue or a forum topic, get the message\n" +"and delete the issue. Say thanks to the reporter and point to the security form for next time. \n" +msgstr "" + +#. type: Fenced code block (mermaid) +#: ../src/internals/016-security-workflow.md +#, no-wrap +msgid "" +"flowchart TD\n" +" form[Security form report] --> verify[Verify issue]\n" +" public[Public report] --> remove[Save details and delete public issue]\n" +" remove --> redirect[Point reporter to the security form]\n" +" redirect --> verify\n" +" verify -->|needs details| requestInfo[Request more information]\n" +" requestInfo --> verify\n" +" verify -->|valid| advisory[Create draft security advisory]\n" +" advisory --> severity[Set CVSS severity]\n" +" severity --> credit[Ask about reporter credit]\n" +" credit --> cve[Request CVE number]\n" +" cve --> patch[Prepare patch pull request]\n" +" patch --> wait[Wait for CVE allocation]\n" +" wait --> release[Release]\n" +" release --> publish[Publish advisory and submit FriendsOfPHP entry]\n" +msgstr "" + +#. type: Title ## +#: ../src/internals/016-security-workflow.md +#, no-wrap +msgid "Verify" +msgstr "" + +#. type: Plain text +#: ../src/internals/016-security-workflow.md +msgid "Verify that the issue is valid. Request more information if needed." +msgstr "" + +#. type: Title ## +#: ../src/internals/016-security-workflow.md +#, no-wrap +msgid "Add security advisory" +msgstr "" + +#. type: Plain text +#: ../src/internals/016-security-workflow.md +msgid "Create a draft GitHub security advisory." +msgstr "" + +#. type: Title ### +#: ../src/internals/016-security-workflow.md +#, no-wrap +msgid "Find out severity" +msgstr "" + +#. type: Bullet: '1. ' +#: ../src/internals/016-security-workflow.md +msgid "Get CVSS score using [NVD calculator](https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator)." +msgstr "" + +#. type: Bullet: '2. ' +#: ../src/internals/016-security-workflow.md +msgid "Choose severity based on the [rating scale](https://www.first.org/cvss/specification-document#Qualitative-Severity-Rating-Scale)." +msgstr "" + +#. type: Title ### +#: ../src/internals/016-security-workflow.md +#, no-wrap +msgid "Give credit to the reporter" +msgstr "" + +#. type: Plain text +#: ../src/internals/016-security-workflow.md +msgid "Ask the reporter if he wants a credit for finding the issue. If so, point to his GitHub account." +msgstr "" + +#. type: Title ## +#: ../src/internals/016-security-workflow.md +#, no-wrap +msgid "Request a CVE number" +msgstr "" + +#. type: Plain text +#: ../src/internals/016-security-workflow.md +msgid "When you're ready, request a CVE." +msgstr "" + +#. type: Title ## +#: ../src/internals/016-security-workflow.md +#, no-wrap +msgid "Prepare a patch" +msgstr "" + +#. type: Plain text +#: ../src/internals/016-security-workflow.md +msgid "Prepare a pull request fixing the issue. GitHub allows doing it in a private fork." +msgstr "" + +#. type: Title ## +#: ../src/internals/016-security-workflow.md +#, no-wrap +msgid "Wait till the CVE number is allocated " +msgstr "" + +#. type: Plain text +#: ../src/internals/016-security-workflow.md +msgid "It usually takes several days." +msgstr "" + +#. type: Title ## +#: ../src/internals/016-security-workflow.md +#, no-wrap +msgid "Release" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/016-security-workflow.md +msgid "Merge the patch pull request right before tagging the next package release." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/016-security-workflow.md +msgid "Publish security advisory." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/016-security-workflow.md +msgid "Add CVE to [FriendsOfPHP/security-advisories](https://github.com/FriendsOfPHP/security-advisories). See [#488](https://github.com/FriendsOfPHP/security-advisories/pull/488) as an example." +msgstr "" diff --git a/_translations/po/pt-BR/internals_017-tags.md.po b/_translations/po/pt-BR/internals_017-tags.md.po new file mode 100644 index 00000000..1077f68b --- /dev/null +++ b/_translations/po/pt-BR/internals_017-tags.md.po @@ -0,0 +1,126 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-12-24 08:02+0000\n" +"PO-Revision-Date: 2025-12-24 08:02+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/en/guide/concept/immutability.md ../src/en/internals/017-tags.md +#: ../src/en/internals/018-widgets.md +#, no-wrap +msgid "Immutability" +msgstr "" + +#. type: Title ### +#: ../src/en/internals/010-code-style.md ../src/en/internals/017-tags.md +#: ../src/en/internals/018-widgets.md +#, no-wrap +msgid "Names" +msgstr "" + +#. type: Title ## +#: ../src/en/internals/010-code-style.md ../src/en/internals/017-tags.md +#: ../src/en/internals/018-widgets.md +#, no-wrap +msgid "Methods" +msgstr "" + +#. type: Title # +#: ../src/en/internals/017-tags.md +#, no-wrap +msgid "017 - Tags" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/017-tags.md +msgid "Unlike regular classes, tags are used in view templates, so syntax is important. It should be both easy to write, easy to read and not too verbose because similar constructs are meant to be used over and over again." +msgstr "" + +#. type: Title ## +#: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md +#, no-wrap +msgid "Class names" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/017-tags.md +msgid "Tags aren't postfixed or prefixed unless it's an abstract base class." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/017-tags.md +msgid "If the tag represents a specification, use a name used in the specification." +msgstr "" + +#. type: Title ## +#: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md +#, no-wrap +msgid "Inheritance" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md +msgid "Inheritance is allowed with some restrictions:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md +msgid "If a class isn't abstract, it should be final." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md +msgid "Hierarchy should be kept as linear as possible." +msgstr "" + +#. type: Plain text +#: ../src/en/internals/017-tags.md +msgid "Tags should:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md +msgid "Have no state." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/017-tags.md +msgid "Be immutable. Every method that modifies a setting returns a clone with the setting changed." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/017-tags.md +msgid "Be free of side effects. Many calls of the same method with the same argument should give the same result." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md +msgid "Unlike other classes, methods that return a clone of the object with some properties modified aren't prefixed." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md +msgid "Keep method names as short as possible but don't hurt readability." +msgstr "" + +#. type: Title ### +#: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md +#, no-wrap +msgid "Boolean flags" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md +msgid "The method that corresponds to the boolean attribute should be named after the attribute and accept a boolean flag argument." +msgstr "" diff --git a/_translations/po/pt-BR/internals_018-widgets.md.po b/_translations/po/pt-BR/internals_018-widgets.md.po new file mode 100644 index 00000000..0c4b6f84 --- /dev/null +++ b/_translations/po/pt-BR/internals_018-widgets.md.po @@ -0,0 +1,116 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-12-24 08:02+0000\n" +"PO-Revision-Date: 2025-12-24 08:02+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/en/guide/concept/immutability.md ../src/en/internals/017-tags.md +#: ../src/en/internals/018-widgets.md +#, no-wrap +msgid "Immutability" +msgstr "" + +#. type: Title ### +#: ../src/en/internals/010-code-style.md ../src/en/internals/017-tags.md +#: ../src/en/internals/018-widgets.md +#, no-wrap +msgid "Names" +msgstr "" + +#. type: Title ## +#: ../src/en/internals/010-code-style.md ../src/en/internals/017-tags.md +#: ../src/en/internals/018-widgets.md +#, no-wrap +msgid "Methods" +msgstr "" + +#. type: Title ## +#: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md +#, no-wrap +msgid "Class names" +msgstr "" + +#. type: Title ## +#: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md +#, no-wrap +msgid "Inheritance" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md +msgid "Inheritance is allowed with some restrictions:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md +msgid "If a class isn't abstract, it should be final." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md +msgid "Hierarchy should be kept as linear as possible." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md +msgid "Have no state." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md +msgid "Unlike other classes, methods that return a clone of the object with some properties modified aren't prefixed." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md +msgid "Keep method names as short as possible but don't hurt readability." +msgstr "" + +#. type: Title ### +#: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md +#, no-wrap +msgid "Boolean flags" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md +msgid "The method that corresponds to the boolean attribute should be named after the attribute and accept a boolean flag argument." +msgstr "" + +#. type: Title # +#: ../src/en/internals/018-widgets.md +#, no-wrap +msgid "018 - Widgets" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/018-widgets.md +msgid "Unlike regular classes, widgets are used in view templates, so syntax is important. It should be both easy to write, easy to read and not too verbose because similar constructs are meant to be used over and over again." +msgstr "" + +#. type: Plain text +#: ../src/en/internals/018-widgets.md +msgid "Widgets aren't postfixed or prefixed." +msgstr "" + +#. type: Plain text +#: ../src/en/internals/018-widgets.md +msgid "Widgets should:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/018-widgets.md +msgid "Be immutable." +msgstr "" diff --git a/_translations/po/pt-BR/internals_019-view-code-style.md.po b/_translations/po/pt-BR/internals_019-view-code-style.md.po new file mode 100644 index 00000000..445c60d6 --- /dev/null +++ b/_translations/po/pt-BR/internals_019-view-code-style.md.po @@ -0,0 +1,101 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-12-24 08:02+0000\n" +"PO-Revision-Date: 2025-12-24 08:02+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/en/internals/019-view-code-style.md +#, no-wrap +msgid "019 — View code style" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/019-view-code-style.md +msgid "The PHP code in the view files shouldn't be complicated. The code must contain the logic responsible for formatting the data, but not the logic for requesting this data." +msgstr "" + +#. type: Title ## +#: ../src/en/internals/019-view-code-style.md +#, no-wrap +msgid "Heading" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/019-view-code-style.md +msgid "View file heading is used to place phpdoc describing variables available and to import classes:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/en/internals/019-view-code-style.md +#, no-wrap +msgid "" +" \n" +"

getTitle()) ?>

\n" +"

getDescription()) ?>

\n" +"\n" +msgstr "" + +#. type: Title ## +#: ../src/en/internals/019-view-code-style.md +#, no-wrap +msgid "Short echo" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/019-view-code-style.md +msgid "Short echo is preferred:" +msgstr "" + +#. type: Fenced code block (php) +#: ../src/en/internals/019-view-code-style.md +#, no-wrap +msgid "\n" +msgstr "" + +#. type: Title ## +#: ../src/en/internals/019-view-code-style.md +#, no-wrap +msgid "Class methods" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/019-view-code-style.md +msgid "All class methods used in view files must be public regardless if the view is rendered by the class itself." +msgstr "" diff --git a/_translations/po/pt-BR/internals_020-package-release.md.po b/_translations/po/pt-BR/internals_020-package-release.md.po new file mode 100644 index 00000000..074224d6 --- /dev/null +++ b/_translations/po/pt-BR/internals_020-package-release.md.po @@ -0,0 +1,157 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-05-29 09:48+0000\n" +"PO-Revision-Date: 2026-05-29 09:48+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/internals/020-package-release.md +#, no-wrap +msgid "020 — Package release" +msgstr "" + +#. type: Title ## +#: ../src/internals/020-package-release.md +#, no-wrap +msgid "Criteria" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/020-package-release.md +msgid "No critical issues." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/020-package-release.md +msgid "Public API changes aren't likely. Some time passed w/o issues reported that may require API changes." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/020-package-release.md +msgid "All dependencies are stable." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/020-package-release.md +msgid "Close to 100% test coverage with, ideally, a 100% MSI score." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/020-package-release.md +msgid "README is alright." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/020-package-release.md +msgid "Everything is type-hinted unless special cases." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/020-package-release.md +msgid "Psalm analysis passes on at least level 2." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/020-package-release.md +msgid "phpdoc is alright." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/020-package-release.md +msgid "Public API is alright." +msgstr "" + +#. type: Title ## +#: ../src/internals/020-package-release.md +#, no-wrap +msgid "Release branch policy" +msgstr "" + +#. type: Plain text +#: ../src/internals/020-package-release.md +msgid "Use `master` for all regular releases." +msgstr "" + +#. type: Plain text +#: ../src/internals/020-package-release.md +msgid "Create a separate branch only when releasing a new version for a previous major version. In this case, create the branch from the latest tag in that previous major version line and apply only the changes needed for the release." +msgstr "" + +#. type: Title ## +#: ../src/internals/020-package-release.md +#, no-wrap +msgid "Release instruction" +msgstr "" + +#. type: Plain text +#: ../src/internals/020-package-release.md +msgid "Release a package via [Yii Development Tool](005-development-tool.md)." +msgstr "" + +#. type: Plain text +#: ../src/internals/020-package-release.md +#, no-wrap +msgid "" +"1. Check that you can sign commits locally (see \n" +"[Signing commits](https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits)).\n" +msgstr "" + +#. type: Bullet: '2. ' +#: ../src/internals/020-package-release.md +msgid "For regular releases, pull last changes from the `master` branch:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/internals/020-package-release.md +#, no-wrap +msgid "" +"./yii-dev git/checkout master package-name\n" +"./yii-dev git/pull package-name\n" +msgstr "" + +#. type: Plain text +#: ../src/internals/020-package-release.md +msgid "For previous major version releases, use the branch created according to the release branch policy instead of `master`." +msgstr "" + +#. type: Bullet: '3. ' +#: ../src/internals/020-package-release.md +msgid "Check the package for compliance with the criteria above." +msgstr "" + +#. type: Bullet: '4. ' +#: ../src/internals/020-package-release.md +msgid "Run `release/make` command:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../src/internals/020-package-release.md +#, no-wrap +msgid "./yii-dev release/make package-name\n" +msgstr "" + +#. type: Bullet: '5. ' +#: ../src/internals/020-package-release.md +msgid "Select the version type (major, minor or patch)." +msgstr "" + +#. type: Bullet: '6. ' +#: ../src/internals/020-package-release.md +msgid "On the question \"Push commits and tags, and release on GitHub?\" check a diff. If the diff is alright, answer \"yes.\"" +msgstr "" + +#. type: Bullet: '7. ' +#: ../src/internals/020-package-release.md +msgid "For major and minor releases, add a record with release notes on [Yii Framework News](https://www.yiiframework.com/news)." +msgstr "" diff --git a/_translations/po/pt-BR/internals_021-changelog-upgrade.md.po b/_translations/po/pt-BR/internals_021-changelog-upgrade.md.po new file mode 100644 index 00000000..76446e13 --- /dev/null +++ b/_translations/po/pt-BR/internals_021-changelog-upgrade.md.po @@ -0,0 +1,130 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-01-08 08:54+0000\n" +"PO-Revision-Date: 2026-01-08 08:54+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/internals/021-changelog-upgrade.md +#, no-wrap +msgid "021 — Changelog and upgrade" +msgstr "" + +#. type: Plain text +#: ../src/internals/021-changelog-upgrade.md +msgid "For all released packages, we've a detailed changelog and upgrade guide." +msgstr "" + +#. type: Title ## +#: ../src/internals/021-changelog-upgrade.md +#, no-wrap +msgid "Changelog" +msgstr "" + +#. type: Plain text +#: ../src/internals/021-changelog-upgrade.md +msgid "Changelog is written for each version released. The file name is `CHANGELOG.md`. The format is the following:" +msgstr "" + +#. type: Fenced code block (markdown) +#: ../src/internals/021-changelog-upgrade.md +#, no-wrap +msgid "" +"# My package Change Log\n" +"\n" +"## 1.0.2 under development\n" +"\n" +"- no changes in this release.\n" +"\n" +"## 1.0.1 March 23, 2021\n" +"\n" +"- Bug #42: Short description of the change (@author1, @author2)\n" +"\n" +"## 1.0.0 February 02, 2021\n" +"\n" +"- Initial release.\n" +msgstr "" + +#. type: Plain text +#: ../src/internals/021-changelog-upgrade.md +msgid "There \"My package\" is the name of the package, `1.0.1` is the version released followed by release date. For each version, there are a number of lines listing the changes. \"Bug\" refers to a change type. The following types are used:" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/021-changelog-upgrade.md +msgid "New — New features." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/021-changelog-upgrade.md +msgid "Chg — General changes." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/021-changelog-upgrade.md +msgid "Enh — Existing feature enhancements." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/internals/021-changelog-upgrade.md +msgid "Bug — Bug fixes." +msgstr "" + +#. type: Plain text +#: ../src/internals/021-changelog-upgrade.md +msgid "In the changelog file lines should be ordered as New, Chg, Enh, Bug." +msgstr "" + +#. type: Plain text +#: ../src/internals/021-changelog-upgrade.md +msgid "\"#42\" above is the number of issue or pull requests corresponding to the change. \"author1\" is the GitHub nickname of the code author. \"author2\" is an additional author. An author's nickname MUST be prefixed with `@`." +msgstr "" + +#. type: Title ## +#: ../src/internals/021-changelog-upgrade.md +#, no-wrap +msgid "Upgrade" +msgstr "" + +#. type: Plain text +#: ../src/internals/021-changelog-upgrade.md +msgid "Upgrade guide is created when there is a new major version that isn't compatible with the previous one. It describes steps necessary to upgrade application code." +msgstr "" + +#. type: Plain text +#: ../src/internals/021-changelog-upgrade.md +msgid "The file name is `UPGRADE.md`. The format is the following:" +msgstr "" + +#. type: Fenced code block (markdown) +#: ../src/internals/021-changelog-upgrade.md +#, no-wrap +msgid "" +"# Upgrading Instructions for my package\n" +"\n" +"This file contains the upgrade notes. These notes highlight changes that could break your\n" +"application when you upgrade the package from one version to another.\n" +"\n" +"> **Important!** The following upgrading instructions are cumulative. That is, if you want\n" +"> to upgrade from version A to version C and there is version B between A and C, you need\n" +"> to follow the instructions for both A and B.\n" +"\n" +"## Upgrade from 2.x\n" +"\n" +"- Public method `test()` was removed. Use `perform()` instead.\n" +"\n" +"## Upgrade from 1.x\n" +"\n" +"- Clean up the cache after upgrading. Old cache is not compatible with new code.\n" +msgstr "" diff --git a/_translations/po/pt-BR/internals_022-config-groups.md.po b/_translations/po/pt-BR/internals_022-config-groups.md.po new file mode 100644 index 00000000..26409073 --- /dev/null +++ b/_translations/po/pt-BR/internals_022-config-groups.md.po @@ -0,0 +1,244 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-12-24 08:02+0000\n" +"PO-Revision-Date: 2025-12-24 08:02+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../src/en/guide/concept/configuration.md ../src/en/guide/concept/events.md +#: ../src/en/internals/022-config-groups.md +#, no-wrap +msgid "Events" +msgstr "" + +#. type: Title ## +#: ../src/en/guide/concept/configuration.md +#: ../src/en/internals/022-config-groups.md +#, no-wrap +msgid "Parameters" +msgstr "" + +#. type: Title ## +#: ../src/en/internals/003-roadmap.md ../src/en/internals/022-config-groups.md +#, no-wrap +msgid "Others" +msgstr "" + +#. type: Title # +#: ../src/en/internals/022-config-groups.md +#, no-wrap +msgid "022 — Config groups" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/022-config-groups.md +msgid "This document defines naming convention for the framework groups used with [yiisoft/config](https://github.com/yiisoft/config). Note that this isn't a naming convention for config files. These could be anything and are mapped to group names via `composer.json`." +msgstr "" + +#. type: Title ## +#: ../src/en/internals/022-config-groups.md +#, no-wrap +msgid "Config group name postfixes" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/022-config-groups.md +msgid "\"web\" postfix applies to web only that's classic server HTML generation, REST, RPC, etc." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/022-config-groups.md +msgid "\"console\" postfix applies to console" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/022-config-groups.md +msgid "If there's no postfix, it's \"common\" and applies to both web and console" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/022-config-groups.md +msgid "\"web\" and \"console\" may override what's defined in \"common\"" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/022-config-groups.md +msgid "Application config parameters that are used in all configs." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/022-config-groups.md +msgid "`params` — common parameters" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/022-config-groups.md +msgid "`params-web` — web application parameters" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/022-config-groups.md +msgid "`params-console` — console application parameters" +msgstr "" + +#. type: Title ## +#: ../src/en/internals/022-config-groups.md +#, no-wrap +msgid "Container" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/022-config-groups.md +msgid "Configuration for [yiisoft/di](https://github.com/yiisoft/di)." +msgstr "" + +#. type: Title ### +#: ../src/en/internals/022-config-groups.md +#, no-wrap +msgid "Definitions" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/022-config-groups.md +msgid "`di` — common container definitions" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/022-config-groups.md +msgid "`di-web` — web container definitions" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/022-config-groups.md +msgid "`di-console` — console container definitions" +msgstr "" + +#. type: Title ### +#: ../src/en/internals/022-config-groups.md +#, no-wrap +msgid "Providers" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/022-config-groups.md +msgid "`di-providers` — common container providers" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/022-config-groups.md +msgid "`di-providers-web` — web container providers" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/022-config-groups.md +msgid "`di-providers-console` — console container providers" +msgstr "" + +#. type: Title ### +#: ../src/en/internals/022-config-groups.md +#, no-wrap +msgid "Delegates" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/022-config-groups.md +msgid "`di-delegates` — common container delegates" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/022-config-groups.md +msgid "`di-delegates-web` — web container delegates" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/022-config-groups.md +msgid "`di-delegates-console` — console container delegates" +msgstr "" + +#. type: Title ### +#: ../src/en/internals/022-config-groups.md +#, no-wrap +msgid "Tags" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/022-config-groups.md +msgid "`di-tags` — common container tags" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/022-config-groups.md +msgid "`di-tags-web` — web container tags" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/022-config-groups.md +msgid "`di-tags-console` — console container tags" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/022-config-groups.md +msgid "Configuration for [yiisoft/yii-event](https://github.com/yiisoft/yii-event)." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/022-config-groups.md +msgid "`events` — common events" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/022-config-groups.md +msgid "`events-web` — web events" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/022-config-groups.md +msgid "`events-console` — console events" +msgstr "" + +#. type: Title ## +#: ../src/en/internals/022-config-groups.md +#, no-wrap +msgid "Bootstrap" +msgstr "" + +#. type: Plain text +#: ../src/en/internals/022-config-groups.md +msgid "Application bootstrapping for [yiisoft/yii-runner](https://github.com/yiisoft/yii-runner)." +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/022-config-groups.md +msgid "`bootstrap` — common bootstrap" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/022-config-groups.md +msgid "`bootstrap-web` — web bootstrap" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/022-config-groups.md +msgid "`bootstrap-console` — console bootstrap" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/022-config-groups.md +msgid "`routes` — [yiisoft/router](https://github.com/yiisoft/router) routes" +msgstr "" + +#. type: Bullet: '- ' +#: ../src/en/internals/022-config-groups.md +msgid "`widgets` — [yiisoft/widget](https://github.com/yiisoft/widget) default widgets configuration" +msgstr "" diff --git a/_translations/po/pt-BR/internals_023-github-actions.md.po b/_translations/po/pt-BR/internals_023-github-actions.md.po new file mode 100644 index 00000000..74b83cf3 --- /dev/null +++ b/_translations/po/pt-BR/internals_023-github-actions.md.po @@ -0,0 +1,80 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-04-05 07:15+0000\n" +"PO-Revision-Date: 2026-04-05 07:15+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/internals/023-github-actions.md +#, no-wrap +msgid "023 — GitHub Actions" +msgstr "" + +#. type: Plain text +#: ../src/internals/023-github-actions.md +msgid "This document defines naming convention for the GitHub actions configuration files." +msgstr "" + +#. type: Title ## +#: ../src/internals/023-github-actions.md +#, no-wrap +msgid "Inputs and Outputs" +msgstr "" + +#. type: Plain text +#: ../src/internals/023-github-actions.md +msgid "Input names and output names must use kebab-case format." +msgstr "" + +#. type: Plain text +#: ../src/internals/023-github-actions.md +msgid "For example:" +msgstr "" + +#. type: Fenced code block (yaml) +#: ../src/internals/023-github-actions.md +#, no-wrap +msgid "" +"inputs:\n" +" my-input:\n" +" description: 'My input'\n" +msgstr "" + +#. type: Title ## +#: ../src/internals/023-github-actions.md +#, no-wrap +msgid "Secrets and Environment Variables" +msgstr "" + +#. type: Plain text +#: ../src/internals/023-github-actions.md +msgid "Secret names and environment variable names must use SCREAMING_SNAKE_CASE format." +msgstr "" + +#. type: Fenced code block (yaml) +#: ../src/internals/023-github-actions.md +#, no-wrap +msgid "" +"secrets:\n" +" MY_SECRET:\n" +" description: 'My secret'\n" +msgstr "" + +#. type: Fenced code block (yaml) +#: ../src/internals/023-github-actions.md +#, no-wrap +msgid "" +"env:\n" +" MY_ENV_VAR: 1\n" +msgstr "" diff --git a/_translations/po/pt-BR/internals_index.md.po b/_translations/po/pt-BR/internals_index.md.po new file mode 100644 index 00000000..7cbca58c --- /dev/null +++ b/_translations/po/pt-BR/internals_index.md.po @@ -0,0 +1,153 @@ +# Language pt-BR translations for PACKAGE package +# Copyright (C) 2026 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2026-04-05 07:15+0000\n" +"PO-Revision-Date: 2026-04-05 07:15+0000\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" +"Language: pt-BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../src/internals/index.md +#, no-wrap +msgid "Yii Framework Internals" +msgstr "Detalhes internos do Yii Framework" + +#. type: Plain text +#: ../src/internals/index.md +msgid "This section contains documentation for developers contributing to the Yii framework itself. It covers guidelines, workflows, and best practices for maintaining and developing Yii packages." +msgstr "Esta seção contém documentação para quem contribui com o próprio framework Yii. Ela cobre diretrizes, fluxos de trabalho e boas práticas para manter e desenvolver os pacotes do Yii." + +#. type: Title ## +#: ../src/internals/index.md +#, no-wrap +msgid "Table of Contents" +msgstr "Sumário" + +#. type: Bullet: '- ' +#: ../src/internals/index.md +msgid "[000 — Packages](000-packages.md) - Package structure and naming conventions" +msgstr "[000 — Pacotes](000-packages.md) - Estrutura e convenções de nomes dos pacotes" + +#. type: Bullet: '- ' +#: ../src/internals/index.md +msgid "[001 — Yii goal and values](001-yii-values.md) - Project goals and core values" +msgstr "[001 — Objetivo e valores do Yii](001-yii-values.md) - Objetivos e valores centrais do projeto" + +#. type: Bullet: '- ' +#: ../src/internals/index.md +msgid "[002 — Issue workflow](002-issue-workflow.md) - How to handle issues" +msgstr "[002 — Fluxo de issues](002-issue-workflow.md) - Como lidar com issues" + +#. type: Bullet: '- ' +#: ../src/internals/index.md +msgid "[003 — Roadmap](003-roadmap.md) - Development roadmap and future plans" +msgstr "[003 — Roadmap](003-roadmap.md) - Roadmap de desenvolvimento e planos futuros" + +#. type: Bullet: '- ' +#: ../src/internals/index.md +msgid "[004 — Namespaces](004-namespaces.md) - Namespace conventions" +msgstr "[004 — Namespaces](004-namespaces.md) - Convenções de namespaces" + +#. type: Bullet: '- ' +#: ../src/internals/index.md +msgid "[005 — Yii development tool](005-development-tool.md) - Development tools for Yii packages" +msgstr "[005 — Ferramenta de desenvolvimento do Yii](005-development-tool.md) - Ferramentas de desenvolvimento para pacotes do Yii" + +#. type: Bullet: '- ' +#: ../src/internals/index.md +msgid "[006 — Git commit messages](006-git-commit-messages.md) - Commit message format" +msgstr "[006 — Mensagens de commit no Git](006-git-commit-messages.md) - Formato das mensagens de commit" + +#. type: Bullet: '- ' +#: ../src/internals/index.md +msgid "[007 — Exceptions](007-exceptions.md) - Exception handling guidelines" +msgstr "[007 — Exceções](007-exceptions.md) - Diretrizes para exceções" + +#. type: Bullet: '- ' +#: ../src/internals/index.md +msgid "[008 — Interfaces](008-interfaces.md) - Interface design principles" +msgstr "[008 — Interfaces](008-interfaces.md) - Princípios de design de interfaces" + +#. type: Bullet: '- ' +#: ../src/internals/index.md +msgid "[009 — Design Decisions](009-design-decisions.md) - Architectural and design decisions" +msgstr "[009 — Decisões de design](009-design-decisions.md) - Decisões de arquitetura e design" + +#. type: Bullet: '- ' +#: ../src/internals/index.md +msgid "[010 — Code style](010-code-style.md) - PHP code style guidelines" +msgstr "[010 — Estilo de código](010-code-style.md) - Diretrizes de estilo de código PHP" + +#. type: Bullet: '- ' +#: ../src/internals/index.md +msgid "[011 — Error correction](011-error-correction.md) - Error handling and correction" +msgstr "[011 — Correção de erros](011-error-correction.md) - Tratamento e correção de erros" + +#. type: Bullet: '- ' +#: ../src/internals/index.md +msgid "[012 — Tests](012-tests.md) - Testing guidelines and practices" +msgstr "[012 — Testes](012-tests.md) - Diretrizes e práticas de testes" + +#. type: Bullet: '- ' +#: ../src/internals/index.md +msgid "[013 — Code review](013-code-review.md) - Code review process and guidelines" +msgstr "[013 — Code review](013-code-review.md) - Processo e diretrizes de code review" + +#. type: Bullet: '- ' +#: ../src/internals/index.md +msgid "[014 — Documentation](014-docs.md) - Documentation writing guidelines" +msgstr "[014 — Documentação](014-docs.md) - Diretrizes para escrever documentação" + +#. type: Bullet: '- ' +#: ../src/internals/index.md +msgid "[015 — PhpStorm metadata and attributes](015-phpstorm.md) - PhpStorm integration" +msgstr "[015 — Metadados e atributos do PhpStorm](015-phpstorm.md) - Integração com o PhpStorm" + +#. type: Bullet: '- ' +#: ../src/internals/index.md +msgid "[016 — Security workflow](016-security-workflow.md) - Security issue handling" +msgstr "[016 — Fluxo de segurança](016-security-workflow.md) - Tratamento de problemas de segurança" + +#. type: Bullet: '- ' +#: ../src/internals/index.md +msgid "[017 — Tags](017-tags.md) - Git tagging conventions" +msgstr "[017 — Tags](017-tags.md) - Convenções de tags no Git" + +#. type: Bullet: '- ' +#: ../src/internals/index.md +msgid "[018 — Widgets](018-widgets.md) - Widget development guidelines" +msgstr "[018 — Widgets](018-widgets.md) - Diretrizes para desenvolver widgets" + +#. type: Bullet: '- ' +#: ../src/internals/index.md +msgid "[019 — View code style](019-view-code-style.md) - Code style for view templates" +msgstr "[019 — Estilo de código de views](019-view-code-style.md) - Estilo de código para templates de view" + +#. type: Bullet: '- ' +#: ../src/internals/index.md +msgid "[020 — Package release](020-package-release.md) - Release process for packages" +msgstr "[020 — Release de pacotes](020-package-release.md) - Processo de release de pacotes" + +#. type: Bullet: '- ' +#: ../src/internals/index.md +msgid "[021 — Changelog and upgrade](021-changelog-upgrade.md) - Maintaining changelogs and upgrade notes" +msgstr "[021 — Changelog e upgrade](021-changelog-upgrade.md) - Mantendo changelogs e notas de upgrade" + +#. type: Bullet: '- ' +#: ../src/internals/index.md +msgid "[022 — Config groups](022-config-groups.md) - Configuration group organization" +msgstr "[022 — Grupos de configuração](022-config-groups.md) - Organização dos grupos de configuração" + +#. type: Bullet: '- ' +#: ../src/internals/index.md +msgid "[023 - GitHub Actions](023-github-actions.md) - GitHub actions configuration" +msgstr "[023 - GitHub Actions](023-github-actions.md) - Configuração do GitHub Actions" diff --git a/_translations/po4a-base.conf b/_translations/po4a-base.conf index 63e1aa0a..fe5ca0ae 100644 --- a/_translations/po4a-base.conf +++ b/_translations/po4a-base.conf @@ -1,4 +1,4 @@ -[po4a_langs] ru id it es zh-CN +[po4a_langs] ru id it es zh-CN pt-BR [po4a_paths] pot/$master.pot $lang:po/$lang/$master.po [options] opt:"--verbose" opt:"--addendum-charset=UTF-8" opt:"--localized-charset=UTF-8" opt:"--master-charset=UTF-8" opt:"--master-language=en_US" opt:"--porefs=file" opt:"--msgmerge-opt='--no-wrap'" opt:"--wrap-po=newlines" diff --git a/_translations/po4a.conf b/_translations/po4a.conf index 28219324..39894812 100644 --- a/_translations/po4a.conf +++ b/_translations/po4a.conf @@ -1,4 +1,4 @@ -[po4a_langs] ru id it es zh-CN +[po4a_langs] ru id it es zh-CN pt-BR [po4a_paths] pot/$master.pot $lang:po/$lang/$master.po [options] opt:"--verbose" opt:"--addendum-charset=UTF-8" opt:"--localized-charset=UTF-8" opt:"--master-charset=UTF-8" opt:"--master-language=en_US" opt:"--porefs=file" opt:"--msgmerge-opt='--no-wrap'" opt:"--wrap-po=newlines" diff --git a/src/.vitepress/config.js b/src/.vitepress/config.js index 056dc216..a7759b93 100644 --- a/src/.vitepress/config.js +++ b/src/.vitepress/config.js @@ -1320,6 +1320,291 @@ export default { } } } + }, + 'pt-BR': { + title: 'Documentação do Yii3', + label: 'Português (Brasil)', + lang: 'pt-BR', + link: '/pt-BR/', + themeConfig: { + nav: [ + {text: 'Guia', link: '/pt-BR/guide/'}, + {text: 'Cookbook', link: '/pt-BR/cookbook/'}, + {text: 'Detalhes internos', link: '/pt-BR/internals/'}, + {text: 'Site', link: 'https://www.yiiframework.com'} + ], + sidebar: { + '/pt-BR/guide/': [ + { + text: 'Introdução', + items: [ + {text: 'Sobre o Yii', link: '/pt-BR/guide/intro/what-is-yii'}, + {text: 'Atualizando a partir da versão 1.1', link: '/pt-BR/guide/intro/upgrade-from-v1'}, + {text: 'Atualizando a partir da versão 2', link: '/pt-BR/guide/intro/upgrade-from-v2'} + ] + }, + { + text: 'Primeiros passos', + items: [ + {text: 'O que você precisa saber', link: '/pt-BR/guide/start/prerequisites'}, + {text: 'Criando um projeto', link: '/pt-BR/guide/start/creating-project'}, + {text: 'Fluxo da aplicação', link: '/pt-BR/guide/start/workflow'}, + {text: 'Dizendo olá', link: '/pt-BR/guide/start/hello'}, + {text: 'Trabalhando com formulários', link: '/pt-BR/guide/start/forms'}, + {text: 'Trabalhando com bancos de dados', link: '/pt-BR/guide/start/databases'}, + {text: 'Gerando código com o Gii', link: '/pt-BR/guide/start/gii'}, + {text: 'Seguindo em frente', link: '/pt-BR/guide/start/looking-ahead'}, + {text: 'Aplicações de demonstração', link: '/pt-BR/guide/start/demo-apps'} + ] + }, + { + text: 'Conceitos principais', + items: [ + {text: 'Aliases', link: '/pt-BR/guide/concept/aliases'}, + {text: 'Autoload', link: '/pt-BR/guide/concept/autoloading'}, + {text: 'Configuração', link: '/pt-BR/guide/concept/configuration'}, + {text: 'Container de DI', link: '/pt-BR/guide/concept/di-container'}, + {text: 'Eventos', link: '/pt-BR/guide/concept/events'}, + {text: 'Imutabilidade', link: '/pt-BR/guide/concept/immutability'} + ] + }, + { + text: 'Estrutura da aplicação', + items: [ + {text: 'Visão geral', link: '/pt-BR/guide/structure/overview'}, + {text: 'Script de entrada', link: '/pt-BR/guide/structure/entry-script'}, + {text: 'Aplicação', link: '/pt-BR/guide/structure/application'}, + {text: 'Módulo', link: '/pt-BR/guide/structure/module'}, + {text: 'Action', link: '/pt-BR/guide/structure/action'}, + {text: 'Middleware', link: '/pt-BR/guide/structure/middleware'} + ] + }, + { + text: 'Pacotes', + items: [ + {text: 'Usando pacotes', link: '/pt-BR/guide/structure/package'}, + {text: 'Projetando pacotes', link: '/pt-BR/guide/structure/designing-packages'} + ] + }, + { + text: 'Tratando requisições', + items: [ + {text: 'Roteamento', link: '/pt-BR/guide/runtime/routing'}, + {text: 'Requisição', link: '/pt-BR/guide/runtime/request'}, + {text: 'Resposta', link: '/pt-BR/guide/runtime/response'}, + {text: 'Sessões', link: '/pt-BR/guide/runtime/sessions'}, + {text: 'Cookies', link: '/pt-BR/guide/runtime/cookies'}, + {text: 'Tratamento de erros', link: '/pt-BR/guide/runtime/handling-errors'}, + {text: 'Logs', link: '/pt-BR/guide/runtime/logging'} + ] + }, + { + text: 'APIs REST', + items: [ + {text: 'Início rápido', link: '/pt-BR/guide/rest/quick-start'} + ] + }, + { + text: 'Segurança', + items: [ + {text: 'Visão geral', link: '/pt-BR/guide/security/overview'}, + {text: 'Autenticação', link: '/pt-BR/guide/security/authentication'}, + {text: 'Autorização', link: '/pt-BR/guide/security/authorization'}, + {text: 'Trabalhando com senhas', link: '/pt-BR/guide/security/passwords'}, + {text: 'Criptografia', link: '/pt-BR/guide/security/cryptography'}, + {text: 'Requisição confiável', link: '/pt-BR/guide/security/trusted-request'}, + {text: 'Boas práticas', link: '/pt-BR/guide/security/best-practices'} + ] + }, + { + text: 'Cache', + items: [ + {text: 'Visão geral', link: '/pt-BR/guide/caching/overview'}, + {text: 'Cache de dados', link: '/pt-BR/guide/caching/data'} + ] + }, + { + text: 'Trabalhando com bancos de dados', + items: [ + {text: 'Yii DB', link: 'https://github.com/yiisoft/db/blob/master/docs/guide/en/README.md'}, + {text: 'Active Record', link: 'https://github.com/yiisoft/active-record/blob/master/README.md'}, + {text: 'Migrations de banco de dados', link: '/pt-BR/guide/databases/db-migrations'} + ] + }, + { + text: 'Views', + items: [ + {text: 'Views', link: '/pt-BR/guide/views/view'}, + {text: 'Assets', link: '/pt-BR/guide/views/asset'}, + {text: 'Scripts, estilos e meta tags', link: '/pt-BR/guide/views/script-style-meta'}, + {text: 'Template engines', link: '/pt-BR/guide/views/template-engines'}, + {text: 'Injeções em views', link: '/pt-BR/guide/views/view-injections'}, + {text: 'Widgets', link: '/pt-BR/guide/views/widget'} + ] + }, + { + text: 'Testes', + items: [ + {text: 'Visão geral de testes', link: '/pt-BR/guide/testing/overview'}, + {text: 'Configurando o ambiente de testes', link: '/pt-BR/guide/testing/environment-setup'}, + {text: 'Testes unitários', link: '/pt-BR/guide/testing/unit'}, + {text: 'Testes funcionais', link: '/pt-BR/guide/testing/functional'}, + {text: 'Testes end-to-end', link: '/pt-BR/guide/testing/end-to-end'}, + {text: 'Análise estática e testes de mutação', link: '/pt-BR/guide/testing/quality-tools'} + ] + }, + { + text: 'Tutorial', + items: [ + {text: 'Aplicações de console', link: '/pt-BR/guide/tutorial/console-applications'}, + {text: 'Envio de e-mails', link: '/pt-BR/guide/tutorial/mailing'}, + {text: 'Otimização de desempenho', link: '/pt-BR/guide/tutorial/performance-tuning'}, + {text: 'Usando com event loop', link: '/pt-BR/guide/tutorial/using-with-event-loop'}, + {text: 'Usando o Yii com FrankenPHP', link: '/pt-BR/guide/tutorial/using-yii-with-frankenphp'}, + {text: 'Usando o Yii com Rapira', link: '/pt-BR/guide/tutorial/using-yii-with-rapira'}, + {text: 'Usando o Yii com RoadRunner', link: '/pt-BR/guide/tutorial/using-yii-with-roadrunner'}, + {text: 'Usando o Yii com Swoole', link: '/pt-BR/guide/tutorial/using-yii-with-swoole'}, + {text: 'Docker nos templates de aplicação', link: '/pt-BR/guide/tutorial/docker'}, + {text: 'Internacionalização', link: '/pt-BR/guide/tutorial/i18n'} + ] + }, + { + text: 'Helpers', + items: [ + {text: 'Arrays', link: 'https://github.com/yiisoft/arrays/'}, + {text: 'Arquivos', link: 'https://github.com/yiisoft/files/'}, + {text: 'Html', link: 'https://github.com/yiisoft/html/'}, + {text: 'Json', link: 'https://github.com/yiisoft/json'}, + {text: 'Utilitários de rede', link: 'https://github.com/yiisoft/network-utilities/'}, + {text: 'VarDumper', link: 'https://github.com/yiisoft/var-dumper'}, + {text: 'Strings', link: 'https://github.com/yiisoft/strings'} + ] + }, + { + text: 'Glossário', + link: '/pt-BR/guide/glossary' + } + ], + '/pt-BR/cookbook/': [ + { + text: 'Cookbook', + items: [ + {text: 'Prefácio', link: '/pt-BR/cookbook/preface'}, + {text: 'Fazendo requisições HTTP', link: '/pt-BR/cookbook/making-http-requests'}, + {text: 'Usando htmx para recarregar partes da página', link: '/pt-BR/cookbook/using-htmx-for-partial-reloads'}, + {text: 'Desativando a proteção CSRF', link: '/pt-BR/cookbook/disabling-csrf-protection'}, + {text: 'Integração com o Sentry', link: '/pt-BR/cookbook/sentry-integration'}, + {text: 'Usando um template de migration personalizado', link: '/pt-BR/cookbook/custom-migration-template'}, + {text: 'Type casters personalizados para o hydrator', link: '/pt-BR/cookbook/custom-hydrator-type-casters'}, + {text: 'Usando o Yii em aplicações de terceiros', link: '/pt-BR/cookbook/using-yii-in-third-party-apps'}, + {text: 'Integrações com terceiros', link: '/pt-BR/cookbook/third-party-integrations/'} + ] + }, + { + text: 'Ambiente de desenvolvimento', + collapsed: false, + items: [ + {text: 'Trabalhando no Windows', link: '/pt-BR/cookbook/working-on-windows'}, + {text: 'Abrindo arquivos no PhpStorm', link: '/pt-BR/cookbook/opening-files-in-phpstorm'}, + {text: 'Configurando o Xdebug', link: '/pt-BR/cookbook/configuring-xdebug'} + ] + }, + { + text: 'Configurando servidores web', + collapsed: false, + items: [ + {text: 'Geral', link: '/pt-BR/cookbook/configuring-webservers/general'}, + {text: 'Apache', link: '/pt-BR/cookbook/configuring-webservers/apache'}, + {text: 'Nginx', link: '/pt-BR/cookbook/configuring-webservers/nginx'}, + {text: 'Nginx Unit', link: '/pt-BR/cookbook/configuring-webservers/nginx-unit'}, + {text: 'IIS', link: '/pt-BR/cookbook/configuring-webservers/iis'}, + {text: 'Lighttpd', link: '/pt-BR/cookbook/configuring-webservers/lighttpd'} + ] + }, + { + text: 'Organizando o código', + items: [ + {text: 'Vertical slices', link: '/pt-BR/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices'}, + {text: 'Domínio', link: '/pt-BR/cookbook/organizing-code/domain'}, + {text: 'Serviço', link: '/pt-BR/cookbook/organizing-code/service'} + ] + }, + { + text: 'Deploy', + items: [ + {text: 'Docker Swarm', link: '/pt-BR/cookbook/deployment/docker-swarm'}, + {text: 'Angie Docker Proxy', link: '/pt-BR/cookbook/deployment/angie-docker-proxy'}, + {text: 'Autoscaling', link: '/pt-BR/cookbook/deployment/autoscaling'}, + {text: 'Migrations em rolling updates', link: '/pt-BR/cookbook/deployment/rolling-update-migrations'} + ] + } + ], + '/pt-BR/internals/': [ + { + text: 'Detalhes internos', + items: [ + {text: 'Pacotes', link: '/pt-BR/internals/000-packages'}, + {text: 'Valores do Yii', link: '/pt-BR/internals/001-yii-values'}, + {text: 'Fluxo de issues', link: '/pt-BR/internals/002-issue-workflow'}, + {text: 'Roadmap', link: '/pt-BR/internals/003-roadmap'}, + {text: 'Namespaces', link: '/pt-BR/internals/004-namespaces'}, + {text: 'Ferramenta de desenvolvimento', link: '/pt-BR/internals/005-development-tool'}, + {text: 'Mensagens de commit no Git', link: '/pt-BR/internals/006-git-commit-messages'}, + {text: 'Exceções', link: '/pt-BR/internals/007-exceptions'}, + {text: 'Interfaces', link: '/pt-BR/internals/008-interfaces'}, + {text: 'Decisões de design', link: '/pt-BR/internals/009-design-decisions'}, + {text: 'Estilo de código', link: '/pt-BR/internals/010-code-style'}, + {text: 'Correção de erros', link: '/pt-BR/internals/011-error-correction'}, + {text: 'Testes', link: '/pt-BR/internals/012-tests'}, + {text: 'Code review', link: '/pt-BR/internals/013-code-review'}, + {text: 'Documentação', link: '/pt-BR/internals/014-docs'}, + {text: 'PHPStorm', link: '/pt-BR/internals/015-phpstorm'}, + {text: 'Fluxo de segurança', link: '/pt-BR/internals/016-security-workflow'}, + {text: 'Tags', link: '/pt-BR/internals/017-tags'}, + {text: 'Widgets', link: '/pt-BR/internals/018-widgets'}, + {text: 'Estilo de código de views', link: '/pt-BR/internals/019-view-code-style'}, + {text: 'Release de pacotes', link: '/pt-BR/internals/020-package-release'}, + {text: 'Changelog e upgrade', link: '/pt-BR/internals/021-changelog-upgrade'}, + {text: 'Grupos de configuração', link: '/pt-BR/internals/022-config-groups'}, + {text: 'GitHub Actions', link: '/pt-BR/internals/023-github-actions'} + ] + } + ] + }, + footer: { + message: 'Publicado sob a Licença BSD-3-Clause.', + copyright: `Copyright © 2008-${currentYear} Yii` + }, + docFooter: { + prev: 'Página anterior', + next: 'Próxima página', + }, + outline: { + label: 'Nesta página' + }, + lastUpdated: { + text: 'Atualizado em' + }, + search: { + options: { + translations: { + button: { + buttonText: 'Pesquisar', + buttonAriaLabel: 'Pesquisar' + }, + modal: { + noResultsText: 'Nenhum resultado para', + resetButtonTitle: 'Limpar pesquisa', + footer: { + selectText: 'selecionar', + navigateText: 'navegar', + closeText: 'fechar' + } + } + } + } + } + } } } } diff --git a/src/pt-BR/cookbook/configuring-webservers/apache.md b/src/pt-BR/cookbook/configuring-webservers/apache.md new file mode 100644 index 00000000..e70f518b --- /dev/null +++ b/src/pt-BR/cookbook/configuring-webservers/apache.md @@ -0,0 +1,60 @@ +# Configuring web servers: Apache + +Use the following configuration in Apache's `httpd.conf` file or within a +virtual host configuration. Note that you should replace +`path/to/app/public` with the actual path for `app/public`. + +```apache +# Set document root to be "app/public" +DocumentRoot "path/to/app/public" + + + # use mod_rewrite for pretty URL support + RewriteEngine on + + # Do not allow access to URLs with a script name + RewriteCond %{THE_REQUEST} index.php [NC] + RewriteRule . - [R=404,L] + + # If a directory or a file exists, use the request directly + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + + # Otherwise forward the request to index.php + RewriteRule . index.php + + SetEnv APP_ENV dev + + # ...other settings... + +``` + +In case you have `AllowOverride All` you can add `.htaccess` file with the +following configuration instead of using `httpd.conf`: + +```apache +# use mod_rewrite for pretty URL support +RewriteEngine on + +# Do not allow access to URLs with a script name +RewriteCond %{THE_REQUEST} index.php [NC] +RewriteRule . - [R=404,L] + +# If a directory or a file exists, use the request directly +RewriteCond %{REQUEST_FILENAME} !-f +RewriteCond %{REQUEST_FILENAME} !-d + +# Otherwise forward the request to index.php +RewriteRule . index.php + +SetEnv APP_ENV dev + +# ...other settings... +``` + +In the above, note the usage of `SetEnv`. Since Yii3 application templates +use environment variables, this is a possible place to set them. In +production environment remember to set `APP_ENV` to `prod`. + +See [application logs](general.md#application-logs) for logging +configuration. diff --git a/src/pt-BR/cookbook/configuring-webservers/general.md b/src/pt-BR/cookbook/configuring-webservers/general.md new file mode 100644 index 00000000..64c5cae3 --- /dev/null +++ b/src/pt-BR/cookbook/configuring-webservers/general.md @@ -0,0 +1,43 @@ +# Configuring web servers: General + +On a production server, if you don't use Docker, configure your web server +to serve only the application's public files. Point the document root of +your web server to the `app/public` folder. + +> [!IMPORTANT] +> If you're running your Yii application behind a reverse proxy, you might need to configure +> [Trusted proxies and headers](../../guide/security/trusted-request.md). + +## Application logs + +Yii3 application templates write application logs to standard output +(`stdout`, or `php://stdout`) by default. They don't create application log +files. Standard error (`stderr`) requires explicit log target +configuration. Docker collects container output, but on a server without +containers you must configure where that output goes or [configure a file +target](../../guide/runtime/logging.md#logging-to-files). Web server access +and error log settings don't configure Yii's log targets. + +### PHP-FPM + +If your web server uses PHP-FPM, enable worker output capture in the +application's PHP-FPM pool configuration: + +```ini +catch_workers_output = yes +``` + +Reload PHP-FPM after changing its configuration. PHP-FPM sends worker +standard output and standard error to its main error log. The `error_log` +directive in `php-fpm.conf` sets the destination. Without this setting, +PHP-FPM redirects both streams to `/dev/null` by default. See the [PHP-FPM +configuration +reference](https://www.php.net/manual/en/install.fpm.configuration.php). + +## Specific server configurations + +- [Nginx](nginx.md) +- [Apache](apache.md) +- [Lighttpd](lighttpd.md) +- [Nginx Unit](nginx-unit.md) +- [IIS](iis.md) diff --git a/src/pt-BR/cookbook/configuring-webservers/iis.md b/src/pt-BR/cookbook/configuring-webservers/iis.md new file mode 100644 index 00000000..971a2570 --- /dev/null +++ b/src/pt-BR/cookbook/configuring-webservers/iis.md @@ -0,0 +1,36 @@ +# Configuring web servers: IIS + +When you use [IIS](https://www.iis.net/), host the application in a virtual +host (Website) where the document root points to the `path/to/app/public` +folder and configure the website to run PHP. In that `public` folder, place +a file named `web.config` at `path/to/app/public/web.config`. Use the +following content: + +```xml + + + + + + + + + + + + + + + + + + +``` + +Also, [IIS documentation](https://learn.microsoft.com/en-us/iis/) could be +useful to configure PHP on IIS. + +See [application logs](general.md#application-logs) for logging +configuration. diff --git a/src/pt-BR/cookbook/configuring-webservers/lighttpd.md b/src/pt-BR/cookbook/configuring-webservers/lighttpd.md new file mode 100644 index 00000000..aee8a84e --- /dev/null +++ b/src/pt-BR/cookbook/configuring-webservers/lighttpd.md @@ -0,0 +1,10 @@ +# Configuring web servers: lighttpd + +To use [lighttpd](https://www.lighttpd.net/) >= 1.4.24, put `index.php` in the web root and add the following to the configuration: + +``` +url.rewrite-if-not-file = ("(.*)" => "/index.php/$0") +``` + +See [application logs](general.md#application-logs) for logging +configuration. diff --git a/src/pt-BR/cookbook/configuring-webservers/nginx-unit.md b/src/pt-BR/cookbook/configuring-webservers/nginx-unit.md new file mode 100644 index 00000000..4f363428 --- /dev/null +++ b/src/pt-BR/cookbook/configuring-webservers/nginx-unit.md @@ -0,0 +1,70 @@ +# Configuring web servers: NGINX Unit and FreeUnit + +Run Yii-based apps using [NGINX Unit](https://unit.nginx.org/) with a PHP +language module. The same configuration format is used by +[FreeUnit](https://github.com/freeunitorg/freeunit), a community LTS fork of +Unit. With FreeUnit Docker images, such as +`ghcr.io/freeunitorg/freeunit:latest-php8.5`, put the configuration in +`/var/lib/unit/config.json`. + +Here is a sample configuration. + +```json +{ + "listeners": { + "*:80": { + "pass": "routes" + } + }, + + "routes": [ + { + "match": { + "uri": [ + "!/assets/*", + "*.php", + "*.php/*" + ] + }, + + "action": { + "pass": "applications/yii/direct" + } + }, + { + "action": { + "share": "/path/to/app/public$uri", + "fallback": { + "pass": "applications/yii/index" + } + } + } + ], + + "applications": { + "yii": { + "type": "php", + "targets": { + "direct": { + "root": "/path/to/app/public/" + }, + + "index": { + "root": "/path/to/app/public/", + "script": "index.php" + } + } + } + } +} +``` + +You can also [set up](https://unit.nginx.org/configuration/#php) your PHP +environment or supply a custom `php.ini` in the same configuration. + +Since Yii3 application templates use environment variables, you can set them +in `applications.yii.environment`. In a production environment, remember to +set `APP_ENV` to `prod`. + +See [application logs](general.md#application-logs) for logging +configuration. diff --git a/src/pt-BR/cookbook/configuring-webservers/nginx.md b/src/pt-BR/cookbook/configuring-webservers/nginx.md new file mode 100644 index 00000000..5b47c96c --- /dev/null +++ b/src/pt-BR/cookbook/configuring-webservers/nginx.md @@ -0,0 +1,66 @@ +# Configuring web servers: Nginx + +To use [Nginx](https:/nginx.org/), install PHP as an [FPM +SAPI](https://secure.php.net/install.fpm). Use the following Nginx +configuration, replacing `path/to/app/public` with the actual path for +`app/public` and `mysite.test` with the actual hostname to serve. + +```nginx +server { + charset utf-8; + client_max_body_size 128M; + + listen 80; ## listen for ipv4 + #listen [::]:80 default_server ipv6only=on; ## listen for ipv6 + + server_name mysite.test; + root /path/to/app/public; + index index.php; + + access_log /path/to/basic/log/access.log; + error_log /path/to/basic/log/error.log; + + location / { + # Redirect everything that isn't a real file to index.php + try_files $uri $uri/ /index.php$is_args$args; + } + + # uncomment to avoid processing of calls to non-existing static files by Yii + #location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ { + # try_files $uri =404; + #} + #error_page 404 /404.html; + + # deny accessing php files for the /assets directory + location ~ ^/assets/.*\.php$ { + deny all; + } + + location ~ \.php$ { + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_pass 127.0.0.1:9000; + #fastcgi_pass unix:/var/run/php8-fpm.sock; + try_files $uri =404; + fastcgi_param APP_ENV "dev"; + } + + location ~* /\. { + deny all; + } +} +``` + +When you use this configuration, also set `cgi.fix_pathinfo=0` in the +`php.ini` file to avoid many unnecessary system `stat()` calls. + +Also, note that when running an HTTPS server, you need to add `fastcgi_param +HTTPS on;` so that Yii can detect if a connection is secure. + +In the above, note the usage of `fastcgi_param APP_ENV`. Since Yii3 +application templates use environment variables, this is a possible place to +set them. In production environment remember to set `APP_ENV` to `prod`. + +The Nginx `access_log` and `error_log` directives above don't capture +PHP-FPM worker output. See [application logs](general.md#application-logs) +for logging configuration. diff --git a/src/pt-BR/cookbook/configuring-xdebug.md b/src/pt-BR/cookbook/configuring-xdebug.md new file mode 100644 index 00000000..14d17192 --- /dev/null +++ b/src/pt-BR/cookbook/configuring-xdebug.md @@ -0,0 +1,278 @@ +# Configuring Xdebug + +Xdebug lets an IDE stop PHP code on breakpoints while the application +handles a web request, console command, or test. The IDE listens for debug +connections. PHP starts the request and Xdebug connects back to the IDE. + +Yii works with the regular Xdebug setup. Configure Xdebug for the PHP +runtime that executes the code and make sure the IDE can map runtime paths +to project files. + +## Check Xdebug + +Use Xdebug 3. The default debug port is `9003`. + +Without Docker, install Xdebug for the PHP executable that runs the +application, then check it: + +```shell +php --version +php --ri xdebug +``` + +In `php.ini` or an Xdebug-specific ini file, enable step debugging: + +```ini +xdebug.mode=develop,debug +xdebug.start_with_request=trigger +xdebug.client_host=127.0.0.1 +xdebug.client_port=9003 +``` + +`trigger` starts a debug session only when a browser extension, query +parameter, cookie, or `XDEBUG_SESSION` environment variable asks for it. + +With Docker, the Yii application template installs Xdebug in the development +image. Enable step debugging in `docker/dev/override.env`: + +```dotenv +XDEBUG_MODE=develop,debug +XDEBUG_CONFIG="client_host=host.docker.internal idekey=phpstorm" +``` + +Keep the default `SERVER_NAME=:80` from `docker/dev/.env` unless the +application needs a different Caddy address. Set the browser port with +`DEV_PORT` in `docker/.env`: + +```dotenv +DEV_PORT=80 +``` + +On Linux, Docker must resolve `host.docker.internal` to the host +gateway. The current Yii application template already has this in +`docker/compose.yml`: + +```yaml +services: + app: + extra_hosts: + - "host.docker.internal:host-gateway" +``` + +Rebuild the development image if Xdebug was added after the image had +already been built: + +```shell +make build +``` + +## PhpStorm + +In **Settings** > **PHP** > **Debug**, check that Xdebug listens on port `9003`. Start listening with +**Run** > **Start Listening for PHP Debug Connections**. + +For browser debugging, install a browser extension from **Settings** > **PHP** > **Debug**. In the extension options, +use `phpstorm` as the IDE key. + +When PHP runs in Docker, configure a server in **Settings** > **PHP** > **Servers**: + +- Name: `localhost`. +- Host: `localhost`. +- Port: `80`, or the host port configured by `DEV_PORT`. +- Debugger: `Xdebug`. +- Path mapping: map the project root on the host to `/app` in the container. + +Use the project root for the mapping. Mapping only `public/` leaves files +under `src/`, `config/`, and `vendor/` unmapped. The path in the container +must match the path used by PHP. In the default template, the project is +mounted into `/app`. + +For local PHP, PhpStorm usually uses the same filesystem paths as PHP, so +path mappings are usually unnecessary. + +## VS Code + +Install the [PHP +Debug](https://marketplace.visualstudio.com/items?itemName=xdebug.php-debug) +extension. + +For PHP that runs on the same filesystem as VS Code, create +`.vscode/launch.json`: + +```json +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Listen for Xdebug", + "type": "php", + "request": "launch", + "port": 9003 + } + ] +} +``` + +For Docker, add path mappings: + +```json +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Listen for Xdebug", + "type": "php", + "request": "launch", + "port": 9003, + "pathMappings": { + "/app": "${workspaceFolder}" + } + } + ] +} +``` + +Start this configuration before running the web request, command, or test. + +## Zed + +Install or enable the PHP extension in Zed. It provides the `Xdebug` debug +adapter. + +Create `.zed/debug.json`: + +```json +[ + { + "label": "PHP: Listen to Xdebug", + "adapter": "Xdebug", + "request": "launch", + "port": 9003 + } +] +``` + +For Docker, add path mappings: + +```json +[ + { + "label": "PHP: Listen to Xdebug", + "adapter": "Xdebug", + "request": "launch", + "port": 9003, + "pathMappings": { + "/app": "$ZED_WORKTREE_ROOT" + } + } +] +``` + +Start the configuration with **debugger: start** before running the web +request, command, or test. Zed can also load debug configurations from +`.vscode/launch.json` when `.zed/debug.json` is absent. + +## Debug a web request + +Without Docker: + +1. Start listening in the IDE. +2. Put a breakpoint in an action or middleware. +3. Start the built-in server with an Xdebug trigger: + + ```shell + ./yii serve --xdebug + ``` + +4. Open or reload the page in the browser. + +The `--xdebug` option passes `XDEBUG_MODE=debug XDEBUG_TRIGGER=yes` to the +built-in PHP server. If you use another web server, enable debugging with +the browser extension and reload the page. + +With Docker: + +1. Add the Docker Xdebug variables to `docker/dev/override.env`. +2. Start or restart the development containers: + + ```shell + make up + ``` + +3. Start listening in the IDE. +4. Put a breakpoint in an action or middleware. +5. Enable debugging in the browser extension and reload the page. + +If the IDE accepts a connection and the breakpoint stays inactive, check +path mappings first. + +## Debug a console command + +Without Docker, start the command with an Xdebug trigger: + +```shell +XDEBUG_MODE=debug XDEBUG_SESSION=phpstorm ./yii hello +``` + +With Docker, pass the trigger to the container: + +```shell +docker compose -f docker/compose.yml -f docker/dev/compose.yml run --rm \ + -e XDEBUG_MODE=debug \ + -e XDEBUG_SESSION=phpstorm \ + -e PHP_IDE_CONFIG=serverName=localhost \ + app ./yii hello +``` + +Use the command name and arguments you need instead of `hello`. + +## Debug tests + +Without Docker, start the test runner with an Xdebug trigger: + +```shell +XDEBUG_MODE=debug XDEBUG_SESSION=phpstorm vendor/bin/codecept run +``` + +With Docker, configure `docker/test/override.env`: + +```dotenv +XDEBUG_MODE=debug,coverage +XDEBUG_CONFIG="client_host=host.docker.internal idekey=phpstorm" +``` + +Then run the test container with a trigger: + +```shell +docker compose -f docker/compose.yml -f docker/test/compose.yml run --rm \ + -e XDEBUG_SESSION=phpstorm \ + -e PHP_IDE_CONFIG=serverName=localhost \ + app ./vendor/bin/codecept run +``` + +Use `make test` for regular test runs. Use the explicit `docker compose` +command when you need to pass debug-only environment variables to one run. + +## Troubleshooting + +- The IDE must listen before PHP starts the request. +- Xdebug connects from PHP to the IDE. Allow incoming connections to port + `9003` in the host firewall. +- In Docker, `client_host` must be reachable from the container. The Yii + template uses `host.docker.internal`. +- For CLI and tests, set `XDEBUG_SESSION=phpstorm` or another trigger + accepted by your Xdebug configuration. +- For Docker path mappings, map the host project root to `/app`. +- To inspect connection attempts, temporarily add + `log=/app/runtime/xdebug.log` to `XDEBUG_CONFIG`. + +## See also + +- [Xdebug step debugging](https://xdebug.org/docs/step_debug) +- [PhpStorm Xdebug + documentation](https://www.jetbrains.com/help/phpstorm/configuring-xdebug.html) +- [PhpStorm servers and path + mappings](https://www.jetbrains.com/help/phpstorm/servers.html) +- [VS Code PHP Debug](https://github.com/xdebug/vscode-php-debug) +- [Zed PHP documentation](https://zed.dev/docs/languages/php#debugging) +- [Docker in application templates](../guide/tutorial/docker.md) diff --git a/src/pt-BR/cookbook/custom-hydrator-type-casters.md b/src/pt-BR/cookbook/custom-hydrator-type-casters.md new file mode 100644 index 00000000..941ee344 --- /dev/null +++ b/src/pt-BR/cookbook/custom-hydrator-type-casters.md @@ -0,0 +1,564 @@ +# Custom hydrator type casters + +[Yii Hydrator](https://github.com/yiisoft/hydrator) creates objects and +fills them with data from arrays. It's used directly and by packages built +on top of it: + +- [Yii Input HTTP](https://github.com/yiisoft/input-http) fills request + input objects from query parameters, request body, and, with the help of + [Yii Router](https://github.com/yiisoft/router), route arguments. +- [Yii Form Model](https://github.com/yiisoft/form-model) provides + `FormHydrator` that fills form models from submitted data. + +The incoming data is usually "raw": HTTP requests, database rows, and queue +messages contain strings, numbers, and arrays. Before assigning a value to a +property or passing it to a constructor parameter, the hydrator converts it +to the declared type. A *type caster* performs this conversion. By writing +your own type caster, you teach the hydrator to create your types, such as +value objects, from raw data. + +## Why custom type casters + +Out of the box, the hydrator uses a composite type caster with two casters: + +- `PhpNativeTypeCaster` casts values to built-in PHP types, such as `int`, + `string`, `bool`, and `array`. +- `HydratorTypeCaster` creates nested objects from arrays using the hydrator + itself. + +That's enough for DTOs with scalar properties, but not for a rich domain +model. Consider a property typed as `UserId`, `Email`, or `Money`. The +incoming value is a string, and neither of the default casters knows how to +turn it into such an object. So you end up declaring the property as +`string` and converting it by hand wherever it's used: + +```php +final class CreatePostForm extends FormModel +{ + public string $authorId = ''; +} + +// In every action that uses the form: +try { + $authorId = new UserId($form->authorId); +} catch (InvalidArgumentException) { + // Report the error somehow. +} +``` + +With a type caster for `UserId`, you can declare the property with its real +type. The conversion happens during hydration: + +```php +final class CreatePostForm extends FormModel +{ + public ?UserId $authorId = null; +} + +// $form->authorId is already an instance of UserId. +``` + +The conversion logic lives in a single place. Once you register the caster, +the hydrator applies it to every property and constructor parameter of the +matching type in every object it creates. + +Typical use cases are: + +- value objects, such as entity IDs, emails, phone numbers, and money + amounts. +- types from third-party libraries, such as UUIDs, dates, or currencies. +- consistent normalization of values, for example, parsing dates in a format + specific to your application. + +## Anatomy of a type caster + +A type caster implements `Yiisoft\Hydrator\TypeCaster\TypeCasterInterface` +with a single method: + +```php +public function cast(mixed $value, TypeCastContext $context): Result; +``` + +- `$value` is the raw value to convert. +- `$context` is a `Yiisoft\Hydrator\TypeCaster\TypeCastContext`. Its + `getReflectionType()` method returns the declared type of the target + property or constructor parameter. Use it to decide whether the caster + supports the target type. +- The method returns a `Yiisoft\Hydrator\Result`: + `Result::success($convertedValue)` if the conversion succeeded or + `Result::fail()` if the caster can't handle the value. + +Follow these rules when writing a type caster: + +1. **Check the target type first.** If the declared type isn't the one your + caster is responsible for, return `Result::fail()` right away so other + casters can handle the value. +2. **Handle both named and union types.** PHP represents a nullable type + such as `?Email` (or `Email|null`) with `ReflectionNamedType` and + `Email|string` with `ReflectionUnionType`. In the latter case, look for + your type among its subtypes. +3. **Don't handle `null` yourself.** If the value is `null`, just return + `Result::fail()`. `PhpNativeTypeCaster` returns `null` for any type that + allows it, so a `null` value assigned to `?Email` stays `null`. +4. **Accept already converted values.** If the value is already an instance + of the target type, return it as is. +5. **Fail instead of throwing.** If your caster can't convert the value, for + example, a malformed string, return `Result::fail()`. An exception would + break the whole hydration. + +Keep in mind what happens when no caster succeeds: + +- For a property, the cast fails silently. The hydrator doesn't set the + property or report an error, so the property keeps its default + value. Reporting the problem to the user is the job of the validation that + runs after hydration. See [Null and invalid + values](#null-and-invalid-values) for an example. +- For a constructor parameter, the hydrator omits the argument. If the + parameter has a default value, it's used. Otherwise, object creation + fails with `WrongConstructorArgumentsCountException`, even for a nullable + parameter without a default value. + +## Registering a type caster + +Combine type casters with `CompositeTypeCaster`. It tries the casters one by +one and uses the result of the first one that succeeds. To add your caster, +redefine `TypeCasterInterface` in the DI container configuration, for +example, in `config/common/di/hydrator.php`. The `HydratorInterface` +implementation from the container uses this chain, as do packages that rely +on it, such as Yii Input HTTP: + +```php + static fn() => new CompositeTypeCaster( + new UuidValueTypeCaster(), + new PhpNativeTypeCaster(), + new HydratorTypeCaster(), + ), +]; +``` + +Since the first successful result wins, the order matters: + +- Put custom casters before `PhpNativeTypeCaster`. Otherwise, for a property + declared as `UserId|string`, `PhpNativeTypeCaster` accepts a string as is, + and your caster never runs. +- Keep the default casters in the list. `PhpNativeTypeCaster` casts scalar + values to built-in types, and `HydratorTypeCaster` creates nested objects + from arrays. + +If a caster has dependencies, take it from the container: + +```php + static fn(ContainerInterface $container) => new CompositeTypeCaster( + $container->get(MoneyTypeCaster::class), + new PhpNativeTypeCaster(), + new HydratorTypeCaster(), + ), +]; +``` + +### Registering for form models + +`FormHydrator` from Yii Form Model doesn't use `TypeCasterInterface`. Its DI +configuration creates a dedicated hydrator with its own chain of type +casters, so add your caster there as well: + +```php + [ + '__construct()' => [ + 'hydrator' => DynamicReference::to([ + 'class' => Hydrator::class, + '__construct()' => [ + 'typeCaster' => new CompositeTypeCaster( + new NullTypeCaster(emptyString: true), + new UuidValueTypeCaster(), + new PhpNativeTypeCaster(), + new NonArrayTypeCaster(), + new HydratorTypeCaster(), + ), + ], + ]), + ], + ], +]; +``` + +This definition replaces the one from the package, so keep its type +casters. This example uses the list from `config/di.php` of Yii Form Model +1.1. Check it against the version you use. `NullTypeCaster` turns empty +strings submitted by forms into `null` for nullable properties, so it stays +first. + +## Example: UUID value objects + +Entity IDs often use value objects, such as `UserId`, `PostId`, and +`OrderId`, instead of plain strings. Such objects make method signatures +self-documenting and prevent passing a post ID where a method expects a user +ID. The following example shows how to write a type caster that creates +them from UUID strings. + +### Value objects + +All ID value objects extend an abstract `UuidValue` class. The example uses +[ramsey/uuid](https://github.com/ramsey/uuid) to validate and generate +UUIDs: + +```shell +composer require ramsey/uuid +``` + +```php +value = Uuid::fromString($value)->toString(); + } + + public static function generate(): static + { + return new static(Uuid::uuid7()->toString()); + } + + public function equals(self $other): bool + { + return $other instanceof static && $other->value === $this->value; + } + + public function __toString(): string + { + return $this->value; + } +} +``` + +The constructor is final, so `new static()` is safe and creates every child +class from a string the same way. A concrete ID is just an empty child +class: + +```php +findUuidValueClass($context->getReflectionType()); + if ($class === null) { + return Result::fail(); + } + + if ($value instanceof $class) { + return Result::success($value); + } + + if (!is_string($value) || !Uuid::isValid($value)) { + return Result::fail(); + } + + return Result::success(new $class($value)); + } + + /** + * Returns the `UuidValue` child class from the declared type, or `null` if there is none or there are several + * of them, such as in `UserId|PostId`. + * + * @return class-string|null + */ + private function findUuidValueClass(?ReflectionType $type): ?string + { + $types = match (true) { + $type instanceof ReflectionNamedType => [$type], + $type instanceof ReflectionUnionType => $type->getTypes(), + default => [], + }; + + $classes = []; + foreach ($types as $subType) { + if ( + $subType instanceof ReflectionNamedType + && !$subType->isBuiltin() + && is_subclass_of($subType->getName(), UuidValue::class) + ) { + $classes[] = $subType->getName(); + } + } + + return count($classes) === 1 ? $classes[0] : null; + } +} +``` + +The caster follows the [rules for writing a type +caster](#anatomy-of-a-type-caster). It chooses the class to create from the +declared type. All IDs share the same UUID format, so a string alone can't +tell whether it's a user ID or a post ID. A single caster therefore serves +all `UuidValue` child classes, and adding a new ID class doesn't require +changes to the caster. For the same reason, the caster fails for a type with +several ID classes, such as `UserId|PostId`. There's no way to choose the +right one. + +Register `UuidValueTypeCaster` as shown in the [Registering a type +caster](#registering-a-type-caster) section, including the [form model +configuration](#registering-for-form-models) if you use Yii Form Model. + +### Using the value objects + +Now any class that's populated by the hydrator can declare ID value objects +directly. + +#### Hydrator + +The same string becomes a different value object depending on the type of +the property: + +```php +use App\Post\PostId; +use App\User\UserId; +use Yiisoft\Hydrator\HydratorInterface; + +final class CommentFilter +{ + public ?UserId $authorId = null; + public ?PostId $postId = null; +} + +/** @var HydratorInterface $hydrator */ +$filter = $hydrator->create(CommentFilter::class, [ + 'authorId' => '0192f2a4-7a4b-7c3e-9a1b-3f5c8d2e6a10', + 'postId' => '0192f2a4-7a4b-7c3e-9a1b-3f5c8d2e6a10', +]); + +// $filter->authorId is UserId, $filter->postId is PostId. +// $filter->authorId->equals($filter->postId) returns false. +``` + +#### Request input + +The [Yii Input HTTP](https://github.com/yiisoft/input-http) package uses the +hydrator to fill request input objects, so the same type caster works for +query parameters, request body, and route arguments. The `RouteArgument` +attribute comes from [Yii Router](https://github.com/yiisoft/router). Extend +`AbstractInput` to get the input validated after hydration: + +```php +getValidationResult()->isValid()) { + // Return an error response. + } + + // $input->id is PostId, $input->authorId is UserId. + // ... + } +} +``` + +#### Form model + +`FormHydrator` from [Yii Form Model](https://github.com/yiisoft/form-model) +populates form models. Once you [register the caster for form +models](#registering-for-form-models), you can declare form properties as +value objects too: + +```php +formHydrator->populateFromPostAndValidate($form, $request)) { + // $form->authorId is UserId. + // ... + } + + // ... + } +} +``` + +### Null and invalid values + +Here is what happens with a property declared as `?UserId` for different +input values: + +| Input value | Handled by | Property value | +|------------------------------------------|------------------------|----------------------------------| +| `'0192f2a4-7a4b-7c3e-9a1b-3f5c8d2e6a10'` | `UuidValueTypeCaster` | `UserId` instance | +| `null` | `PhpNativeTypeCaster` | `null` | +| `'not-a-uuid'` | none, all casters fail | default value, `null` in example | + +The last row is the important one: the hydrator doesn't report the malformed +value. With the `Required` rule, validation catches it with the "cannot be +blank" error. See the [request input](#request-input) and [form +model](#form-model) examples. But if the property is optional, an invalid +UUID is silently turned into `null` and is indistinguishable from a missing +value. If that's not acceptable, keep the raw value for validation: declare +the property as `string`, validate its format, and convert it to the value +object after validation. + +## When to use a type caster + +A type caster fits well when the conversion: + +- depends only on the value and the declared type. +- is the same everywhere in the application. +- doesn't need I/O, such as database queries or HTTP calls. + +Value objects for IDs, emails, and money amounts match all three. Keep the +conversion in a dedicated mapper or a domain factory instead when it: + +- needs a database lookup, for example, turning an ID into a loaded entity. +- depends on context, such as the current user. +- combines several input fields into one object. +- differs between use cases. diff --git a/src/pt-BR/cookbook/custom-migration-template.md b/src/pt-BR/cookbook/custom-migration-template.md new file mode 100644 index 00000000..99675545 --- /dev/null +++ b/src/pt-BR/cookbook/custom-migration-template.md @@ -0,0 +1,136 @@ +# Using a custom migration template + +The `migrate:create` command from `yiisoft/db-migration` generates migration +classes from PHP view templates. Use a custom template when your project +wants a standard header, strict class shape, comments, helper calls, or +team-specific placeholders in every new migration. + +This recipe assumes migrations are already configured as described in the +[Database migrations](../guide/databases/db-migrations.md) guide. + +## Create a template + +Create `resources/migration-templates/migration.php`: + +```php + + +use Yiisoft\Db\Migration\MigrationBuilder; +use Yiisoft\Db\Migration\RevertibleMigrationInterface; + +final class implements RevertibleMigrationInterface +{ + public function up(MigrationBuilder $b): void + { + // Add forward migration code. + } + + public function down(MigrationBuilder $b): void + { + // Add rollback migration code. + } +} +``` + +The template is a PHP file that prints the generated migration. For the +default `create` command, the most useful variables are `$className` and +`$namespace`. + +## Configure the generator + +Create `config/common/di/migration-generator.php`: + +```php + [ + 'setTemplate()' => [ + 'create', + dirname(__DIR__, 3) . '/resources/migration-templates/migration.php', + ], + ], +]; +``` + +The `create` key changes the template used by: + +```shell +./yii migrate:create audit_log +``` + +The command asks for confirmation and then writes a migration using your +template. + +If the new DI file is not picked up, rebuild the config merge plan: + +```shell +composer yii-config-rebuild +``` + +## Configure multiple templates + +`yiisoft/db-migration` supports these template keys: + +- `create` +- `table` +- `dropTable` +- `addColumn` +- `dropColumn` +- `junction` + +To replace multiple templates at once, use `setTemplates()`: + +```php +use Yiisoft\Db\Migration\Service\Generate\CreateService; + +return [ + CreateService::class => [ + 'setTemplates()' => [[ + 'create' => dirname(__DIR__, 3) . '/resources/migration-templates/migration.php', + 'table' => dirname(__DIR__, 3) . '/resources/migration-templates/create-table.php', + 'dropTable' => dirname(__DIR__, 3) . '/resources/migration-templates/drop-table.php', + 'addColumn' => dirname(__DIR__, 3) . '/resources/migration-templates/add-column.php', + 'dropColumn' => dirname(__DIR__, 3) . '/resources/migration-templates/drop-column.php', + 'junction' => dirname(__DIR__, 3) . '/resources/migration-templates/create-junction.php', + ]], + ], +]; +``` + +For table-oriented templates, copy the corresponding file from +`vendor/yiisoft/db-migration/resources/views/` and adjust it. Those +templates receive additional variables such as `$table`, `$columns`, +`$foreignKeys`, and `$tableComment`. + +## Keep templates maintainable + +Keep generated migrations independent from current application services. A +migration may run years later, after service APIs have changed. Put stable +schema operations in the generated class and leave business logic in console +commands or application services. + +Do not edit templates under `vendor/`. Copy them into your project and +configure `CreateService` to use the copies. diff --git a/src/pt-BR/cookbook/deployment/angie-docker-proxy.md b/src/pt-BR/cookbook/deployment/angie-docker-proxy.md new file mode 100644 index 00000000..57c85ca0 --- /dev/null +++ b/src/pt-BR/cookbook/deployment/angie-docker-proxy.md @@ -0,0 +1,234 @@ +# Deploying Yii applications with Angie Docker Proxy + +[Angie Docker Proxy](https://hub.docker.com/r/angiesoftware/proxy) is a +small reverse proxy for Docker Compose projects. It runs in a separate +container alongside the applications, reads the Docker API through the +Docker socket, discovers containers using the `VIRTUAL_HOST` and +`VIRTUAL_PORT` environment variables, generates the Angie configuration, and +automatically obtains TLS certificates using ACME. + +This approach is useful when you need to run several web applications on one +server and enable HTTPS for them without manually editing the reverse proxy +configuration for each domain. + +In this example, we'll connect a containerized Yii application to Angie +Docker Proxy and configure automatic HTTPS. + +This guide assumes that your Yii application is already packaged as a Docker +image and accepts HTTP requests on port 80. Building and configuring the +application image is outside the scope of this guide. + +```mermaid +graph LR + A[Internet] --> B[Reverse Proxy: Angie] + B --> C[Yii application] + B --> D[Another application] + + subgraph Docker Compose Project + B + C + D + end +``` + +## Prerequisites + +- A server with a fresh Linux distribution. +- A domain name pointing to your server's IP address. +- Docker and Docker Compose. +- Open TCP ports `80` and `443`. +- SSH access to your server. +- Basic knowledge of Docker and command-line tools. + +## Project structure + +The example requires a single Docker Compose configuration: + +```text +yii-angie-demo/ +└── docker-compose.yml +``` + +## Configuring Docker Compose + +Create `docker-compose.yml` with the following configuration. Replace: + +- `admin@example.com` with your email address; +- `registry.example.com/yii-app:1.0.0` with your application image; +- `example-demo.example.com` with the domain pointing to your server. + +```yaml +services: + angie-proxy: + image: angiesoftware/proxy:latest + environment: + - ANGIE_ACME_EMAIL=admin@example.com + - ANGIE_ACME_URL=https://acme-v02.api.letsencrypt.org/directory + - ANGIE_RESOLVER=1.1.1.1 8.8.8.8 + - ANGIE_RESOLVER_VALID=300s + - ANGIE_PROXY_NETWORK=proxy + ports: + - "80:80" + - "443:443" + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + - angie_acme:/var/lib/angie/acme + networks: + - proxy + + yii-app: + image: registry.example.com/yii-app:1.0.0 + environment: + - VIRTUAL_HOST=example-demo.example.com + - VIRTUAL_PORT=80 + networks: + - proxy + +networks: + proxy: + name: proxy + +volumes: + angie_acme: +``` + +`VIRTUAL_HOST` is the application's public domain. + +`VIRTUAL_PORT` is the container's internal port to which Angie should proxy +requests. + +Angie Docker Proxy automatically discovers `VIRTUAL_HOST` and `VIRTUAL_PORT` +from the environment variables and issues certificates using the Angie ACME +module and Let's Encrypt. + +## Starting the services + +Start the proxy and application containers: + +```bash +docker compose up -d +``` + +## Adding another application + +To expose another application, add it to `services` in `docker-compose.yml` +and attach it to the `proxy` network: + +```yaml +services: + second-app: + image: traefik/whoami + environment: + - VIRTUAL_HOST=example-demo2.example.com + - VIRTUAL_PORT=80 + networks: + - proxy +``` + +Apply the changes: + +```bash +docker compose up -d +``` + +## How it works + +Angie Docker Proxy monitors the Docker API and discovers containers +configured with `VIRTUAL_HOST` and `VIRTUAL_PORT`. It generates the Angie +configuration, obtains TLS certificates using ACME, and forwards incoming +requests to the corresponding containers through the shared Docker network. + +When containers are added, removed, or updated, the proxy regenerates its +configuration and performs a graceful reload. Existing connections continue +to be handled while the updated configuration is applied. + +For configuration options and implementation details, see the [Angie Docker +Proxy documentation](https://hub.docker.com/r/angiesoftware/proxy). + +## Verification + +Check the containers: + +```bash +docker compose ps +``` + +Check the HTTP redirect: + +```bash +curl -I http://example-demo.example.com/ +``` + +Expected result: + +```text +HTTP/1.1 301 Moved Permanently +Location: https://example-demo.example.com/ +``` + +Check HTTPS: + +```bash +curl -I https://example-demo.example.com/ +``` + +Expected result: + +```text +HTTP/1.1 200 OK +Server: Angie/... +``` + +Check the certificate: + +```bash +echo | openssl s_client \ + -connect example-demo.example.com:443 \ + -servername example-demo.example.com 2>/dev/null \ + | openssl x509 -noout -issuer -subject -dates +``` + +Expected issuer: + +```text +Let's Encrypt +``` + + +## Logs + +Proxy logs: + +```bash +docker compose logs -f angie-proxy +``` + +## Stopping the services + +Stop the services: + +```bash +docker compose down +``` + +Stop the services and remove the certificates: + +```bash +docker compose down -v +``` + +## Limitations + +This setup is intended for Docker Compose. Kubernetes doesn't expose +workloads through the Docker API and requires an Ingress or Gateway API +controller. Docker Swarm also uses the Docker API, but Swarm deployment +isn't covered in this guide. + +## For more information + +- [Angie Docker Proxy + documentation](https://hub.docker.com/r/angiesoftware/proxy) +- [Yii Application Template](https://github.com/yiisoft/app) +- [Docker in Yii Application + Templates](https://yiisoft.github.io/docs/guide/tutorial/docker.html) +- [Docker Compose documentation](https://docs.docker.com/compose/) diff --git a/src/pt-BR/cookbook/deployment/autoscaling.md b/src/pt-BR/cookbook/deployment/autoscaling.md new file mode 100644 index 00000000..4ba2993f --- /dev/null +++ b/src/pt-BR/cookbook/deployment/autoscaling.md @@ -0,0 +1,168 @@ +# Configuring an application for autoscaling + +Autoscaling works when any application instance can handle any request and +can be added or removed without special local state. In Yii applications +this mostly means keeping runtime state outside the container or VM, making +health checks cheap, and running migrations and workers separately from web +replicas. + +## Keep web instances stateless + +Do not store user-visible state on the local filesystem of a web +instance. Local files disappear when an instance is replaced and are not +visible to other replicas. + +Move these resources to shared services: + +- Sessions: use a shared session handler when users can move between + replicas. See [Sessions](../../guide/runtime/sessions.md) and prefer + closing sessions early. +- Cache: use Redis, Memcached, database, or another shared PSR-16 cache + backend for data that must be consistent across replicas. See [Data + caching](../../guide/caching/data.md). +- Uploads: store files in object storage, a shared volume, or a service + dedicated to file storage. Local `runtime` or `public/uploads` directories + are safe only for temporary files. +- Generated assets: build them into the image or publish them to shared + storage/CDN during deployment. +- Logs: write to stdout/stderr or a central log target. Do not depend on + files inside a short-lived instance. + +Sticky sessions can reduce immediate pressure, but they are not a substitute +for shared state. A replacement instance or deployment rollout still breaks +local session and upload storage. + +## Add health endpoints + +Use a cheap liveness endpoint for the load balancer or orchestrator: + +```php +responseFactory->createResponse(Status::NO_CONTENT); + } +} +``` + +Register it in `config/common/routes.php`: + +```php +use App\Web\Health\HealthCheckAction; +use Yiisoft\Router\Route; + +return [ + // ... + Route::get('/healthz') + ->action(HealthCheckAction::class) + ->name('healthz'), +]; +``` + +Keep this endpoint independent from the database and external APIs. It +should answer whether the PHP process can accept requests, not whether every +dependency is healthy. + +If your platform supports readiness checks, add a separate endpoint such as +`/readyz` for dependencies that must be available before routing traffic to +a new instance. Keep it bounded with short timeouts. A slow readiness check +can make a traffic spike worse. + +## Configure runtime paths + +The `runtime` directory should contain disposable process-local files only: +logs before shipping, cache files that can be rebuilt, temporary upload +chunks, locks scoped to one instance, and debug artifacts. + +For autoscaled deployments: + +- mount `runtime` as an instance-local writable volume or create it during + image startup; +- do not store permanent uploaded files in `runtime`; +- do not use local file locks for jobs that must be unique across all + replicas; +- clear or ignore local runtime cache during rollouts. + +When a command or worker must be unique globally, use a database lock, Redis +lock, queue semantics, or run it as a single scheduled job outside the web +autoscaling group. + +## Run migrations once + +Do not run `./yii migrate` from every web instance during startup. Multiple +replicas starting at the same time can compete for locks, slow down boot, or +partially deploy incompatible schema. + +Run migrations from one deployment job or a dedicated console container +before or during rollout: + +```shell +APP_ENV=prod php ./yii migrate --no-interaction +``` + +For zero-downtime deployments, use an expand-and-contract migration +flow. See [Applying migrations during rolling +updates](rolling-update-migrations.md). + +## Separate web, workers, and scheduled jobs + +Scale web replicas for request traffic. Scale queue workers for queue depth +or processing latency. Run scheduled jobs from one scheduler, not from every +web replica. + +Use the same application image when practical, but different entry points: + +```shell +php ./yii queue:listen +php ./yii app:send-digests --no-interaction +``` + +Make workers and scheduled commands idempotent. A deployment may stop a +worker after it started processing a message, and the queue may deliver it +again. + +## Use environment-specific configuration + +Keep secrets and per-environment values out of the image: + +- database DSN, username, and password; +- cache/session backend addresses; +- cookie validation keys and encryption keys; +- mail, queue, and object-storage credentials; +- public base URL and trusted proxy settings. + +Load them through environment variables or environment-specific Yii config +files. Every replica of the same release should receive the same +configuration values, except for platform-provided instance metadata. + +## Capacity checklist + +Before enabling autoscaling, verify that: + +- a request can be served correctly after the previous request went to + another replica; +- login and flash messages work without sticky sessions; +- uploaded files remain available after the handling instance is removed; +- cache misses on one instance do not corrupt or hide data on another + instance; +- migrations are run by exactly one deployment step; +- background workers and scheduled commands are not multiplied accidentally; +- health checks are fast and do not overload the database; +- logs and metrics identify the application version and instance; +- shutdown is graceful enough for your web server and queue worker timeouts. diff --git a/src/pt-BR/cookbook/deployment/docker-swarm-caddy.md b/src/pt-BR/cookbook/deployment/docker-swarm-caddy.md new file mode 100644 index 00000000..cd105c0c --- /dev/null +++ b/src/pt-BR/cookbook/deployment/docker-swarm-caddy.md @@ -0,0 +1,591 @@ +# Deploying Yii applications to Docker Swarm and Caddy + +This guide walks you through deploying a Yii application to [Docker +Swarm](https://docs.docker.com/engine/swarm/) starting from a blank server, +using [Caddy](https://caddyserver.com/) as a reverse proxy and deploying +from a container registry ([Forgejo](https://forgejo.org/) or +[Gitea](https://about.gitea.com/)). + +```mermaid +graph LR + A[Internet] --> B[Reverse Proxy: Caddy] + B --> C[app1.example.com] + B --> D[app2.example.com] + + subgraph Docker Swarm Cluster + B + C + D + end +``` + +## Prerequisites + +- A server with a fresh installation of a Linux distribution (Ubuntu 22.04 + LTS or later recommended) +- A domain name pointing to your server's IP address +- SSH access to your server +- Basic knowledge of Docker and command-line tools + +## Server preparation + +### Install Docker + +For installation instructions, see the [official Docker +documentation](https://docs.docker.com/engine/install/ubuntu/). + +### Initialize Docker Swarm + +Initialize your server as a Docker Swarm manager: + +```bash +docker swarm init --advertise-addr +``` + +Replace `` with your server's public IP address. + +### Set up the reverse proxy network + +Create a dedicated overlay network for reverse proxy to communicate with +your services: + +```bash +docker network create --driver=overlay reverse_proxy_public +``` + +## Setting up Caddy as reverse proxy + +To deploy Caddy as reverse proxy create a file `caddy-stack.yml`: + +```yaml +services: + caddy: + image: lucaslorentz/caddy-docker-proxy:ci-alpine + ports: + - "80:80" + - "443:443" + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - caddy_data:/data + networks: + - reverse_proxy_public + +volumes: + caddy_data: + +networks: + reverse_proxy_public: + external: true +``` + +Deploy Caddy: + +```bash +docker stack deploy -c caddy-stack.yml caddy +``` + +Caddy automatically discovers services with Caddy labels and sets up HTTPS +using Let's Encrypt. Yii3 application templates are using Caddy labels by +default: + +```yaml +deploy: + labels: + - caddy: ${PROD_HOST:-app.example.com} + - caddy.reverse_proxy: "{{upstreams 80}}" +``` + +> [!IMPORTANT] +> Make sure your domain DNS records are configured and pointing to your server before deploying services with +> Caddy labels, as Let's Encrypt requires domain validation. + +## Setting up a container registry + +You need a container registry to store your Docker images. Choose one of the +following options. + +### Option 1: Using Forgejo + +To deploy Forgejo create a file `forgejo-stack.yml`: + +```yaml +services: + forgejo: + image: codeberg.org/forgejo/forgejo:1.21 + ports: + - "3000:3000" + volumes: + - forgejo_data:/data + networks: + - reverse_proxy_public + deploy: + labels: + - "caddy=git.example.com" + - "caddy.reverse_proxy={{upstreams 3000}}" + +volumes: + forgejo_data: + +networks: + reverse_proxy_public: + external: true +``` + +Deploy Forgejo: + +```bash +docker stack deploy -c forgejo-stack.yml forgejo +``` + +Replace `git.example.com` with your desired subdomain. + +After deployment, access Forgejo at `https://git.example.com` and complete +the initial setup. Make sure to enable the container registry in the +settings. + +### Option 2: Using Gitea + +To deploy Gitea create a file `gitea-stack.yml`: + +```yaml +services: + gitea: + image: gitea/gitea:latest + ports: + - "3000:3000" + volumes: + - gitea_data:/data + networks: + - reverse_proxy_public + deploy: + labels: + - "caddy=git.example.com" + - "caddy.reverse_proxy={{upstreams 3000}}" + +volumes: + gitea_data: + +networks: + reverse_proxy_public: + external: true +``` + +Deploy Gitea: + +```bash +docker stack deploy -c gitea-stack.yml gitea +``` + +Replace `git.example.com` with your desired subdomain. + +After deployment, access Gitea at `https://git.example.com` and complete the +initial setup. Make sure to enable the container registry in the settings. + +## Configuring your Yii application + +### Update the Makefile configuration + +The [Yii application template](https://github.com/yiisoft/app) includes a +Makefile with deployment commands. Update the `docker/.env` file in your +project: + +```bash +STACK_NAME=myapp + +# +# Production +# + +PROD_HOST=app.example.com +PROD_SSH="ssh://user@your-server-ip" + +IMAGE=git.example.com/username/myapp +IMAGE_TAG=latest +``` + +Replace the values: - `STACK_NAME`: A unique name for your application stack +- `PROD_HOST`: The domain name where your app will be accessible - +`PROD_SSH`: SSH connection string to your server (format: `ssh://user@host`) +- `IMAGE`: Full path to your container image in the registry - `IMAGE_TAG`: +Image tag, typically `latest` or a version number + +### Configure the production environment + +Update `docker/prod/.env` with your production environment variables: + +```bash +APP_ENV=prod +YII_DEBUG=false +YII_ENV=prod + +# Database configuration +DB_HOST=db +DB_NAME=myapp +DB_USER=myapp +DB_PASSWORD=secure_password_here + +# Add other environment-specific variables +``` + +> [!WARNING] +> Never commit sensitive credentials to version control. Use `docker/prod/override.env` for sensitive values and add it to `.gitignore`. + +### Review the production Docker Compose configuration + +The default `docker/prod/compose.yml` includes: + +```yaml +services: + app: + image: ${IMAGE}:${IMAGE_TAG} + networks: + - reverse_proxy_public + volumes: + - runtime:/app/runtime + - caddy_data:/data + - caddy_config:/config + env_file: + - path: ./prod/.env + - path: ./prod/override.env + required: false\ + environment: + CADDY_EXTRA_CONFIG: 'auto_https off' + deploy: + replicas: 2 + update_config: + delay: 10s + parallelism: 1 + order: start-first + failure_action: rollback + monitor: 10s + rollback_config: + parallelism: 0 + order: stop-first + restart_policy: + condition: on-failure + delay: 5s + max_attempts: 3 + window: 120s + labels: + caddy: ${PROD_HOST:-app.example.com} + caddy.reverse_proxy: "{{upstreams 80}}" +``` + +This configuration: +- Runs 2 replicas for high availability +- Uses a rolling update strategy with automatic rollback on failure +- Configures `labels` for automatic HTTPS on the reverse proxy +- Disables obtaining of HTTPs certificates on the container itself + since proxy communicates with the container via HTTP. That is `auto_https off`. + +If you need a database, add it to the stack: + +```yaml +services: + app: + # ... existing configuration ... + + db: + image: postgres:18-alpine + environment: + POSTGRES_DB: myapp + POSTGRES_USER: myapp + POSTGRES_PASSWORD_FILE: /run/secrets/db_password + POSTGRES_INITDB_ARGS: "--locale-provider=icu --icu-locale=und --encoding=UTF8" + volumes: + - db_data:/var/lib/postgresql + networks: + - reverse_proxy_public + deploy: + placement: + constraints: + - node.role == manager + secrets: + - db_password + +volumes: + runtime: + db_data: + +secrets: + db_password: + external: true +``` + +Create the database password secret on the server: + +```bash +echo "your_secure_password" | docker secret create db_password - +``` + +## Building and pushing the image + +### Set up Docker login on your local machine + +Configure Docker to authenticate with your container registry: + +```bash +docker login git.example.com +``` + +Enter your username and password when prompted. + +### Build the production image + +Use the Makefile to build your production image: + +```bash +make prod-build +``` + +This runs the command defined in the Makefile: + +```bash +docker build --file docker/Dockerfile --target prod --pull -t ${IMAGE}:${IMAGE_TAG} . +``` + +The Dockerfile uses a multi-stage build: 1. Installs Composer dependencies +in a builder stage 2. Creates a minimal production image with only the +necessary files 3. Runs as a non-root user (`www-data`) + +### Push the image to the registry + +Push your built image to the container registry: + +```bash +make prod-push +``` + +This executes: + +```bash +docker push ${IMAGE}:${IMAGE_TAG} +``` + +## Deploying to Docker Swarm + +### Configure SSH access + +Set up SSH key-based authentication to your server: + +```bash +# Generate SSH key (if you don't have one) +ssh-keygen -t ed25519 -C "your_email@example.com" + +# Copy the key to your server +ssh-copy-id user@your-server-ip + +# Add the SSH host to your SSH config (~/.ssh/config) +cat >> ~/.ssh/config << EOF +Host docker-web + HostName your-server-ip + User user + IdentityFile ~/.ssh/id_ed25519 +EOF +``` + +### Set up Docker context + +Create a Docker context for remote deployment: + +```bash +docker context create swarm-prod --docker "host=ssh://docker-web" +``` + +Alternatively, configure the `DOCKER_HOST` environment variable: + +```bash +export DOCKER_HOST=ssh://docker-web +``` + +### Deploy the application + +Deploy your application stack to Docker Swarm: + +```bash +make prod-deploy +``` + +This executes: + +```bash +docker -H ${PROD_SSH} stack deploy --prune --detach=false --with-registry-auth -c docker/compose.yml -c docker/prod/compose.yml ${STACK_NAME} +``` + +The `--with-registry-auth` flag ensures the Swarm nodes can pull images from +your private registry. + +### Verify the deployment + +Check the status of your services: + +```bash +docker -H ssh://docker-web service ls +docker -H ssh://docker-web service ps ${STACK_NAME}_app +``` + +View logs: + +```bash +docker -H ssh://docker-web service logs ${STACK_NAME}_app +``` + +## Monitoring and maintenance + +### View service logs + +```bash +# View all logs +docker -H ssh://docker-web service logs -f ${STACK_NAME}_app + +# View logs from the last 100 lines +docker -H ssh://docker-web service logs --tail 100 ${STACK_NAME}_app + +# View logs with timestamps +docker -H ssh://docker-web service logs -t ${STACK_NAME}_app +``` + +### Scale the application + +Adjust the number of replicas: + +```bash +docker -H ssh://docker-web service scale ${STACK_NAME}_app=3 +``` + +Or update the `replicas` value in `docker/prod/compose.yml` and redeploy. + +### Resource limits + +Add resource limits to prevent containers from consuming all server +resources. Update `docker/prod/compose.yml`: + +```yaml +services: + app: + # ... existing configuration ... + deploy: + resources: + limits: + cpus: '0.5' + memory: 512M + reservations: + cpus: '0.25' + memory: 256M +``` + +## Security considerations + +### Use Docker secrets for sensitive data + +Instead of environment variables, use Docker secrets for sensitive +information: + +```bash +# Create secrets +echo "database_password" | docker secret create db_password - +echo "api_key" | docker secret create api_key - +``` + +Update `docker/prod/compose.yml`: + +```yaml +services: + app: + secrets: + - db_password + - api_key + +secrets: + db_password: + external: true + api_key: + external: true +``` + +Access secrets in your application at `/run/secrets/secret_name`. + +### Set up a firewall + +Configure UFW (Uncomplicated Firewall) on your server: + +```bash +# Allow SSH +sudo ufw allow 22/tcp + +# Allow HTTP and HTTPS +sudo ufw allow 80/tcp +sudo ufw allow 443/tcp + +# Allow Docker Swarm ports (if you plan to add more nodes) +sudo ufw allow 2377/tcp +sudo ufw allow 7946/tcp +sudo ufw allow 7946/udp +sudo ufw allow 4789/udp + +# Enable the firewall +sudo ufw enable +``` + +### Keep the system updated + +Regularly update your server and Docker: + +```bash +# Update system packages +sudo apt-get update && sudo apt-get upgrade -y + +# Update Docker images +docker -H ssh://docker-web service update --image ${IMAGE}:${IMAGE_TAG} ${STACK_NAME}_app +``` + +## Troubleshooting + +### Service won't start + +Check service events and logs: + +```bash +docker -H ssh://docker-web service ps ${STACK_NAME}_app --no-trunc +docker -H ssh://docker-web service logs ${STACK_NAME}_app +``` + +Common issues: - **Image pull errors**: Verify registry authentication with +`docker -H ssh://docker-web login` - **Port conflicts**: Ensure no other +services are using ports 80/443 - **Resource constraints**: Check available +resources with `docker -H ssh://docker-web node ls` + +### SSL certificate issues + +If Caddy can't obtain certificates: - Verify DNS is pointing to your server +- Check that ports 80 and 443 are accessible from the internet - Ensure the +email in the Let's Encrypt configuration is valid - Check logs: `docker -H +ssh://docker-web service logs caddy` + +### Container registry connection issues + +Test registry connectivity: + +```bash +# From your local machine +docker pull git.example.com/username/myapp:latest + +# From the server +docker -H ssh://docker-web pull git.example.com/username/myapp:latest +``` + +## Resumo + +You've successfully deployed a Yii application to Docker Swarm with: - A +container registry (Forgejo or Gitea) - Automatic HTTPS via Caddy - +Zero-downtime deployments with rolling updates - High availability with +multiple replicas + +The Makefile commands simplify the deployment workflow: - `make prod-build` +- Build the production image - `make prod-push` - Push to the registry - +`make prod-deploy` - Deploy to Docker Swarm + +For more information, see: - [Yii Application +Template](https://github.com/yiisoft/app) - [Docker Swarm +Documentation](https://docs.docker.com/engine/swarm/) - [Caddy Docker +Proxy](https://github.com/lucaslorentz/caddy-docker-proxy) diff --git a/src/pt-BR/cookbook/deployment/docker-swarm-traefik.md b/src/pt-BR/cookbook/deployment/docker-swarm-traefik.md new file mode 100644 index 00000000..f5c725de --- /dev/null +++ b/src/pt-BR/cookbook/deployment/docker-swarm-traefik.md @@ -0,0 +1,601 @@ +# Deploying Yii applications to Docker Swarm and Traefik + +This guide walks you through deploying a Yii application to [Docker +Swarm](https://docs.docker.com/engine/swarm/) starting from a blank server, +using [Traefik](https://traefik.io/traefik) as a reverse proxy and deploying +from a container registry ([Forgejo](https://forgejo.org/) or +[Gitea](https://about.gitea.com/)). + +```mermaid +graph LR + A[Internet] --> B[Reverse Proxy: Traefik] + B --> C[app1.example.com] + B --> D[app2.example.com] + + subgraph Docker Swarm Cluster + B + C + D + end +``` + +## Prerequisites + +- A server with a fresh installation of a Linux distribution (Ubuntu 22.04 + LTS or later recommended) +- A domain name pointing to your server's IP address +- SSH access to your server +- Basic knowledge of Docker and command-line tools + +## Server preparation + +### Install Docker + +For installation instructions, see the [official Docker +documentation](https://docs.docker.com/engine/install/ubuntu/). + +### Initialize Docker Swarm + +Initialize your server as a Docker Swarm manager: + +```bash +docker swarm init --advertise-addr +``` + +Replace `` with your server's public IP address. + +### Set up the reverse proxy network + +Create a dedicated overlay network for reverse proxy to communicate with +your services: + +```bash +docker network create --driver=overlay reverse_proxy_public +``` + +## Setting up Traefik as reverse proxy + +To deploy Traefik as reverse proxy create a file `traefik-stack.yml`: + +```yaml +services: + traefik: + image: traefik:v2.10 + command: + - "--api.insecure=true" + - "--providers.docker=true" + - "--providers.docker.swarmMode=true" + - "--providers.docker.exposedbydefault=false" + - "--entrypoints.web.address=:80" + - "--entrypoints.websecure.address=:443" + - "--certificatesresolvers.letsencrypt.acme.tlschallenge=true" + - "--certificatesresolvers.letsencrypt.acme.email=admin@example.com" + - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json" + ports: + - "80:80" + - "443:443" + - "8080:8080" + volumes: + - "/var/run/docker.sock:/var/run/docker.sock:ro" + - "traefik_certificates:/letsencrypt" + networks: + - reverse_proxy_public + deploy: + placement: + constraints: + - node.role == manager + +volumes: + traefik_certificates: + +networks: + reverse_proxy_public: + external: true +``` + +Deploy Traefik: + +```bash +docker stack deploy -c traefik-stack.yml traefik +``` + +## Setting up a container registry + +You need a container registry to store your Docker images. Choose one of the +following options. + +### Option 1: Using Forgejo + +To deploy Forgejo create a file `forgejo-stack.yml`: + +```yaml +services: + forgejo: + image: codeberg.org/forgejo/forgejo:1.21 + ports: + - "3000:3000" + volumes: + - forgejo_data:/data + networks: + - reverse_proxy_public + deploy: + labels: + - "traefik.enable=true" + - "traefik.http.routers.app.rule=Host(`git.example.com`)" + - "traefik.http.routers.app.entrypoints=websecure" + - "traefik.http.routers.app.tls.certresolver=letsencrypt" + - "traefik.http.services.app.loadbalancer.server.port=3000" + +volumes: + forgejo_data: + +networks: + reverse_proxy_public: + external: true +``` + +Deploy Forgejo: + +```bash +docker stack deploy -c forgejo-stack.yml forgejo +``` + +Replace `git.example.com` with your desired subdomain. + +After deployment, access Forgejo at `https://git.example.com` and complete +the initial setup. Make sure to enable the container registry in the +settings. + +### Option 2: Using Gitea + +To deploy Gitea create a file `gitea-stack.yml`: + +```yaml +services: + gitea: + image: gitea/gitea:latest + ports: + - "3000:3000" + volumes: + - gitea_data:/data + networks: + - reverse_proxy_public + deploy: + labels: + - "traefik.enable=true" + - "traefik.http.routers.app.rule=Host(`git.example.com`)" + - "traefik.http.routers.app.entrypoints=websecure" + - "traefik.http.routers.app.tls.certresolver=letsencrypt" + - "traefik.http.services.app.loadbalancer.server.port=3000" + +volumes: + gitea_data: + +networks: + reverse_proxy_public: + external: true +``` + +Deploy Gitea: + +```bash +docker stack deploy -c gitea-stack.yml gitea +``` + +Replace `git.example.com` with your desired subdomain. + +After deployment, access Gitea at `https://git.example.com` and complete the +initial setup. Make sure to enable the container registry in the settings. + +## Configuring your Yii application + +### Update the Makefile configuration + +The [Yii application template](https://github.com/yiisoft/app) includes a +Makefile with deployment commands. Update the `docker/.env` file in your +project: + +```bash +STACK_NAME=myapp + +# +# Production +# + +PROD_HOST=app.example.com +PROD_SSH="ssh://user@your-server-ip" + +IMAGE=git.example.com/username/myapp +IMAGE_TAG=latest +``` + +Replace the values: - `STACK_NAME`: A unique name for your application stack +- `PROD_HOST`: The domain name where your app will be accessible - +`PROD_SSH`: SSH connection string to your server (format: `ssh://user@host`) +- `IMAGE`: Full path to your container image in the registry - `IMAGE_TAG`: +Image tag, typically `latest` or a version number + +### Configure the production environment + +Update `docker/prod/.env` with your production environment variables: + +```bash +APP_ENV=prod +YII_DEBUG=false +YII_ENV=prod + +# Database configuration +DB_HOST=db +DB_NAME=myapp +DB_USER=myapp +DB_PASSWORD=secure_password_here + +# Add other environment-specific variables +``` + +> [!WARNING] +> Never commit sensitive credentials to version control. Use `docker/prod/override.env` for sensitive values and add it to `.gitignore`. + +### Review the production Docker Compose configuration + +When using Traefik, you'll need to modify the Yii application's +`docker/prod/compose.yml` to use Traefik labels instead of Caddy labels: + +```yaml +services: + app: + image: ${IMAGE}:${IMAGE_TAG} + networks: + - reverse_proxy_public + volumes: + - runtime:/app/runtime + - caddy_data:/data + - caddy_config:/config + env_file: + - path: ./prod/.env + - path: ./prod/override.env + required: false\ + environment: + CADDY_EXTRA_CONFIG: 'auto_https off' + deploy: + replicas: 2 + update_config: + delay: 10s + parallelism: 1 + order: start-first + failure_action: rollback + monitor: 10s + rollback_config: + parallelism: 0 + order: stop-first + restart_policy: + condition: on-failure + delay: 5s + max_attempts: 3 + window: 120s + labels: + - "traefik.enable=true" + - "traefik.http.routers.app.rule=Host(`${PROD_HOST:-app.example.com}`)" + - "traefik.http.routers.app.entrypoints=websecure" + - "traefik.http.routers.app.tls.certresolver=letsencrypt" + - "traefik.http.services.app.loadbalancer.server.port=80" +``` + +This configuration: +- Runs 2 replicas for high availability +- Uses a rolling update strategy with automatic rollback on failure +- Configures `labels` for automatic HTTPS on the reverse proxy +- Disables obtaining of HTTPs certificates on the container itself + since proxy communicates with the container via HTTP. That is `auto_https off`. + +If you need a database, add it to the stack: + +```yaml +services: + app: + # ... existing configuration ... + + db: + image: postgres:18-alpine + environment: + POSTGRES_DB: myapp + POSTGRES_USER: myapp + POSTGRES_PASSWORD_FILE: /run/secrets/db_password + POSTGRES_INITDB_ARGS: "--locale-provider=icu --icu-locale=und --encoding=UTF8" + volumes: + - db_data:/var/lib/postgresql + networks: + - reverse_proxy_public + deploy: + placement: + constraints: + - node.role == manager + secrets: + - db_password + +volumes: + runtime: + db_data: + +secrets: + db_password: + external: true +``` + +Create the database password secret on the server: + +```bash +echo "your_secure_password" | docker secret create db_password - +``` + +## Building and pushing the image + +### Set up Docker login on your local machine + +Configure Docker to authenticate with your container registry: + +```bash +docker login git.example.com +``` + +Enter your username and password when prompted. + +### Build the production image + +Use the Makefile to build your production image: + +```bash +make prod-build +``` + +This runs the command defined in the Makefile: + +```bash +docker build --file docker/Dockerfile --target prod --pull -t ${IMAGE}:${IMAGE_TAG} . +``` + +The Dockerfile uses a multi-stage build: 1. Installs Composer dependencies +in a builder stage 2. Creates a minimal production image with only the +necessary files 3. Runs as a non-root user (`www-data`) + +### Push the image to the registry + +Push your built image to the container registry: + +```bash +make prod-push +``` + +This executes: + +```bash +docker push ${IMAGE}:${IMAGE_TAG} +``` + +## Deploying to Docker Swarm + +### Configure SSH access + +Set up SSH key-based authentication to your server: + +```bash +# Generate SSH key (if you don't have one) +ssh-keygen -t ed25519 -C "your_email@example.com" + +# Copy the key to your server +ssh-copy-id user@your-server-ip + +# Add the SSH host to your SSH config (~/.ssh/config) +cat >> ~/.ssh/config << EOF +Host docker-web + HostName your-server-ip + User user + IdentityFile ~/.ssh/id_ed25519 +EOF +``` + +### Set up Docker context + +Create a Docker context for remote deployment: + +```bash +docker context create swarm-prod --docker "host=ssh://docker-web" +``` + +Alternatively, configure the `DOCKER_HOST` environment variable: + +```bash +export DOCKER_HOST=ssh://docker-web +``` + +### Deploy the application + +Deploy your application stack to Docker Swarm: + +```bash +make prod-deploy +``` + +This executes: + +```bash +docker -H ${PROD_SSH} stack deploy --prune --detach=false --with-registry-auth -c docker/compose.yml -c docker/prod/compose.yml ${STACK_NAME} +``` + +The `--with-registry-auth` flag ensures the Swarm nodes can pull images from +your private registry. + +### Verify the deployment + +Check the status of your services: + +```bash +docker -H ssh://docker-web service ls +docker -H ssh://docker-web service ps ${STACK_NAME}_app +``` + +View logs: + +```bash +docker -H ssh://docker-web service logs ${STACK_NAME}_app +``` + +## Monitoring and maintenance + +### View service logs + +```bash +# View all logs +docker -H ssh://docker-web service logs -f ${STACK_NAME}_app + +# View logs from the last 100 lines +docker -H ssh://docker-web service logs --tail 100 ${STACK_NAME}_app + +# View logs with timestamps +docker -H ssh://docker-web service logs -t ${STACK_NAME}_app +``` + +### Scale the application + +Adjust the number of replicas: + +```bash +docker -H ssh://docker-web service scale ${STACK_NAME}_app=3 +``` + +Or update the `replicas` value in `docker/prod/compose.yml` and redeploy. + +### Resource limits + +Add resource limits to prevent containers from consuming all server +resources. Update `docker/prod/compose.yml`: + +```yaml +services: + app: + # ... existing configuration ... + deploy: + resources: + limits: + cpus: '0.5' + memory: 512M + reservations: + cpus: '0.25' + memory: 256M +``` + +## Security considerations + +### Use Docker secrets for sensitive data + +Instead of environment variables, use Docker secrets for sensitive +information: + +```bash +# Create secrets +echo "database_password" | docker secret create db_password - +echo "api_key" | docker secret create api_key - +``` + +Update `docker/prod/compose.yml`: + +```yaml +services: + app: + secrets: + - db_password + - api_key + +secrets: + db_password: + external: true + api_key: + external: true +``` + +Access secrets in your application at `/run/secrets/secret_name`. + +### Set up a firewall + +Configure UFW (Uncomplicated Firewall) on your server: + +```bash +# Allow SSH +sudo ufw allow 22/tcp + +# Allow HTTP and HTTPS +sudo ufw allow 80/tcp +sudo ufw allow 443/tcp + +# Allow Docker Swarm ports (if you plan to add more nodes) +sudo ufw allow 2377/tcp +sudo ufw allow 7946/tcp +sudo ufw allow 7946/udp +sudo ufw allow 4789/udp + +# Enable the firewall +sudo ufw enable +``` + +### Keep the system updated + +Regularly update your server and Docker: + +```bash +# Update system packages +sudo apt-get update && sudo apt-get upgrade -y + +# Update Docker images +docker -H ssh://docker-web service update --image ${IMAGE}:${IMAGE_TAG} ${STACK_NAME}_app +``` + +## Troubleshooting + +### Service won't start + +Check service events and logs: + +```bash +docker -H ssh://docker-web service ps ${STACK_NAME}_app --no-trunc +docker -H ssh://docker-web service logs ${STACK_NAME}_app +``` + +Common issues: - **Image pull errors**: Verify registry authentication with +`docker -H ssh://docker-web login` - **Port conflicts**: Ensure no other +services are using ports 80/443 - **Resource constraints**: Check available +resources with `docker -H ssh://docker-web node ls` + +### SSL certificate issues + +If Traefik can't obtain certificates: - Verify DNS is pointing to your +server - Check that ports 80 and 443 are accessible from the internet - +Ensure the email in the Let's Encrypt configuration is valid - Check logs: +`docker -H ssh://docker-web service logs traefik_traefik` + +### Container registry connection issues + +Test registry connectivity: + +```bash +# From your local machine +docker pull git.example.com/username/myapp:latest + +# From the server +docker -H ssh://docker-web pull git.example.com/username/myapp:latest +``` + +## Resumo + +You've successfully deployed a Yii application to Docker Swarm with: - A +container registry (Forgejo or Gitea) - Automatic HTTPS via Traefik - +Zero-downtime deployments with rolling updates - High availability with +multiple replicas + +The Makefile commands simplify the deployment workflow: - `make prod-build` +- Build the production image - `make prod-push` - Push to the registry - +`make prod-deploy` - Deploy to Docker Swarm + +For more information, see: - [Yii Application +Template](https://github.com/yiisoft/app) - [Docker Swarm +Documentation](https://docs.docker.com/engine/swarm/) - [Traefik +Documentation](https://doc.traefik.io/traefik/) diff --git a/src/pt-BR/cookbook/deployment/docker-swarm.md b/src/pt-BR/cookbook/deployment/docker-swarm.md new file mode 100644 index 00000000..242ee4d3 --- /dev/null +++ b/src/pt-BR/cookbook/deployment/docker-swarm.md @@ -0,0 +1,4 @@ +# Deploying Yii applications to Docker Swarm + +- [Using Caddy](docker-swarm-caddy.md) +- [Using Traefik](docker-swarm-traefik.md) diff --git a/src/pt-BR/cookbook/deployment/rolling-update-migrations.md b/src/pt-BR/cookbook/deployment/rolling-update-migrations.md new file mode 100644 index 00000000..d857edce --- /dev/null +++ b/src/pt-BR/cookbook/deployment/rolling-update-migrations.md @@ -0,0 +1,190 @@ +# Applying migrations during rolling updates + +Rolling updates keep old and new application instances running at the same +time. This makes database changes more delicate than in a single-server +deployment: both application versions must work with the same database while +the deployment is in progress. + +The safe rule is: + +1. Apply database changes that are compatible with the current production + code. +2. Deploy code that starts using these database changes. +3. Remove obsolete database structures only after every old application + instance is gone. + +This is often called the expand and contract pattern. First expand the +schema so both versions can use it. Then move the application code. Finally +contract the schema in a later deployment. + +## Why this matters + +During a rolling update, requests may be served by different versions of the +application: + +- old code that does not know about the new schema; +- new code that expects the new schema; +- background workers that may lag behind web instances; +- scheduled commands that may run during deployment. + +If a migration drops or renames a column before all old instances stop using +it, old code fails. If code that requires a new column is deployed before +the column exists, new code fails. The migration plan must keep every +intermediate state valid. + +## Deployment flow + +Use this flow for changes that must not interrupt production traffic: + +1. Create a migration that only adds compatible schema. +2. Apply this migration to production while the current application version + is still running. +3. Deploy the new application version with a rolling update. +4. Verify that all instances and workers run the new version. +5. In a later release, apply cleanup migrations that remove old columns, + indexes, tables, or compatibility code. + +For Yii applications, run migrations with the same command you use in +regular deployments, for example: + +```shell +./yii migrate +``` + +Run migrations from a single deployment job or one dedicated console +container. Do not let every rolling application instance run migrations on +startup. + +## Adding a column + +Adding a nullable column is usually compatible with old code: + +```php +public function up(MigrationBuilder $b): void +{ + $cb = $b->columnBuilder(); + + $b->addColumn('user', 'display_name', $cb::string()); +} +``` + +Then deploy code that writes and reads `display_name`. + +If the column must eventually be required: + +1. Add it as nullable. +2. Deploy code that writes it for new and updated rows. +3. Backfill existing rows in batches. +4. Add a `NOT NULL` constraint in a later migration. + +Do not add a `NOT NULL` column without a database default while old code +still inserts rows without that column. + +## Renaming a column + +Renaming is not compatible because old code uses the old name and new code +uses the new name. Use a multi-release change instead: + +1. Add the new column. +2. Backfill it from the old column. +3. Deploy code that writes both columns and reads the new column with a + fallback to the old one. +4. Wait until all old code is gone. +5. Deploy code that uses only the new column. +6. Drop the old column in a later cleanup migration. + +The same approach works for moving data to a different table. + +## Changing a column type + +Changing a column type in place may lock the table or break either the old +or new code. Prefer a new column: + +1. Add a column with the target type. +2. Backfill it in batches. +3. Deploy code that writes both columns. +4. Deploy code that reads the new column. +5. Drop the old column after all code uses the new one. + +For small tables, an in-place type change may be acceptable. For production +tables with traffic, verify locking behavior on the exact database engine +and version before applying it. + +## Dropping columns and tables + +Dropping is a cleanup step, not the first step: + +1. Deploy code that no longer reads or writes the column or table. +2. Confirm that old application instances, workers, and scheduled commands + are stopped. +3. Confirm that no external reporting or maintenance scripts depend on it. +4. Drop it in a separate migration. + +This makes rollback safer. If you need to roll back application code before +cleanup, the old schema is still available. + +## Adding indexes and constraints + +Indexes and constraints may be logically compatible but operationally risky +because they can lock tables. + +For indexes: + +- use online index creation when the database supports it; +- for PostgreSQL, consider `CREATE INDEX CONCURRENTLY` from a migration or + command that is not wrapped in a transaction; +- for MySQL and MariaDB, check whether the operation can use online DDL for + your table and engine. + +For constraints: + +- clean invalid data before adding the constraint; +- add the constraint only after deployed code preserves it; +- for PostgreSQL, consider adding foreign keys and check constraints as `NOT + VALID`, then validating them separately. + +Keep long-running index creation and validation separate from unrelated +schema changes so it is easier to monitor and retry them. + +## Data migrations + +Data migrations that touch many rows should be safe to run while the +application is live: + +- make them idempotent so rerunning them does not corrupt data; +- process rows in small batches; +- avoid depending on current application service or entity logic because + that logic changes over time; +- prefer forward-compatible values that both old and new code can handle; +- store progress when a backfill is too large for a single migration run. + +For very large backfills, use a console command or background job after the +schema migration. The schema migration should prepare the database; the +background process should move the data gradually. + +## Reverting + +In production rolling deployments, reverting a destructive migration is +often harder than deploying a corrective migration. Treat `down()` methods +for destructive operations as a local-development convenience, not as the +main production rollback plan. + +A practical rollback plan is: + +- before cleanup, roll back code only because old schema is still present; +- after cleanup, deploy a new forward migration that restores the required + structure or compatibility; +- restore from backup only when data was actually lost and no forward repair + is possible. + +## Checklist + +Before applying a production migration, verify that: + +- the current production code works after the migration; +- the new code works before and after all instances are updated; +- old workers and scheduled commands are covered; +- inserts and updates keep required columns valid in every deployment phase; +- long-running schema operations will not block production traffic + unexpectedly; +- cleanup happens in a separate release after the rollout is complete. diff --git a/src/pt-BR/cookbook/disabling-csrf-protection.md b/src/pt-BR/cookbook/disabling-csrf-protection.md new file mode 100644 index 00000000..245fefd4 --- /dev/null +++ b/src/pt-BR/cookbook/disabling-csrf-protection.md @@ -0,0 +1,153 @@ +# Disabling CSRF protection + +## What is CSRF protection? + +Cross-Site Request Forgery (CSRF) protection is a security mechanism that +prevents malicious websites from making unauthorized requests on behalf of +authenticated users. Yii3 includes built-in CSRF protection through the +`Yiisoft\Yii\Web\Middleware\CsrfTokenMiddleware` middleware. + +For a comprehensive understanding of CSRF attacks and protection mechanisms, +see the [Security best +practices](../guide/security/best-practices.md#avoiding-csrf) section in the +main guide. + +## When to disable CSRF protection + +While CSRF protection should generally remain enabled for web applications, +there are specific scenarios where you might need to disable it: + +### When external systems cannot provide CSRF tokens + +When building APIs or handling automated requests from external systems, +CSRF protection can interfere with legitimate requests since these systems +cannot provide valid CSRF tokens: + +- **Third-party integrations**: External services cannot provide valid CSRF + tokens +- **Mobile applications**: Native mobile apps typically don't use cookies or + sessions in the same way as web browsers +- **Server-to-server communication**: API endpoints designed for + machine-to-machine communication +- **Payment processors**: PayPal, Stripe, and other payment systems send + webhook notifications +- **Version control systems**: GitHub, GitLab webhooks for CI/CD pipelines +- **Social media platforms**: Twitter, Facebook webhook notifications +- **Communication services**: Slack, Discord bot integrations + +## How to disable CSRF protection + +First, you need to remove CSRF middleware from your main application +middleware list in `config/web/di/application.php`: + +```php +return [ + Application::class => [ + '__construct()' => [ + 'dispatcher' => DynamicReference::to([ + 'class' => MiddlewareDispatcher::class, + 'withMiddlewares()' => [ + [ + ErrorCatcher::class, + SessionMiddleware::class, + CsrfTokenMiddleware::class, // <- Remove this line +``` + +Now, if you need to leave CSRF on for specific routes or route groups, you +can do so by adding the `CsrfTokenMiddleware` middleware to the router +configuration in `config/common/routes.php`. For a group that would be the +following: + +```php +return [ + Group::create() + ->middleware(CsrfTokenMiddleware::class) + ->routes( +``` + +For a single route, you can add the middleware directly to the route: + +```php +Route::methods([Method::GET, Method::POST], '/say[/{test}]') + ->action(\App\Controller\Echo\Action::class) + ->name('echo/say') + ->middleware(CsrfTokenMiddleware::class) +``` + + +## Security considerations + +When disabling CSRF protection, keep these security considerations in mind: + +### Alternative authentication methods + +For API endpoints, implement proper authentication mechanisms: + +- **API keys**: Require API keys for authentication +- **Bearer tokens**: Use JWT or similar token-based authentication +- **OAuth 2.0**: Implement OAuth 2.0 for third-party access +- **IP whitelisting**: Restrict access to known IP addresses for webhooks + +### Request validation + +Implement additional validation for requests without CSRF protection: + +- **Signature verification**: Verify webhook signatures (e.g., GitHub's + X-Hub-Signature) +- **Timestamp validation**: Check request timestamps to prevent replay + attacks +- **Rate limiting**: Implement rate limiting to prevent abuse +- **Input validation**: Strictly validate all input parameters + +### Example: Webhook signature verification + +```php +getHeaderLine('X-Webhook-Signature'); + $payload = (string) $request->getBody(); + $expectedSignature = hash_hmac('sha256', $payload, $this->webhookSecret); + + if (!hash_equals($signature, $expectedSignature)) { + throw new \RuntimeException('Invalid webhook signature'); + } + + // Process webhook payload + // ... + } +} +``` + +## Best practices + +1. **Minimize exposure**: Only disable CSRF protection where absolutely + necessary +2. **Use HTTPS**: Always use HTTPS for API endpoints and webhooks +3. **Monitor logs**: Log all requests to API endpoints for security + monitoring +4. **Regular security audits**: Periodically review your API endpoints and + their security measures +5. **Documentation**: Clearly document which endpoints have CSRF protection + disabled and why + +## Conclusion + +While CSRF protection is crucial for web applications, there are legitimate +scenarios where it needs to be disabled, particularly for external APIs and +webhooks. When disabling CSRF protection, always implement alternative +security measures and follow security best practices to maintain the overall +security of your application. + +Remember that disabling CSRF protection increases security risks, so careful +consideration and proper implementation of alternative security measures are +essential. diff --git a/src/pt-BR/cookbook/index.md b/src/pt-BR/cookbook/index.md new file mode 100644 index 00000000..06162bc6 --- /dev/null +++ b/src/pt-BR/cookbook/index.md @@ -0,0 +1,44 @@ +# Cookbook da comunidade Yii3 + +O Cookbook da comunidade Yii3 é um livro de código aberto cheio de dicas e +truques sobre o framework PHP [Yii3](https://www.yiiframework.com/). + +- A comunidade Yii escreve o cookbook. +- Membros do time principal do Yii fazem a curadoria e a edição. + +Fique à vontade para enviar seus próprios textos via pull request. Os +membros do time vão revisar, dar feedback e fazer o merge da melhor forma +possível. + +Este livro segue os [Termos da documentação do +Yii](https://www.yiiframework.com/license#docs). + +--- + +- [Prefácio](preface.md) +- [Fazendo requisições HTTP](making-http-requests.md) +- [Usando htmx para recarregar partes da + página](using-htmx-for-partial-reloads.md) +- [Desativando a proteção CSRF](disabling-csrf-protection.md) +- [Integração com o Sentry](sentry-integration.md) +- [Usando um template de migration + personalizado](custom-migration-template.md) +- [Type casters personalizados para o + hydrator](custom-hydrator-type-casters.md) +- [Usando o Yii em aplicações de + terceiros](using-yii-in-third-party-apps.md) +- [Integrações com terceiros](third-party-integrations/index.md) +- [Trabalhando no Windows](working-on-windows.md) +- [Abrindo arquivos direto no PhpStorm](opening-files-in-phpstorm.md) +- [Configurando o Xdebug](configuring-xdebug.md) +- [Configurando servidores web](configuring-webservers/general.md) +- [Estruturando o código por caso de uso com vertical + slices](organizing-code/structuring-by-use-case-with-vertical-slices.md) +- [Domínio](organizing-code/domain.md) +- [Componentes de serviço](organizing-code/service.md) +- [Deploy com Docker Swarm](deployment/docker-swarm.md) +- [Deploy de aplicações Yii com Angie Docker + Proxy](deployment/angie-docker-proxy.md) +- [Configurando uma aplicação para autoscaling](deployment/autoscaling.md) +- [Aplicando migrations durante rolling + updates](deployment/rolling-update-migrations.md) diff --git a/src/pt-BR/cookbook/making-http-requests.md b/src/pt-BR/cookbook/making-http-requests.md new file mode 100644 index 00000000..e36a4f46 --- /dev/null +++ b/src/pt-BR/cookbook/making-http-requests.md @@ -0,0 +1,208 @@ +# Making HTTP requests + +Yii doesn't include its own HTTP client implementation. Use a client that +implements [PSR-18](https://www.php-fig.org/psr/psr-18/) and depend on PSR +interfaces in your application code. + +This recipe uses [Guzzle](https://docs.guzzlephp.org/) as the HTTP +client. Guzzle provides a PSR-18 client and uses PSR-7 messages. + +## Installation + +Install Guzzle: + +```shell +composer require guzzlehttp/guzzle +``` + +The package installs the PSR HTTP interfaces and `guzzlehttp/psr7`, which +provides PSR-7 messages and PSR-17 factories. + +## Configure the container + +Create `config/common/di/http-client.php`: + +```php + [ + 'class' => Client::class, + '__construct()' => [ + 'config' => [ + 'timeout' => 10.0, + 'connect_timeout' => 3.0, + ], + ], + ], + + HttpFactory::class => HttpFactory::class, + RequestFactoryInterface::class => Reference::to(HttpFactory::class), + ResponseFactoryInterface::class => Reference::to(HttpFactory::class), + StreamFactoryInterface::class => Reference::to(HttpFactory::class), + UriFactoryInterface::class => Reference::to(HttpFactory::class), +]; +``` + +Use `ClientInterface` for sending requests and PSR-17 factories for creating +requests, streams, and URIs. + +## Send a GET request + +Inject `Psr\Http\Client\ClientInterface` and +`Psr\Http\Message\RequestFactoryInterface` into the service that talks to +the external API: + +```php + + */ + public function latest(string $owner, string $repository): array + { + $request = $this->requestFactory + ->createRequest( + 'GET', + sprintf( + 'https://api.github.com/repos/%s/%s/releases/latest', + rawurlencode($owner), + rawurlencode($repository), + ), + ) + ->withHeader('Accept', 'application/vnd.github+json'); + + try { + $response = $this->httpClient->sendRequest($request); + } catch (ClientExceptionInterface $e) { + throw new RuntimeException('GitHub request failed.', previous: $e); + } + + if ($response->getStatusCode() !== 200) { + throw new RuntimeException(sprintf( + 'GitHub returned HTTP %d.', + $response->getStatusCode(), + )); + } + + return json_decode((string) $response->getBody(), true, 512, JSON_THROW_ON_ERROR); + } +} +``` + +PSR-18 clients throw `ClientExceptionInterface` for request sending +errors. HTTP status codes such as `404` and `500` are valid responses, so +check the status code in your service. + +## Send JSON + +Use `StreamFactoryInterface` when you need a request body: + +```php + $payload + */ + public function send(array $payload): void + { + $body = $this->streamFactory->createStream(json_encode($payload, JSON_THROW_ON_ERROR)); + + $request = $this->requestFactory + ->createRequest('POST', 'https://api.example.com/webhooks') + ->withHeader('Content-Type', 'application/json') + ->withHeader('Accept', 'application/json') + ->withBody($body); + + $this->httpClient->sendRequest($request); + } +} +``` + +## Testes + +For unit tests, pass a client configured with Guzzle's `MockHandler`: + +```php + '1.0.0'], JSON_THROW_ON_ERROR)), + ]); + + $client = new Client(['handler' => HandlerStack::create($handler)]); + $factory = new HttpFactory(); + + $releaseClient = new ReleaseClient($client, $factory); + + $release = $releaseClient->latest('yiisoft', 'docs'); + + $this->assertSame('1.0.0', $release['tag_name']); + } +} +``` + +## When to use Guzzle directly + +Depend on PSR interfaces for regular application services. Use +`GuzzleHttp\Client` directly in infrastructure code that needs Guzzle-only +features such as asynchronous requests, handler stacks, or middleware. diff --git a/src/pt-BR/cookbook/opening-files-in-phpstorm.md b/src/pt-BR/cookbook/opening-files-in-phpstorm.md new file mode 100644 index 00000000..4ef72cc5 --- /dev/null +++ b/src/pt-BR/cookbook/opening-files-in-phpstorm.md @@ -0,0 +1,128 @@ +# Opening files directly in PhpStorm + +Yii error pages can show links that open stack trace files in PhpStorm at +the failing line. This is useful in local development when the error page +runs in a browser and the project is open in the IDE. + +## Check Toolbox links + +PhpStorm supports Toolbox URLs that use the `jetbrains://` protocol. To get the `project` value and path format, +right-click a project file in the Project tool window and select **Copy Path/Reference** > **Toolbox URL**. +If the copied URL has `origin`, keep the `origin` parameter and its value in your links. + +On Linux, check that Toolbox registered the protocol handler: + +```shell +xdg-mime query default x-scheme-handler/jetbrains +``` + +The command should print a Toolbox or JetBrains daemon desktop file, for +example `jetbrainsd.desktop`. + +PhpStorm should be running with the project open when you click stack trace +links. + +## Configure error trace links + +The Yii application template configures +`Yiisoft\ErrorHandler\Renderer\HtmlRenderer` in +`config/common/di/error-handler.php`. It reads a `traceLink` parameter and +uses it for stack trace file links. + +Add the parameter to `config/common/params.php`: + +```php + 'jetbrains://phpstorm/navigate/reference?project=my-app&path={file}:{line}', + // Other parameters. +]; +``` + +Replace `my-app` with the `project` value from the Toolbox URL. If the +Toolbox URL uses `origin`, keep `origin` in the link template and use its +value. + +After that, open a debug error page and click a file link in the stack +trace. + +## Map Docker paths to host paths + +When the application runs in Docker, stack traces usually contain container +paths such as `/app/src/...`. PhpStorm needs the matching host path. + +Set `APP_HOST_PATH` in `docker/dev/override.env` to the project path on the +host machine. Set `APP_IDE_PROJECT` to the `project` value from a Toolbox +URL. If the URL uses `origin`, store the `origin` value instead and use +`origin` in the final URL template: + +```dotenv +APP_HOST_PATH=/home/user/projects/my-app +APP_IDE_PROJECT=my-app +``` + +`docker/dev/override.env` is for developer-specific settings and shouldn't +be committed. See [Override env +files](../guide/tutorial/docker.md#override-env-files) for details. + +In the application parameters, expose these environment values as +`$params['app']['hostPath']` and `$params['app']['ideProject']`. + +With the default application template, `/app/src/Web/HomePage/Action.php` +will be linked as `/home/user/projects/my-app/src/Web/HomePage/Action.php`. + +## Configure `HtmlRenderer` manually + +If your application doesn't have the template's `error-handler.php` +configuration, configure `HtmlRenderer` directly: + +```php + [ + '__construct()' => [ + 'traceLink' => 'jetbrains://phpstorm/navigate/reference?project=my-app&path={file}:{line}', + ], + ], +]; +``` + +For Docker, use a closure to map the container path to the host path: + +```php + [ + '__construct()' => [ + 'traceLink' => static function (string $file, ?int $line) use ($hostPath, $project): string { + $file = preg_replace('~^/app/~', $hostPath, $file); + $path = $line === null ? $file : $file . ':' . $line; + + return str_replace( + ['{project}', '{path}'], + [$project, $path], + 'jetbrains://phpstorm/navigate/reference?project={project}&path={path}', + ); + }, + ], + ], +]; +``` diff --git a/src/pt-BR/cookbook/organizing-code/domain.md b/src/pt-BR/cookbook/organizing-code/domain.md new file mode 100644 index 00000000..6a35bb14 --- /dev/null +++ b/src/pt-BR/cookbook/organizing-code/domain.md @@ -0,0 +1,91 @@ +# Domain + +The Domain or domain model is what makes the project unique. With requirements and terminology of the problem being solved +in mind (the problem context), you build an abstraction that consists of entities, their relationships, and logic that +operates these entities. To focus on the complex part of the problem, domain is, ideally, separated from + the infrastructure part of the system (that's how to save data into a database, how to form HTTP response, etc.). + +> [!NOTE] +> Such isolation is suitable for complex systems. If your project domain is basically create/read/update/delete +> for a set of records with not much complex logic, it makes no sense to apply a complex solution to a simple problem. +> The individual concepts of domain design below could be applied separately, so make sure to check these even if your +> project isn't that complicated. + +## Bounded context + +It's nearly impossible to build a model that solves multiple problems that +aren't too complicated by itself. Therefore, it's a good practice to divide +the domain into several use-cases and have a separate model for each +use-case. Such separated models are called "bounded contexts." + +## Building blocks + +There are various building blocks that are typically used when describing +domain models. It isn't mandatory to use them all. + +### Entity + +Entity is a uniquely identifiable object such as user, product, payment, +etc. When comparing them, you're checking ID, not the attribute values. If +there are two objects with different attributes but the same ID, they're +considered being the same thing. + +### Value object + +Value object describes an object by its characteristics. For example, a +price that consists of value and currency. When comparing such objects, +you're checking actual values. If they match, an object is considered to be +the same. + +### Aggregate + +Aggregate is a set of domain objects such as entities and value objects and +additional data that could be treated as a single unit. It usually +represents a compound object from a domain model such as shop order or HR +person dossier. + +One of the components of an aggregate is called a root. The root identifies +an aggregate as a whole and should be used to access it. + +### Domain event + +An aggregate, while processed, may raise events. For example, when order is +confirmed, `OrderConfirmed` event would be risen so other parts of the +system may react on these. + +### Data transfer object + +Data transfer object or DTO is an object whose only purpose is to hold data +as it is. It's commonly used to pass data between different services. + +### Service + +Service is a class that contains a standalone operation within the context +of your domain model. See "[service components](service.md)". + +### Repository + +The repository task is to abstract away how domain objects are +obtained. These are usually separated into two parts: an interface that +stays in the domain layer and an implementation that's situated in the +infrastructure layer. In such a way, domain doesn't care how data is +obtained and saved and may be focused around the complicated business logic +instead. + +Repository is usually implemented as a service. + +### Instantiating building blocks + +Entity, value object, aggregate, and domain events aren't services and +shouldn't be instantiated through DI container. Using `new` is the way to +go with these. + +## References + +- [BoundedContext by Martin + Fowler](https://martinfowler.com/bliki/BoundedContext.html) +- [ValueObject by Martin + Fowler](https://martinfowler.com/bliki/ValueObject.html) +- [Aggregate by Marting + Fowler](https://martinfowler.com/bliki/DDD_Aggregate.html) + diff --git a/src/pt-BR/cookbook/organizing-code/service.md b/src/pt-BR/cookbook/organizing-code/service.md new file mode 100644 index 00000000..0baee5d5 --- /dev/null +++ b/src/pt-BR/cookbook/organizing-code/service.md @@ -0,0 +1,119 @@ +# Service components + +Application may get complicated, so it makes sense to extract focused parts +of business logic or infrastructure into service components. They're +typically injected into other components or action handlers. It's usually +done via autowiring: + +```php +public function actionIndex(CurrentRoute $route, MyService $myService): ResponseInterface +{ + $id = $route->getArgument('id'); + + // ... + $extraData = $myService->getExtraData($id); + + // ... +} +``` + +Yii3 doesn't technically imply any limitations on how you build services. In +general, there's no need to extend from a base class or implement a certain +interface: + +```php +final readonly class MyService +{ + public function __construct( + private ExtraDataStorage $extraDataStorage + ) + { + } + + public function getExtraData(string $id): array + { + return $this->extraDataStorage->get($id); + } +} +``` + +Services either perform a task or return data. They're created once, put +into a DI container and then could be used multiple times. Because of that, +it's a good idea to keep your services stateless that's both service itself +and any of its dependencies shouldn't hold state. You can ensure it by using +`readonly` PHP keyword at class level. + +## Service dependencies and configuration + +Services should always define all their dependencies on other services via +`__construct()`. It both allows you to use a service right away after it's +created and serves as an indicator of a service doing too much if there are +too many dependencies. + +- After the service is created, it shouldn't be re-configured in runtime. +- DI container instance usually **shouldn't** be injected as a + dependency. Prefer concrete interfaces. +- In case of complicated or "heavy" initialization, try to postpone it until + the service method is called. + +The same is valid for configuration values. They should be provided as a +constructor argument. Related values could be grouped together into value +objects. For example, database connection usually requires DSN string, +username and password. These three could be combined into Dsn class: + +```php +final readonly class Dsn +{ + public function __construct( + public string $dsn, + public string $username, + public string $password + ) + { + if (!$this->isValidDsn($dsn)) { + throw new \InvalidArgumentException('DSN provided is not valid.'); + } + } + + private function isValidDsn(string $dsn): bool + { + // check DSN validity + } +} +``` + +## Service methods + +Service method usually does something. It could be a simple thing repeated +exactly, but usually it depends on the context. For example: + +```php +final readonly class PostPersister +{ + public function __construct( + private Storage $db + ) + { + } + + public function persist(Post $post) + { + $this->db->insertOrUpdate('post', $post); + } +} +``` + +There's a service that is saving posts into permanent storage such as a +database. An object allowing communication with a concrete storage is always +the same, so it's injected using constructor while the post saved could +vary, so it's passed as a method argument. + +## Is everything a service? + +Often it makes sense to choose another class type to place your code +into. Check: + +- Repository +- Widget +- [Middleware](middleware.md) +- Entity diff --git a/src/pt-BR/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md b/src/pt-BR/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md new file mode 100644 index 00000000..8ee871aa --- /dev/null +++ b/src/pt-BR/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md @@ -0,0 +1,81 @@ +# Structuring code by use-case with vertical slices + +When building an application, it's important to organize the code in a way +that makes it easy to understand, support, and scale. One popular approach +is to structure the code by use-case with vertical slices. + +Vertical slices are self-contained pieces of functionality that cover the +entire stack, from the user interface to the data access layer. Developer +organizes each slice around a specific use case, such as creating a new user +or updating a product. + +When structuring code classically by type (such as models, views, +controllers, helpers, etc.), it can be easy to lose sight of the bigger +picture and how different pieces of code interact to support specific +features or use cases. This can lead to code duplication, tight coupling, +and poor maintainability as the application grows. + +On the other hand, structuring code by use-case makes developers focus on a +specific feature or workflow and understand how different pieces of code +work together to support that feature. This approach also helps to keep +related code together in a single directory, making it easier to navigate +and support. Vertical slicing also encourages the use of domain-driven +design concepts, such as entities, repositories, and services, which can +help to promote good separation of concerns and modularity. + +Additionally, structuring code by use-case can make it easier to test and +debug the application since use-case namespace encapsulates each feature or +workflow in its own directory with clear boundaries and well-defined +interfaces. + +Here's an example directory structure for a PHP application organized using +vertical slices: + +``` +src/ +└── Blog/ + ├── Model/ + │ ├── Comment.php + │ ├── CommentRepository.php + │ ├── Post.php + │ └── PostRepository.php + ├── Service/ + │ └── MarkdownProcessor.php + ├── UseCase/ + │ ├── CreateComment/ + │ │ ├── CreateCommentAction.php + │ │ ├── CreateCommentRequest.php + │ ├── CreatePost/ + │ │ ├── CreatePostAction.php + │ │ ├── CreatePostRequest.php + │ ├── DeleteComment/ + │ │ ├── DeleteCommentAction.php + │ │ ├── DeleteCommentRequest.php + │ ├── DeletePost/ + │ │ ├── DeletePostAction.php + │ │ ├── DeletePostRequest.php + │ ├── ListComments/ + │ │ ├── ListCommentsAction.php + │ ├── ListPosts/ + │ │ ├── ListPostsAction.php + │ ├── UpdatePost/ + │ │ ├── UpdatePostAction.php + │ │ ├── UpdatePostRequest.php + │ ├── ViewPost/ + │ │ ├── ViewPostAction.php + │ ├── Rss/ + │ │ ├── RssAction.php + | | ├── RssBuilder.php +``` + +Each vertical slice has its own directory, which has code associated with +the use case. + +The use-case subdirectories and their respective classes are organized by +type within each directory, omitting a directory if there's a single class +of the type. If code is shared between multiple use-cases, it's moved one +level up such as `Model` or `Service`. + +## References + +- [Application structure overview](../../guide/structure/overview.md) diff --git a/src/pt-BR/cookbook/preface.md b/src/pt-BR/cookbook/preface.md new file mode 100644 index 00000000..83dd31c7 --- /dev/null +++ b/src/pt-BR/cookbook/preface.md @@ -0,0 +1,37 @@ +# Preface + +O Yii é um framework PHP de alto desempenho, baseado em pacotes, para +desenvolver aplicações modernas. O nome Yii (pronuncia-se `Yee` ou `[ji:]`) +significa "simples e evolutivo" em chinês. Você também pode pensar nele +como um acrônimo de **Yes It Is**! + +O Yii é um framework genérico de programação web. Você pode usá-lo para +desenvolver todo tipo de aplicação web com PHP. Por causa da sua +arquitetura e do suporte sofisticado a cache, ele é especialmente indicado +para aplicações de grande porte, como portais, sistemas de gerenciamento de +conteúdo, e-commerce, APIs REST etc. + +With comprehensive documentation and an enthusiastic user community, Yii can +significantly reduce your development time in the long run. + +## What's the book about + +This book is for you if you're familiar with Yii3, building Yii +applications, and read the official Yii3 guide. It covers fundamentally +important development concepts, application architecture approaches, +integrating third party services with Yii3, etc. + +The book consists of individual recipes gathered from Yii experts that you +can apply in your applications. These go by topic, but you are free to read +them in any order as there is no dependency between them. + +## Prerequisites + +- You should have Yii3 installed. +- You should be familiar with the framework basics and the official guide. + +## How to participate + +If you've found any errata, wrong information, want to improve something or +have a good recipe, create an issue or make a pull request in [the book +GitHub repository](https://github.com/yiisoft/docs). diff --git a/src/pt-BR/cookbook/sentry-integration.md b/src/pt-BR/cookbook/sentry-integration.md new file mode 100644 index 00000000..b2d4685f --- /dev/null +++ b/src/pt-BR/cookbook/sentry-integration.md @@ -0,0 +1,125 @@ +# Sentry integration + +## What is Sentry + +[Sentry](https://sentry.io/) is a tool for monitoring and debugging application stability and performance. +Sentry gives you access to the events that you send there from your application. + +Most often, Sentry is used for monitoring errors (exceptions). You can +enrich errors with context to better understand the problem: - Request +arguments - Tags for grouping exceptions - Environment state: environment +variables, application state, and other global attributes + +You can find the full list of features on the official website: +https://sentry.io/welcome/ + +## Installation + +### Install the package + +Install the required package `yiisoft/yii-sentry` with the following +command: + +```shell +composer require yiisoft/yii-sentry --prefer-dist +``` + +### Install an HTTP driver + +The [`getsentry/sentry-php`](https://github.com/getsentry/sentry-php) +library requires the `php-http/httplug` package and any HTTP driver. In the +example below we’ll use the Guzzle adapter. + +> You can find the list of all adapters on [this page](https://docs.php-http.org/en/latest/clients.html#clients-adapters). + +To install the packages, run the following command: + +```shell +composer require php-http/httplug php-http/guzzle7-adapter --prefer-dist +``` + +## Configuration + +### Get and store the token + +Next, configure the application. + +First, register at [Sentry](https://sentry.io) and create a project. + +Then, in the project settings on the “General Settings” tab, find the +“Security Token” field and copy its value. + +Now put this token into the package configuration. By default, the config is located at `config/packages/yiisoft/yii-sentry/config/params.php`. +Set the copied token as the value of the array element at `yiisoft/yii-sentry` => `options` => `dsn`. Example: + +```diff +'yiisoft/yii-sentry' => [ + 'enabled' => true, + 'options' => [ +- 'dsn' => '', ++ 'dsn' => 'TOKEN', + ], +], +``` + +### Configure the HTTP client + +After installing the HTTP client, configure it. + +Create the file `config/common/sentry.php` and put the following code into +it: + +```php + \GuzzleHttp\Client::class, + \Http\Client\HttpAsyncClient::class => [ + 'class' => \Http\Adapter\Guzzle7\Client::class, + '__construct()' => [ + \Yiisoft\Factory\Definition\Reference::to(\Http\Client\HttpClient::class), + ], + ], +]; +``` + +# Integration + +### Web + +Sentry support for `web` is implemented as middleware. + +That means you only need to add `SentryMiddleware` to the global middleware +list in `config/web/application.php`: + +```diff +return [ + Yiisoft\Yii\Web\Application::class => [ + '__construct()' => [ + 'dispatcher' => DynamicReference::to(static function (Injector $injector) { + return ($injector->make(MiddlewareDispatcher::class)) + ->withMiddlewares( + [ + Router::class, + SubFolder::class, ++ SentryMiddleware::class, + ErrorCatcher::class, + ] + ); + }), + 'fallbackHandler' => Reference::to(NotFoundHandler::class), + ], + ], +]; +``` + +### Console + +Sentry supports `console` via a handler for the +[ConsoleEvents::ERROR](https://symfony.com/doc/current/components/console/events.html#the-consoleevents-error-event) +event. + +The package provides a configuration file that automatically subscribes the +application to this event. diff --git a/src/pt-BR/cookbook/third-party-integrations/index.md b/src/pt-BR/cookbook/third-party-integrations/index.md new file mode 100644 index 00000000..fea18d68 --- /dev/null +++ b/src/pt-BR/cookbook/third-party-integrations/index.md @@ -0,0 +1,18 @@ +# Third-Party Integrations + +This is a collection of community-contributed guides for integrating +third-party packages with Yii3. + +- The Yii community creates the guides. +- Membros do time principal do Yii fazem a curadoria e a edição. + +Fique à vontade para enviar seus próprios textos via pull request. Os +membros do time vão revisar, dar feedback e fazer o merge da melhor forma +possível. + +--- + +- [Symfony Messenger integration + guide](symfony-messenger-integration-guide.md) +- [Symfony Scheduler integration + guide](symfony-scheduler-integration-guide.md) diff --git a/src/pt-BR/cookbook/third-party-integrations/symfony-messenger-integration-guide.md b/src/pt-BR/cookbook/third-party-integrations/symfony-messenger-integration-guide.md new file mode 100644 index 00000000..c2de56e0 --- /dev/null +++ b/src/pt-BR/cookbook/third-party-integrations/symfony-messenger-integration-guide.md @@ -0,0 +1,352 @@ +# Symfony Messenger integration guide + +The [Symfony +Messenger](https://symfony.com/doc/current/components/messenger.html) +component helps applications send and receive messages to/from other +applications or via message queues. + +## Installation + +```shell +composer require symfony/messenger +``` + +## How to use with Yii + +### 1. Create a Message and Handler. + +```php +namespace App\Messages; + +final readonly class MyMessage +{ + public function __construct(public string $content) + { + } +} +``` + +```php +namespace App\Messages; + +use Psr\Log\LoggerInterface; + +final readonly class MyMessageHandler +{ + public function __construct(private LoggerInterface $logger) + { + } + public function __invoke(MyMessage $message): void + { + // ... + $this->logger->info("The message with the content '$message->content' has been received."); + } +} +``` + +### 2. Implement the ServiceProviderInterface. + +This instance of the ServiceProviderInterface is used to configure certain +Symfony Messenger commands. + +```php +namespace App\Services; + +use Psr\Container\ContainerInterface; +use Symfony\Contracts\Service\ServiceProviderInterface; + +final readonly class ServiceProvider implements ServiceProviderInterface +{ + /** + * @param ContainerInterface $container + * @param array $serviceMap + */ + public function __construct( + private ContainerInterface $container, + private array $serviceMap) + { + } + + /** + * @inheritDoc + */ + public function get(string $id): mixed + { + return $this->container->get($id); + } + + public function has(string $id): bool + { + return $this->container->has($id); + } + + /** + * @inheritDoc + */ + public function getProvidedServices(): array + { + return $this->serviceMap; + } +} +``` + +### 3. Configure the Symfony Messenger. + +Example uses the +[symfony/doctrine-messenger](https://packagist.org/packages/symfony/doctrine-messenger) +package for transport: + +Add the Doctrine packages to the `composer.json`: +```json +{ + // ... + "require": { + // ... + "doctrine/orm": "^3", + "doctrine/dbal": "^4", + "symfony/cache": "^7" + }, +} +``` + +Install Doctrine: +```shell +composer install +``` + +Configure the Doctrine connection in the `config/common/params.php`: +```php +return [ + // ... + 'doctrine' => [ + 'paths' => [ + ], + 'isDevMode' => false, + 'connection' => [ + 'driver' => 'pdo_mysql', + 'user' => 'site1', + 'password' => 'secret', + 'dbname' => 'site3' + ] + ], +]; +``` + +Install the Symfony Doctrine Messenger package: +```shell +composer require symfony/doctrine-messenger +``` + +Configure the Doctrine and Symfony Messenger dependencies in the +`config/common/di/application.php`: +```php +use App\Messages\MyMessage; +use App\Messages\MyMessageHandler; +use App\Services\ServiceProvider; +use Doctrine\DBAL\DriverManager; +use Doctrine\ORM\Configuration; +use Doctrine\ORM\EntityManager; +use Doctrine\ORM\EntityManagerInterface; +use Doctrine\ORM\ORMSetup; +use Doctrine\ORM\Proxy\ProxyFactory; +use Doctrine\ORM\Tools\Console\EntityManagerProvider; +use Doctrine\ORM\Tools\Console\EntityManagerProvider\SingleManagerProvider; +use Psr\Cache\CacheItemPoolInterface; +use Psr\Container\ContainerInterface; +use Psr\Log\LoggerInterface; +use Symfony\Component\Cache\Adapter\FilesystemAdapter; +use Symfony\Component\EventDispatcher\EventDispatcher; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\Messenger\Bridge\Doctrine\Transport\Connection; +use Symfony\Component\Messenger\Bridge\Doctrine\Transport\DoctrineTransport; +use Symfony\Component\Messenger\Command\ConsumeMessagesCommand; +use Symfony\Component\Messenger\Command\DebugCommand; +use Symfony\Component\Messenger\Command\FailedMessagesRemoveCommand; +use Symfony\Component\Messenger\Command\FailedMessagesRetryCommand; +use Symfony\Component\Messenger\Command\FailedMessagesShowCommand; +use Symfony\Component\Messenger\Command\SetupTransportsCommand; +use Symfony\Component\Messenger\Command\StatsCommand; +use Symfony\Component\Messenger\EventListener\StopWorkerOnRestartSignalListener; +use Symfony\Component\Messenger\Handler\HandlersLocator; +use Symfony\Component\Messenger\MessageBus; +use Symfony\Component\Messenger\Middleware\HandleMessageMiddleware; +use Symfony\Component\Messenger\Middleware\SendMessageMiddleware; +use Symfony\Component\Messenger\RoutableMessageBus; +use Symfony\Component\Messenger\Transport\Sender\SendersLocator; +use Symfony\Component\Messenger\Transport\Serialization\PhpSerializer; +use Symfony\Component\Messenger\Transport\Serialization\SerializerInterface; +use Symfony\Contracts\Service\ServiceProviderInterface; +use Yiisoft\Aliases\Aliases; +use Yiisoft\Definitions\Reference; + +class_alias(MessageBus::class, 'MyMessageBus'); + +return [ + // ... + CacheItemPoolInterface::class => static function (ContainerInterface $container) { + return new FilesystemAdapter(directory: $container->get(Aliases::class)->get('@runtime')); + }, //One of the following adapters can be used instead: Psr16Adapter, RedisAdapter, MemcachedAdapter, DoctrineDbalAdapter, and so forth. + + Configuration::class => static function (ContainerInterface $container) use ($params) { + $config = ORMSetup::createAttributeMetadataConfiguration( // on PHP >= 8.4, use ORMSetup::createAttributeMetadataConfig() + paths: $params['doctrine']['paths'], + isDevMode: $params['doctrine']['isDevMode'], + cache: $container->get(CacheItemPoolInterface::class)); + $config->setAutoGenerateProxyClasses(ProxyFactory::AUTOGENERATE_FILE_NOT_EXISTS_OR_CHANGED); + return $config; + }, + + EntityManagerInterface::class => static function (ContainerInterface $container) use ($params) { + $configuration = $container->get(Configuration::class); + return new EntityManager( + DriverManager::getConnection( + $params['doctrine']['connection'], + $configuration + ), + $configuration); + }, + EntityManagerProvider::class => SingleManagerProvider::class, + + SerializerInterface::class => PhpSerializer::class, + 'DoctrineTransport' => static function (ContainerInterface $container) use ($params) { + $configuration = $container->get(Configuration::class); + $connection = new Connection([], DriverManager::getConnection( + $params['doctrine']['connection'], + $configuration + )); + return new DoctrineTransport($connection, $container->get(SerializerInterface::class)); + }, + + MyMessageBus::class => static function (ContainerInterface $container) { + return new MyMessageBus([ + new SendMessageMiddleware(sendersLocator: new SendersLocator([ + MyMessage::class => ['DoctrineTransport'] + ], $container)), + new HandleMessageMiddleware(new HandlersLocator([ + MyMessage::class => [$container->get(MyMessageHandler::class)] + ])), + ]); + }, + + EventDispatcherInterface::class => static function (ContainerInterface $container) { + $eventDispatcher = new EventDispatcher(); + $eventDispatcher->addSubscriber($container->get(StopWorkerOnRestartSignalListener::class)); + return $eventDispatcher; + }, + ServiceProviderInterface::class => [ + 'class' => ServiceProvider::class, + '__construct()' => [ + 'container' => Reference::to(ContainerInterface::class), + 'serviceMap' => [ + 'DoctrineTransport' => DoctrineTransport::class + ] + ], + ], + + ConsumeMessagesCommand::class => static function (ContainerInterface $container) { + return new ConsumeMessagesCommand( + $container->get(RoutableMessageBus::class), + $container, + $container->get(EventDispatcherInterface::class), + $container->get(LoggerInterface::class), + array_keys($container->get(ServiceProviderInterface::class)->getProvidedServices()) + ); + }, + DebugCommand::class => [ + '__construct()' => [ + 'mapping' => [ + MyMessageBus::class => [Reference::to(MyMessageHandler::class)] + ] + ], + ], + FailedMessagesRemoveCommand::class => [ + '__construct()' => [ + 'globalFailureReceiverName' => null, + 'failureTransports' => Reference::to(ServiceProviderInterface::class) + ], + ], + FailedMessagesRetryCommand::class => [ + '__construct()' => [ + 'globalReceiverName' => null, + 'failureTransports' => Reference::to(ServiceProviderInterface::class), + 'messageBus' => Reference::to(MyMessageBus::class), + 'eventDispatcher' => Reference::to(EventDispatcherInterface::class), + 'logger' => Reference::to(LoggerInterface::class), + ], + ], + FailedMessagesShowCommand::class => [ + '__construct()' => [ + 'globalFailureReceiverName' => null, + 'failureTransports' => Reference::to(ServiceProviderInterface::class) + ], + ], + SetupTransportsCommand::class => static function (ContainerInterface $container) { + return new SetupTransportsCommand( + $container, + array_keys($container->get(ServiceProviderInterface::class)->getProvidedServices()) + ); + }, + StatsCommand::class => static function (ContainerInterface $container) { + return new StatsCommand( + $container, + array_keys($container->get(ServiceProviderInterface::class)->getProvidedServices()) + ); + }, +]; +``` + +### 4. Integrate the Symfony Messenger commands into the Yii console. + +Add the commands to `config/console/commands.php`: +```php +use Symfony\Component\Messenger\Command\ConsumeMessagesCommand; +use Symfony\Component\Messenger\Command\DebugCommand; +use Symfony\Component\Messenger\Command\FailedMessagesRemoveCommand; +use Symfony\Component\Messenger\Command\FailedMessagesRetryCommand; +use Symfony\Component\Messenger\Command\FailedMessagesShowCommand; +use Symfony\Component\Messenger\Command\SetupTransportsCommand; +use Symfony\Component\Messenger\Command\StatsCommand; +use Symfony\Component\Messenger\Command\StopWorkersCommand; + +return [ + // ... + 'symfony:messenger:consume' => ConsumeMessagesCommand::class, + 'symfony:messenger:debug' => DebugCommand::class, + 'symfony:messenger:failed:remove' => FailedMessagesRemoveCommand::class, + 'symfony:messenger:failed:retry' => FailedMessagesRetryCommand::class, + 'symfony:messenger:failed:show' => FailedMessagesShowCommand::class, + 'symfony:messenger:setup-transports' => SetupTransportsCommand::class, + 'symfony:messenger:stats' => StatsCommand::class, + 'symfony:messenger:stop-workers' => StopWorkersCommand::class +]; +``` + +### 5. Dispatch a message. + +Example: + +```php +use App\Messages\MyMessage; +use MyMessageBus; +use Psr\Http\Message\ResponseInterface; + +final readonly class MyController +{ + public function __construct(private MyMessageBus $bus) + { + } + + public function sendMessage(): ResponseInterface + { + $this->bus->dispatch(new MyMessage('Hello Symfony Messenger!')); + // ... + } +} +``` + +### 6. Consume messages. + +Example: +```bash +./yii symfony:messenger:consume DoctrineTransport --bus=MyMessageBus +``` diff --git a/src/pt-BR/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md b/src/pt-BR/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md new file mode 100644 index 00000000..5c4b3cf4 --- /dev/null +++ b/src/pt-BR/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md @@ -0,0 +1,292 @@ +# Symfony Scheduler integration guide + +The [Symfony Scheduler](https://symfony.com/doc/current/scheduler.html) +component manages task scheduling within your PHP application, like running +a task each night at 3 AM, every two weeks except for holidays or any other +custom schedule you might need. + +## Installation + +```shell +composer require symfony/scheduler +``` + +## How to use with Yii + +### 1. Create a Message and Handler. + +```php +namespace App\Messages; + +final readonly class MyMessage +{ + public function __construct(public string $content) + { + } +} +``` + +```php +namespace App\Messages; + +use Psr\Log\LoggerInterface; + +final readonly class MyMessageHandler +{ + public function __construct(private LoggerInterface $logger) + { + } + public function __invoke(MyMessage $message): void + { + // ... + $this->logger->info("The message with the content '$message->content' has been received."); + } +} +``` + +### 2. Attaching Recurring Messages to a Schedule. + +```php +namespace App\Scheduler; + +use App\Messages\MyMessage; +use Symfony\Component\Scheduler\RecurringMessage; +use Symfony\Component\Scheduler\Schedule; +use Symfony\Component\Scheduler\ScheduleProviderInterface; + +class MyScheduleProvider implements ScheduleProviderInterface +{ + public function getSchedule(): Schedule + { + return (new Schedule()) + ->with( + RecurringMessage::every( + '10 seconds', + new MyMessage('Hello Symfony Scheduler!')) + ); + } +} +``` + +### 3. Configure the Symfony Scheduler. + +Depending on your needs, the Symfony Scheduler component offers two ways to +consume messages: using the `messenger:consume` command or [creating a +worker +programmatically](https://symfony.com/doc/current/scheduler.html#creating-a-consumer-programmatically). +The example uses the +[symfony/messenger](https://packagist.org/packages/symfony/messenger) +package to consume messages. + + +Install the Symfony Messenger package: +```shell +composer require symfony/messenger +``` + +Install the Symfony Cache package: +```shell +composer require symfony/cache +``` + +Implement the ServiceProviderInterface. This instance of the +ServiceProviderInterface is used to configure certain Symfony Messenger +commands. + +```php +namespace App\Services; + +use Psr\Container\ContainerInterface; +use Symfony\Contracts\Service\ServiceProviderInterface; + +final readonly class ServiceProvider implements ServiceProviderInterface +{ + /** + * @param ContainerInterface $container + * @param array $serviceMap + */ + public function __construct( + private ContainerInterface $container, + private array $serviceMap) + { + } + + /** + * @inheritDoc + */ + public function get(string $id): mixed + { + return $this->container->get($id); + } + + public function has(string $id): bool + { + return $this->container->has($id); + } + + /** + * @inheritDoc + */ + public function getProvidedServices(): array + { + return $this->serviceMap; + } +} +``` + +Configure the Symfony Scheduler and Symfony Messenger dependencies in the +`config/common/di/application.php`: +```php +use App\Messages\MyMessage; +use App\Messages\MyMessageHandler; +use App\Scheduler\MyScheduleProvider; +use App\Services\ServiceProvider; +use Psr\Cache\CacheItemPoolInterface; +use Psr\Container\ContainerInterface; +use Psr\EventDispatcher\EventDispatcherInterface; +use Psr\Log\LoggerInterface; +use Symfony\Component\Cache\Adapter\FilesystemAdapter; +use Symfony\Component\EventDispatcher\EventDispatcher; +use Symfony\Component\Messenger\Command\ConsumeMessagesCommand; +use Symfony\Component\Messenger\Command\DebugCommand; +use Symfony\Component\Messenger\Command\FailedMessagesRemoveCommand; +use Symfony\Component\Messenger\Command\FailedMessagesRetryCommand; +use Symfony\Component\Messenger\Command\FailedMessagesShowCommand; +use Symfony\Component\Messenger\Command\SetupTransportsCommand; +use Symfony\Component\Messenger\Command\StatsCommand; +use Symfony\Component\Messenger\EventListener\StopWorkerOnRestartSignalListener; +use Symfony\Component\Messenger\Handler\HandlersLocator; +use Symfony\Component\Messenger\MessageBus; +use Symfony\Component\Messenger\Middleware\HandleMessageMiddleware; +use Symfony\Component\Messenger\RoutableMessageBus; +use Symfony\Component\Scheduler\Generator\MessageGenerator; +use Symfony\Component\Scheduler\Messenger\SchedulerTransport; +use Symfony\Contracts\Service\ServiceProviderInterface; +use Yiisoft\Aliases\Aliases; +use Yiisoft\Definitions\Reference; + +class_alias(MessageBus::class, 'MyMessageBus'); + +return [ + // ... + CacheItemPoolInterface::class => static function (ContainerInterface $container) { + return new FilesystemAdapter(directory: $container->get(Aliases::class)->get('@runtime')); + }, //One of the following adapters can be used instead: Psr16Adapter, RedisAdapter, MemcachedAdapter, DoctrineDbalAdapter, and so forth. + + + 'SchedulerTransport' => static function () { + return new SchedulerTransport( + new MessageGenerator( + new MyScheduleProvider(), + 'MySchedule' + ) + ); + }, + + MyMessageBus::class => static function (ContainerInterface $container) { + return new MyMessageBus([ + new HandleMessageMiddleware(new HandlersLocator([ + MyMessage::class => [$container->get(MyMessageHandler::class)] + ])), + ]); + }, + + EventDispatcherInterface::class => static function (ContainerInterface $container) { + $eventDispatcher = new EventDispatcher(); + $eventDispatcher->addSubscriber($container->get(StopWorkerOnRestartSignalListener::class)); + return $eventDispatcher; + }, + ServiceProviderInterface::class => [ + 'class' => ServiceProvider::class, + '__construct()' => [ + 'container' => Reference::to(ContainerInterface::class), + 'serviceMap' => [ + 'SchedulerTransport' => SchedulerTransport::class + ] + ], + ], + + ConsumeMessagesCommand::class => static function (ContainerInterface $container) { + return new ConsumeMessagesCommand( + $container->get(RoutableMessageBus::class), + $container, + $container->get(EventDispatcherInterface::class), + $container->get(LoggerInterface::class), + array_keys($container->get(ServiceProviderInterface::class)->getProvidedServices()) + ); + }, + DebugCommand::class => [ + '__construct()' => [ + 'mapping' => [ + MyMessageBus::class => [Reference::to(MyMessageHandler::class)] + ] + ], + ], + FailedMessagesRemoveCommand::class => [ + '__construct()' => [ + 'globalFailureReceiverName' => null, + 'failureTransports' => Reference::to(ServiceProviderInterface::class) + ], + ], + FailedMessagesRetryCommand::class => [ + '__construct()' => [ + 'globalReceiverName' => null, + 'failureTransports' => Reference::to(ServiceProviderInterface::class), + 'messageBus' => Reference::to(MyMessageBus::class), + 'eventDispatcher' => Reference::to(EventDispatcherInterface::class), + 'logger' => Reference::to(LoggerInterface::class), + ], + ], + FailedMessagesShowCommand::class => [ + '__construct()' => [ + 'globalFailureReceiverName' => null, + 'failureTransports' => Reference::to(ServiceProviderInterface::class) + ], + ], + SetupTransportsCommand::class => static function (ContainerInterface $container) { + return new SetupTransportsCommand( + $container, + array_keys($container->get(ServiceProviderInterface::class)->getProvidedServices()) + ); + }, + StatsCommand::class => static function (ContainerInterface $container) { + return new StatsCommand( + $container, + array_keys($container->get(ServiceProviderInterface::class)->getProvidedServices()) + ); + }, +]; +``` + +### 4. Integrate the Symfony Messenger commands into the Yii console. + +Add the commands to `config/console/commands.php`: +```php +use Symfony\Component\Messenger\Command\ConsumeMessagesCommand; +use Symfony\Component\Messenger\Command\DebugCommand; +use Symfony\Component\Messenger\Command\FailedMessagesRemoveCommand; +use Symfony\Component\Messenger\Command\FailedMessagesRetryCommand; +use Symfony\Component\Messenger\Command\FailedMessagesShowCommand; +use Symfony\Component\Messenger\Command\SetupTransportsCommand; +use Symfony\Component\Messenger\Command\StatsCommand; +use Symfony\Component\Messenger\Command\StopWorkersCommand; + +return [ + // ... + 'symfony:messenger:consume' => ConsumeMessagesCommand::class, + 'symfony:messenger:debug' => DebugCommand::class, + 'symfony:messenger:failed:remove' => FailedMessagesRemoveCommand::class, + 'symfony:messenger:failed:retry' => FailedMessagesRetryCommand::class, + 'symfony:messenger:failed:show' => FailedMessagesShowCommand::class, + 'symfony:messenger:setup-transports' => SetupTransportsCommand::class, + 'symfony:messenger:stats' => StatsCommand::class, + 'symfony:messenger:stop-workers' => StopWorkersCommand::class +]; +``` + +### 5. Consume messages. + +Example: +```bash +./yii symfony:messenger:consume SchedulerTransport --bus=MyMessageBus +``` diff --git a/src/pt-BR/cookbook/using-htmx-for-partial-reloads.md b/src/pt-BR/cookbook/using-htmx-for-partial-reloads.md new file mode 100644 index 00000000..c588aa88 --- /dev/null +++ b/src/pt-BR/cookbook/using-htmx-for-partial-reloads.md @@ -0,0 +1,390 @@ +# Using htmx for partial page reloads + +[htmx](https://htmx.org/) lets links and forms request HTML fragments and swap them into the current page. In a Yii +application, this works well for grids: sorting, filtering, and pagination can update only the grid while the rest of +the page stays in place. + +This recipe uses `GridView` as an example because it has links and forms +that naturally benefit from partial reloads. The same pattern works for any +widget or page fragment: render the fragment separately, add htmx attributes +to the controls that should refresh it, and return only that fragment for +htmx requests. + +## Install GridView + +Install the data view package if the application doesn't use it yet: + +```shell +composer require yiisoft/yii-dataview +``` + +## Load htmx + +The simplest setup is loading htmx from a CDN. Create +`src/Web/Shared/Layout/Main/HtmxAsset.php`: + +```php + 'sha384-H5SrcfygHmAuTDZphMHqBJLc3FhssKjG7w/CeCpFReSfwBWDTKpkzPP8c+cLsK+V', + 'crossorigin' => 'anonymous', + ]; +} +``` + +When updating the htmx version, update the URL and `integrity` value +together. + +For production applications, consider serving htmx from your application +assets to avoid depending on a third-party CDN. Download `htmx.min.js` into +`assets/main/js/htmx.min.js` and use a local asset bundle: + +```php + */ + $pagination = OffsetPagination::widget(); + + return GridView::widget() + ->containerAttributes([ + 'id' => 'UsersGridView', + 'class' => 'mt-4 position-relative', + ]) + ->dataReader($this->dataReader()) + ->pageSizeConstraint(5) + ->paginationWidget($pagination) + ->columns( + new DataColumn('id', header: 'ID', filter: true), + new DataColumn('login', header: 'Login', filter: true), + new DataColumn('name', header: 'Name', filter: true), + new DataColumn('status', header: 'Status', filter: true), + ) + ->render(); + } + + private function dataReader(): IterableDataReader + { + return new IterableDataReader([ + ['id' => 1, 'login' => 'admin', 'name' => 'Alice Adams', 'status' => 'Active'], + ['id' => 2, 'login' => 'editor', 'name' => 'Eve Editor', 'status' => 'Active'], + ['id' => 3, 'login' => 'author', 'name' => 'Arthur Author', 'status' => 'Active'], + ['id' => 4, 'login' => 'reviewer', 'name' => 'Rita Reviewer', 'status' => 'Inactive'], + ['id' => 5, 'login' => 'support', 'name' => 'Sam Support', 'status' => 'Active'], + ['id' => 6, 'login' => 'guest', 'name' => 'Grace Guest', 'status' => 'Inactive'], + ]); + } +} +``` + +For a real application, replace `dataReader()` with a reader backed by a +database query or repository. Keep the widget responsible for rendering the +grid fragment. + +Create `src/Web/Users/Index/template.php`: + +```php +setTitle('Users'); +?> +

Users

+ + +``` + +Create `src/Web/Users/Index/Action.php`: + +```php +viewRenderer->render(__DIR__ . '/template'); + } +} +``` + +Add the action to `config/common/routes.php`: + +```php +routes( + Route::get('/') + ->action(Web\HomePage\Action::class) + ->name('home'), + Route::get('/users') + ->action(Web\Users\Index\Action::class) + ->name('users/index'), + ), +]; +``` + +Open `/users` and make sure sorting, filtering, and pagination work with +full page reloads first. + +## Add htmx attributes to the grid + +Now update `UsersGrid` so the grid controls request a fragment and swap it +into `#UsersGridView`: + +```php + '#UsersGridView', + 'hx-target' => '#UsersGridView', + 'hx-replace-url' => 'true', + 'hx-swap' => 'outerHTML', + ]; + + /** @var PaginationWidgetInterface */ + $pagination = OffsetPagination::widget()->addLinkAttributes([ + 'hx-boost' => 'true', + ...$htmxLoadAttributes, + ]); + + return GridView::widget() + ->containerAttributes([ + 'id' => 'UsersGridView', + 'class' => 'mt-4 position-relative', + ]) + ->dataReader($this->dataReader()) + ->pageSizeConstraint(5) + ->sortableLinkAttributes([ + 'hx-boost' => 'true', + ...$htmxLoadAttributes, + ]) + ->filterFormAttributes([ + 'hx-boost' => 'true', + ...$htmxLoadAttributes, + ]) + ->paginationWidget($pagination) + ->columns( + new DataColumn('id', header: 'ID', filter: true), + new DataColumn('login', header: 'Login', filter: true), + new DataColumn('name', header: 'Name', filter: true), + new DataColumn('status', header: 'Status', filter: true), + ) + ->render(); + } + + private function dataReader(): IterableDataReader + { + return new IterableDataReader([ + ['id' => 1, 'login' => 'admin', 'name' => 'Alice Adams', 'status' => 'Active'], + ['id' => 2, 'login' => 'editor', 'name' => 'Eve Editor', 'status' => 'Active'], + ['id' => 3, 'login' => 'author', 'name' => 'Arthur Author', 'status' => 'Active'], + ['id' => 4, 'login' => 'reviewer', 'name' => 'Rita Reviewer', 'status' => 'Inactive'], + ['id' => 5, 'login' => 'support', 'name' => 'Sam Support', 'status' => 'Active'], + ['id' => 6, 'login' => 'guest', 'name' => 'Grace Guest', 'status' => 'Inactive'], + ]); + } +} +``` + +The important part is the shared `$htmxLoadAttributes` array: + +- `hx-boost="true"` makes the grid links and filter form send htmx requests. +- `hx-target="#UsersGridView"` tells htmx which element to replace. +- `hx-swap="outerHTML"` replaces the whole grid container with the response. +- `hx-replace-url="true"` keeps the browser URL in sync with the current + sort, filter, and page. +- `hx-indicator="#UsersGridView"` marks the grid as the loading indicator + element while the request is active. + +The target selector and the container `id` must match. In this example, both +use `UsersGridView`. + +## Return partial HTML for htmx requests + +htmx sends the `HX-Request` header with its requests. + +In the action, return only the widget when the header is present: + +```php +getHeaderLine('HX-Request') === 'true' + ? $this->htmlResponseFactory->createResponse(UsersGrid::widget()) + : $this->viewRenderer->render(__DIR__ . '/template'); + + return $response->withAddedHeader('Vary', 'HX-Request'); + } +} +``` + +The `Vary` header matters when a browser, proxy, or CDN caches +responses. The same URL can return a full page without `HX-Request` and a +fragment with `HX-Request: true`, so caches must keep these responses +separate. + +## Try it + +Open the list page and use sorting, filtering, or pagination. The browser +URL should change, and only the grid HTML should be replaced. + +In the browser developer tools, the htmx requests should include the +`HX-Request` header. Their responses should contain only the grid container. + +Use the same pattern for other widgets or page fragments: + +1. Put the reloadable HTML into a widget or another small renderer. +2. Add htmx attributes to the links and forms that should refresh it. +3. Return the fragment for htmx requests and the full page for regular + requests. diff --git a/src/pt-BR/cookbook/using-yii-in-third-party-apps.md b/src/pt-BR/cookbook/using-yii-in-third-party-apps.md new file mode 100644 index 00000000..4109f880 --- /dev/null +++ b/src/pt-BR/cookbook/using-yii-in-third-party-apps.md @@ -0,0 +1,171 @@ +# Using Yii in third-party applications + +Sometimes a project already has an entry point owned by another framework, +CMS, or legacy application, but you still want to reuse Yii services: +configuration, DI definitions, domain services, logging, mailers, database +connections, or console-oriented application code. + +Yii3 has no global application singleton. Bootstrap the Yii container +explicitly and pass the services you need to the third-party code. + +## Bootstrap the Yii container + +Create a small adapter in the host application, for example +`bootstrap-yii-services.php`: + +```php +withValidate(Environment::appDebug()) + ->withDefinitions(array_merge( + $config->get('di-console'), + [ConfigInterface::class => $config], + )) + ->withProviders($config->get('di-providers-console')) + ->withDelegates($config->get('di-delegates-console')); + + if ($config->has('di-tags-console')) { + $containerConfig = $containerConfig->withTags($config->get('di-tags-console')); + } + + $container = new Container($containerConfig); + + foreach ($config->get('bootstrap-console') as $callback) { + if (!is_callable($callback)) { + throw new RuntimeException(sprintf( + 'Bootstrap callback must be callable, "%s" given.', + get_debug_type($callback), + )); + } + + $callback($container); + } + + return $container; +} +``` + +The adapter builds only the Yii configuration and DI container, then runs +the configured bootstrap callbacks. It does not create or run a Yii +application runner, so the third-party application keeps ownership of the +entry point and process lifecycle. + +Use console configuration groups when you need common services and +console-safe services. Use web groups instead only when you intentionally +need web-specific definitions from the `di-web` group, such as PSR-17 HTTP +factories or web middleware dependencies. + +## Get Yii services from the host application + +Use the adapter from the third-party application: + +```php +get(ApplicationParams::class); + +echo $params->name; +``` + +In real integrations, prefer getting your own application services instead +of framework infrastructure. For example, expose `InvoiceSender`, +`ReportBuilder`, or `CatalogImporter` from Yii and call that service from +the host application. + +## Keep boundaries explicit + +Avoid mixing request lifecycles. Let the host application continue to own +its HTTP request and response. Let Yii provide services that do not assume +Yii is handling the current request. + +Good candidates for reuse: + +- domain services; +- repositories and database connections; +- mailers and notification services; +- loggers; +- validators; +- queue producers; +- command-like application services. + +Avoid pulling in Yii actions, middleware stacks, sessions, CSRF middleware, +or view rendering unless the host application explicitly delegates that +whole responsibility to Yii. + +## Configuration groups + +The default application template separates configuration by group: + +- `di` is shared by web and console entry points; +- `di-console` is console-specific and includes `di` in the template; +- `di-web` is web-specific and includes `di`; +- `params-console` and `params-web` extend common `params`. + +Choose the smallest group that contains the services you need. If the host +application only needs domain services, keep those definitions in +`config/common/di/*.php` so both Yii and the third-party app can use them +without web-only dependencies. + +After changing `config/configuration.php`, rebuild the merge plan: + +```shell +composer yii-config-rebuild +``` + +## Error handling and logging + +The host application should remain responsible for top-level error +handling. Catch exceptions at the integration boundary when the host app +needs to convert them into its own response or error format. + +Yii services can still use `Psr\Log\LoggerInterface`. Configure the Yii +logger to write to the same destination as the host application or bridge +both applications to the same PSR-3 logger. + +## Long-running host processes + +If the third-party application is a worker, daemon, or event-loop server, +avoid mutable shared state in services. Yii services resolved from the +container are shared by default, so design them as stateless services or +create a fresh container for each isolated job when stateful dependencies +are unavoidable. diff --git a/src/pt-BR/cookbook/working-on-windows.md b/src/pt-BR/cookbook/working-on-windows.md new file mode 100644 index 00000000..a89a91f7 --- /dev/null +++ b/src/pt-BR/cookbook/working-on-windows.md @@ -0,0 +1,84 @@ +# Working on Windows + +Yii applications usually run on Linux in production. On Windows, choose a +local workflow that stays close to that environment and keeps filesystem +performance predictable. + +## Recommended setup: WSL + +Use [Windows Subsystem for Linux](https://learn.microsoft.com/windows/wsl/) +with a Linux distribution such as Ubuntu. Install PHP, Composer, Git, and +Make inside WSL, then clone the project into the Linux filesystem: + +```shell +cd ~ +git clone https://github.com/yiisoft/app.git my-app +cd my-app +composer install +``` + +Keep the project under the WSL filesystem, for example +`/home/user/projects/my-app`. Avoid working from a mounted Windows path such +as `/mnt/c/Users/user/projects/my-app`; it is much slower for Composer, +tests, and tools that read many small files. + +You can open the project from Windows editors through the WSL +integration. In PhpStorm, open the project from the WSL filesystem. In VS +Code, use the WSL extension and open the folder from inside the WSL session. + +## Docker with WSL + +Docker Desktop with the WSL backend is also a good Windows setup. Keep the +project in the WSL filesystem and run Docker commands from WSL: + +```shell +make build +make up +make yii +make test +``` + +This keeps bind mounts fast and gives containers Linux paths that match the +tooling used by the Yii application templates. + +If you need IDE links from debug stack traces, set `APP_HOST_PATH` to the +project path that your IDE can open. + +## Git Bash + +[Git for Windows](https://git-scm.com/downloads/win) installs Git Bash and +common Unix tools. It can be enough when you want to run the application +directly on Windows without WSL or Docker. + +Use this option when your project does not depend on Linux-only extensions +or shell scripts. Check the same commands you expect contributors to use: + +```shell +composer install +composer test +``` + +If the project uses `make`, Git for Windows includes a Bash environment, but +`make` availability depends on your local installation. Install it +separately when needed. + +## PowerShell and CMD + +PowerShell and CMD can run PHP and Composer, but they differ from the common +Linux server environment in quoting, environment variables, paths, and shell +utilities. Use them for simple commands only. + +For regular Yii development on Windows, prefer WSL or Docker with WSL. + +## Choosing a workflow + +Use WSL when you want the closest local match to a Linux server and do not +need containers for every service. + +Use Docker with WSL when you want the application, database, and other +services described by Compose files. + +Use Git Bash for small projects or quick checks that run directly on +Windows. + +Use PowerShell or CMD when the command is known to be platform-neutral. diff --git a/src/pt-BR/guide/caching/data.md b/src/pt-BR/guide/caching/data.md new file mode 100644 index 00000000..0b7d1a62 --- /dev/null +++ b/src/pt-BR/guide/caching/data.md @@ -0,0 +1,216 @@ +# Data caching + +Data caching is about storing some PHP variables in a cache and retrieving +them later from the cache. It's also the foundation for more advanced +caching features, such as [page caching](page.md). + +To use cache, install [yiisoft/cache](https://github.com/yiisoft/cache) +package: + +```shell +composer require yiisoft/cache +``` + +The following code is a typical usage pattern of data caching, where +`$cache` refers to a `Cache` instance from the package: + +```php +public function getTopProducts(\Yiisoft\Cache\CacheInterface $cache): array +{ + $key = ['top-products', $count = 10]; + + // Try retrieving $data from cache. + $data = $cache->getOrSet($key, function (\Psr\SimpleCache\CacheInterface $cache) use ($count) { + // Can't find $data in a cache, calculate it from scratch. + return getTopProductsFromDatabase($count); + }, 3600); + + return $data; +} +``` + +When cache has data associated with the `$key`, it returns the cached +value. Otherwise, it executes the passed anonymous function to calculate +the value to cache and return. + +If the anonymous function requires some data from the outer scope, you can +pass it with the `use` statement. + +## Cache handlers + +The cache service uses [PSR-16](https://www.php-fig.org/psr/psr-16/) +compatible cache handlers which represent various cache storages, such as +memory, files, and databases. + +Yii provides the following handlers: + +- `NullCache` — a cache placeholder which does no real caching. The purpose + of this handler is to simplify the code that needs to check the + availability of cache. For example, during development or if the server + doesn't have actual cache support, you may configure a cache service to + use this handler. When you enable actual cache support, you can switch to + using the corresponding cache handler. In both cases, you may use the + same code without extra checks. +- `ArrayCache` — provides caching for the current request only by storing + the values in an array. +- [APCu](https://github.com/yiisoft/cache-apcu) - uses a PHP + [APC](https://secure.php.net/manual/en/book.apc.php) extension. You can + consider this option as the fastest one when dealing with cache for a + centralized thick application (e.g., one server, no dedicated load + balancers, etc.). +- [Database](https://github.com/yiisoft/cache-db) — uses a database table to + store cached data. +- [File](https://github.com/yiisoft/cache-file) — uses standard files to + store cached data. This is particularly suitable to cache large chunks of + data, such as page content. +- [Memcached](https://github.com/yiisoft/cache-memcached) — uses a PHP + [memcached](https://secure.php.net/manual/en/book.memcached.php) + extension. You can consider this option as the fastest one when dealing + with cache in a distributed application + (e.g., with several servers, load balancers, etc.) +- [Wincache](https://github.com/yiisoft/cache-wincache) — uses PHP [WinCache](https://iis.net/downloads/microsoft/wincache-extension) + ([see also](https://secure.php.net/manual/en/book.wincache.php)) extension. + +[You could find more handlers at +packagist.org](https://packagist.org/providers/psr/simple-cache-implementation). + +> [!TIP] +> You may use different cache storage in the same application. A common strategy is: +> - To use memory-based cache storage to store small but constantly used data (e.g., statistics) +> - To use file-based or database-based cache storage to store big and less often used data (e.g., page content) + +Cache handlers are usually set up in a [dependency injection +container](../concept/di-container.md) so that they can be globally +configurable and accessible. + +Because all cache handlers support the same set of APIs, you can swap the +underlying cache handler with a different one. You can do it by +reconfiguring the application without modifying the code that uses the +cache. + +### Cache keys + +A key uniquely identifies each data item stored in the cache. When you store +a data item, you have to specify a key for it. Later, when you retrieve the +data item, you should give the corresponding key. + +You may use a string or an arbitrary value as a cache key. When a key isn't +a string, it will be automatically serialized into a string. + +A common strategy of defining a cache key is to include all determining +factors in terms of an array. + +When different applications use the same cache storage, you should specify a +unique cache key prefix for each application to avoid conflicts of cache +keys. You can do this by using `\Yiisoft\Cache\PrefixedCache` decorator: + +```php +$arrayCacheWithPrefix = new \Yiisoft\Cache\PrefixedCache(new \Yiisoft\Cache\ArrayCache(), 'myapp_'); +$cache = new \Yiisoft\Cache\Cache($arrayCacheWithPrefix); +``` + +### Cache expiration + +A data item stored in a cache will remain there forever unless it's removed +because of some caching policy enforcement. For example, caching space is +full and cache storage removes the oldest data. To change this behavior, +you can set a TTL parameter when calling a method to store a data item: + +```php +$ttl = 3600; +$data = $cache->getOrSet($key, function (\Psr\SimpleCache\CacheInterface $cache) use ($count) { +return getTopProductsFromDatabase($count); +}, $ttl); +``` + +The `$ttl` parameter indicates for how many seconds the data item can remain +valid in the cache. When you retrieve the data item, if it has passed the +expiration time, the method will execute the function and set the resulting +value into cache. + +You may set the default TTL for the cache: + +```php +$cache = new \Yiisoft\Cache\Cache($arrayCache, 60 * 60); // 1 hour +``` + +Additionally, you can invalidate a cache key explicitly: + +```php +$cache->remove($key); +``` + +### Invalidation dependencies + +Besides the expiration setting, changes of the so-called **invalidation +dependencies** may also invalidate cached data item. For example, +`\Yiisoft\Cache\Dependency\FileDependency` represents the dependency of a +file's modification time. When this dependency changes, it means something +modifying the corresponding file. As a result, any outdated file content +found in the cache should invalidate. + +Cache dependencies are objects of `\Yiisoft\Cache\Dependency\Dependency` +descendant classes. When you store a data item in the cache, you can pass +along an associated cache dependency object. For example, + +```php +/** + * @var callable $callable + * @var \Yiisoft\Cache\CacheInterface $cache + */ + +use Yiisoft\Cache\Dependency\TagDependency; + +// Set many cache values marking both with a tag. +$cache->getOrSet('item_42_price', $callable, null, new TagDependency('item_42')); +$cache->getOrSet('item_42_total', $callable, 3600, new TagDependency('item_42')); + +// Trigger invalidation by tag. +TagDependency::invalidate($cache, 'item_42'); +``` + +Below is a summary of the available cache dependencies: + +- `\Yiisoft\Cache\Dependency\ValueDependency`: invalidates the cache when + specified value changes. +- `\Yiisoft\Cache\Dependency\CallbackDependency`: invalidates the cache when + the result of the specified PHP callback is different. +- `\Yiisoft\Cache\Dependency\FileDependency`: invalidates the cache when the + file's last modification time is different. +- `\Yiisoft\Cache\Dependency\TagDependency`: associates a cached data item + with one or many tags. You may invalidate the cached data items with the + specified tag(s) by calling `TagDependency::invalidate()`. + +You may combine many dependencies using +`\Yiisoft\Cache\Dependency\AnyDependency` or +`\Yiisoft\Cache\Dependency\AllDependencies`. + +To implement your own dependency, extend from +`\Yiisoft\Cache\Dependency\Dependency`. + +### Cache stampede prevention + +[A cache stampede](https://en.wikipedia.org/wiki/Cache_stampede) is a type +of cascading failure that can occur when massively parallel computing +systems with caching mechanisms come under a high load. This behavior is +sometimes also called dog-piling. + +The `\Yiisoft\Cache\Cache` uses a built-in "Probably early expiration" +algorithm that prevents cache stampede. This algorithm randomly fakes a +cache miss for one user while others are still served the cached value. You +can control its behavior with the fifth optional parameter of `getOrSet()`, +which is a float value called `$beta`. By default, beta is `1.0`, which is +usually enough. The higher the value, the earlier cache will be re-created. + +```php +/** + * @var mixed $key + * @var callable $callable + * @var \DateInterval $ttl + * @var \Yiisoft\Cache\CacheInterface $cache + * @var \Yiisoft\Cache\Dependency\Dependency $dependency + */ + +$beta = 2.0; +$cache->getOrSet($key, $callable, $ttl, $dependency, $beta); +``` diff --git a/src/pt-BR/guide/caching/overview.md b/src/pt-BR/guide/caching/overview.md new file mode 100644 index 00000000..1f9b8ccc --- /dev/null +++ b/src/pt-BR/guide/caching/overview.md @@ -0,0 +1,21 @@ +# Cache + +Caching is an inexpensive and effective way to improve the performance of an +application. By storing relatively static data in cache and serving it from +cache when requested, the application saves the time that it otherwise would +require to generate the data from scratch every time. + +Caching can occur at different levels and places in an application. On the +server-side, at the lower level, cache may be used to store basic data, such +as a list of most recent article information fetched from the database; and +at the higher level, cache may be used to store fragments or whole of Web +pages, such as the rendering result of the most recent articles. On the +client-side, you may use HTTP caching to keep most recently visited page +content in the browser cache. + +Yii supports all these caching mechanisms: + +* [Data caching](data.md) +* [Fragment caching](fragment.md) +* [Page caching](page.md) +* [HTTP caching](http.md) diff --git a/src/pt-BR/guide/concept/aliases.md b/src/pt-BR/guide/concept/aliases.md new file mode 100644 index 00000000..c41871ed --- /dev/null +++ b/src/pt-BR/guide/concept/aliases.md @@ -0,0 +1,149 @@ +# Aliases + +You can use aliases to represent file paths or URLs so that you don't have +to hard-code absolute paths or URLs in your project. An alias must start +with the `@` character to be differentiated from normal file paths and +URLs. Alias defined without leading `@` will be prefixed with `@` character. + +Default Yii application has some aliases pre-defined in +`config/params.php`. For example, the alias `@public` represents the web +root path; `@baseUrl` represents the base URL for the currently running Web +application. + +## Defining aliases + +You can define an alias via application's `config/params.php`: + +```php +return [ + // ... + + 'yiisoft/aliases' => [ + 'aliases' => [ + // ... + + // an alias of a file path + '@foo' => '/path/to/foo', + + // an alias of a URL + '@bar' => 'https://www.example.com', + + // an alias of a concrete file that contains a \foo\Bar class + '@foo/Bar.php' => '/definitely/not/foo/Bar.php', + ], + ], +]; +``` + +> [!NOTE] +> The file path or URL being aliased may *not* necessarily refer to an existing file or resource. + +Given a defined alias, you may derive a new alias by appending a slash `/` +followed with one or more path segments. For example, `@foo` is a root +alias, while `@foo/bar/file.php` is a derived alias. + +You can define an alias using another alias (either root or derived): + +```php +'@foobar' => '@foo/bar', +``` + +The `yiisoft/aliases` parameter initializes `Aliases` service from +[`yiisoft/aliases`](https://github.com/yiisoft/aliases) package. You can +set extra aliases in runtime by using the service: + +```php +use \Yiisoft\Aliases\Aliases; + +public function actionIndex(Aliases $aliases) +{ + $aliases->set('@uploads', '@root/uploads'); +} +``` + +## Using aliases in configuration + +It's preferred to resolve aliases at the configuration level, so services +get URLs and paths as ready to use strings: + +```php + static fn (Aliases $aliases) => new FileCache( + $aliases->get($params['yiisoft/cache-file']['fileCache']['path']) + ), +]; +``` + +## Resolving aliases + +You can use `Aliases` service to resolve an alias or derived alias into the +file path or URL it represents: + +```php +use \Yiisoft\Aliases\Aliases; + +public function actionIndex(Aliases $aliases) +{ + $foo = $aliases->get('@foo'); // /path/to/foo + $bar = $aliases->get('@bar'); // https://www.example.com + $file = $aliases->get('@foo/bar/file.php'); // /path/to/foo/bar/file.php +} +``` + +The path/URL represented by a derived alias is determined by replacing the +root alias part with its corresponding path/URL in the derived alias. + +> [!NOTE] +> The `get()` method doesn't check whether the resulting path/URL refers to an existing file or resource. + + +A root alias may also contain slash `/` characters. The `get()` method is +intelligent enough to tell, which part of an alias is a root alias and thus +correctly determines the corresponding file path or URL: + +```php +use \Yiisoft\Aliases\Aliases; + +public function actionIndex(Aliases $aliases) +{ + $aliases->set('@foo', '/path/to/foo'); + $aliases->set('@foo/bar', '/path2/bar'); + + $aliases->get('@foo/test/file.php'); // /path/to/foo/test/file.php + $aliases->get('@foo/bar/file.php'); // /path2/bar/file.php +} +``` + +If `@foo/bar` isn't defined as a root alias, the last statement would +display `/path/to/foo/bar/file.php`. + + +## Predefined aliases + +[Yii application](https://github.com/yiisoft/app) predefines a set of +aliases to reference commonly used file paths and URLs: + +- `@root` - the base directory of the currently running application. +- `@assets` - application's public directory where it publishes assets. +- `@assetsUrl` - URL of base directory with published assets. +- `@baseUrl` - the base URL of the currently running Web + application. Defaults to `/`. +- `@npm` - node packages directory. +- `@bower` - bower packages directory. +- `@vendor` - Composer's `vendor` directory. +- `@public` - application's publicly accessible directory that with + `index.php`. +- `@runtime` - the runtime path of the currently running + application. Defaults to `@root/runtime`. +- `@layout` - the directory with layouts. +- `@resources` - directory with views, asset sources and other resources. +- `@views` - application view templates base directory. diff --git a/src/pt-BR/guide/concept/autoloading.md b/src/pt-BR/guide/concept/autoloading.md new file mode 100644 index 00000000..c01226ae --- /dev/null +++ b/src/pt-BR/guide/concept/autoloading.md @@ -0,0 +1,37 @@ +# Class autoloading + +Since Yii uses [Composer](https://getcomposer.org) to manage packages, it +automatically loads classes from these packages without the need to +`require` their file explicitly. When it installs packages, it generates a +[PSR-4 compatible autoloader](https://www.php-fig.org/psr/psr-4/). To use +it, `require_once` autoloader `/vendor/autoload.php` in your `index.php` +entry point file. + +You can use autoloader not only for the packages installed, but for your +application as well since it's also a package. To load classes of a certain +namespace, add the following to `composer.json`: + +```json +{ + "autoload": { + "psr-4": { + "App\\": "src/" + } + } +} +``` + +Where `App\\` is a root namespace and `src/` is a directory where you have +your classes. You can add more source roots if needed. When done, execute +`composer dump-autoload` or simply `composer du` and classes from the +corresponding namespaces will start loading automatically. + +If you need development-environment-specific autoloading that isn't used +when executing Composer with `--no-dev` flag, add it to `autoload-dev` +section instead of `autoload`. + +## References + +- [PSR-4: Autoloader](https://www.php-fig.org/psr/psr-4/). +- [Composer guide on + autoloading](https://getcomposer.org/doc/01-basic-usage.md#autoloading). diff --git a/src/pt-BR/guide/concept/configuration.md b/src/pt-BR/guide/concept/configuration.md new file mode 100644 index 00000000..e83bc33a --- /dev/null +++ b/src/pt-BR/guide/concept/configuration.md @@ -0,0 +1,455 @@ +# Configuration + +There are many ways to configure your application. We will focus on concepts +used in the [default project template](https://github.com/yiisoft/app). + +Yii3 configs are part of the application. You can change many aspects of how +the application works by editing configuration under `config/` directory. + +## Config plugin + +The application template uses +[yiisoft/config](https://github.com/yiisoft/config) as a composer plugin to +assemble configs. + +Packages provide default configurations through defined [config +groups](https://github.com/yiisoft/config#config-groups) in the +`config-plugin` key in the `extra` section of the `composer.json`: + +```json +"extra": { + "config-plugin-options": { + "source-directory": "config", + }, + "config-plugin": { + "params": "params.php", + "web": "web.php" + } +} +``` + +After Composer updates autoload files, such as during `dump-autoload`, +`install`, `require`, `update`, or `remove`, the plugin scans installed +packages for configurations and writes a merge plan to +`config/.merge-plan.php`. The merge plan declares the order of merging +found configurations into the final configuration to be passed to [DI +container](di-container.md). + +At runtime, `Yiisoft\Config\Config` loads the defined config groups +according to that merge plan. Configs are read in three layers: + +1. Vendor package configs with default values. +2. Root package configs from the application `config/` directory. +3. Environment-specific configs from the application. + +> [!WARNING] +> Config keys with the same name are not allowed within a single layer. + +The application template stores configurations in a PHP file instead of +inline JSON: + +```json +"extra": { + "config-plugin-file": "config/configuration.php" +} +``` + +That file returns the same keys you could otherwise define in +`composer.json`: `config-plugin`, `config-plugin-options`, and +`config-plugin-environments`. + +```php +use App\Environment; + +return [ + 'config-plugin-options' => [ + 'source-directory' => 'config', + ], + 'config-plugin' => [ + 'params' => 'common/params.php', + 'params-web' => [ + '$params', + 'web/params.php', + ], + 'params-console' => [ + '$params', + 'console/params.php', + ], + 'bootstrap' => 'common/bootstrap.php', + 'bootstrap-web' => '$bootstrap', + 'bootstrap-console' => '$bootstrap', + 'di' => 'common/di/*.php', + 'di-web' => [ + '$di', + 'web/di/*.php', + ], + 'di-console' => '$di', + 'di-delegates' => [], + 'di-delegates-console' => '$di-delegates', + 'di-delegates-web' => '$di-delegates', + 'di-providers' => [], + 'di-providers-web' => '$di-providers', + 'di-providers-console' => '$di-providers', + 'events' => [], + 'events-web' => '$events', + 'events-console' => '$events', + 'routes' => 'common/routes.php', + ], + 'config-plugin-environments' => [ + Environment::DEV => [ + 'params' => [ + 'environments/dev/params.php', + ], + ], + Environment::TEST => [ + 'params' => [ + 'environments/test/params.php', + ], + ], + Environment::PROD => [ + 'params' => [ + 'environments/prod/params.php', + ], + ], + ], +]; +``` + +Config group names are mapping keys. Their values are file paths relative to +the `source-directory` option, which defaults to the directory containing +`composer.json`. + +- A string value loads one file. +- An array loads and merges multiple files in the given order. +- `?` marks an optional file. +- `*` marks a wildcard path. +- `$group` references another config group to be merged. + +The `params` group is special: its values are available as `$params` in +other config files by default. + +You can read more in the [yiisoft/config +documentation](https://github.com/yiisoft/config/blob/master/README.md). + +## Config files + +Now, as you know how the plugin assembles configs, look at the `config/` +directory structure used by the default application template: + +``` +common/ + bootstrap.php + params.php + routes.php + di/ + *.php +console/ + params.php +environments/ + dev/ + params.php + prod/ + params.php + test/ + params.php +web/ + params.php + di/ + *.php +.merge-plan.php +configuration.php +``` + +This structure follows the groups defined in `config/configuration.php`: + +- `params`, `params-web`, and `params-console` load parameter files from + `common/`, `web/`, and `console/`. +- `di` and `di-web` load container definitions from `common/di/` and + `web/di/`. +- `routes` and `bootstrap` load `common/routes.php` and + `common/bootstrap.php`. +- `config-plugin-environments` adds environment-specific parameter files + from `environments/dev/`, `environments/test/`, and `environments/prod/`. + +At runtime, `.merge-plan.php` stores the assembled merge plan generated from +`configuration.php`. + +### Container configuration + +The application consists of services registered in a [dependency +container](di-container.md). In the default template, direct container +definitions live in `config/common/di/*.php` and `config/web/di/*.php`. + +Definitions from `common/di/` are shared by web and console entry +points. The `di-web` group adds web-specific definitions from `web/di/`. The +`di-console` group currently reuses the shared `di` definitions without +extra files. + +```php + [ + '__construct()' => [ + 'name' => $params['application']['name'], + 'charset' => $params['application']['charset'], + 'locale' => $params['application']['locale'], + ], + ], +]; +``` + +Config plugin passes the special `$params` variable to all config files. The +definition uses it to configure services. + +The guide on ["Dependency injection and container"](di-container.md) +describes the configuration format and the idea of dependency injection in +detail. + +For convenience, there is a naming convention for custom string keys: + +1. Prefix package name such as `yiisoft/cache-file/custom-definition`. +2. In case configuration are for the application itself, skip package + prefix, such as `custom-definition`. + +### Service providers + +As an alternative to registering dependencies directly, you can use service +providers. A service provider is a class that returns a reusable set of +container definitions and extensions. + +The default template exposes three config groups for service providers: +`di-providers`, `di-providers-web`, and `di-providers-console`. In the +template they are initialized as empty arrays in `config/configuration.php`, +and you can later populate them inline or switch them to load values from +files. + +Prefer direct container configuration for application services with a simple +definition: a class name, an interface implementation, constructor arguments +from `$params`, or a closure that creates a single service. + +Use a service provider when the registration itself is a reusable unit: + +- A package registers several related services, aliases, or extensions. +- A service registration also needs supporting definitions. +- The same registration should be reused in several applications. +- Registration depends on optional classes or environment-specific + decisions. + +Use a factory class when construction logic belongs to one service. A +factory returns an object. A service provider returns definitions for +several related services. + +```php +/* @var array $params */ + +// ... +use App\Provider\CacheProvider; +use App\Provider\MiddlewareProvider; +// ... + +return [ + // ... + 'yiisoft/yii-web/middleware' => MiddlewareProvider::class, + 'yiisoft/cache/cache' => new CacheProvider($params['yiisoft/cache-file']['file-cache']['path']), + // ... +]; +``` + +In this config keys are provider names. By convention these are +`vendor/package-name/provider-name`. Values are provider class names or +provider instances. These classes could be either created in the project +itself or provided by a package. + +If you need to configure some options for a service, similar to direct +container configuration, take values from `$params` and pass them to +providers. + +Provider should implement `Yiisoft\Di\ServiceProviderInterface`. Below is a +provider for a cache service: + +```php +use Psr\Container\ContainerInterface; +use Psr\SimpleCache\CacheInterface; +use Yiisoft\Aliases\Aliases; +use Yiisoft\Cache\Cache; +use Yiisoft\Cache\CacheInterface as YiiCacheInterface; +use Yiisoft\Cache\File\FileCache; +use Yiisoft\Di\ServiceProviderInterface; + +final readonly class CacheProvider implements ServiceProviderInterface +{ + public function __construct( + private string $cachePath = '@runtime/cache' + ) + { + } + + public function getDefinitions(): array + { + return [ + CacheInterface::class => function (ContainerInterface $container) { + $aliases = $container->get(Aliases::class); + + return new FileCache($aliases->get($this->cachePath)); + }, + YiiCacheInterface::class => Cache::class, + ]; + } + + public function getExtensions(): array + { + return []; + } +} +``` + +### Routes + +You can configure how the web application responds to certain URLs in +`config/common/routes.php`: + +```php +use App\Web; +use Yiisoft\Router\Group; +use Yiisoft\Router\Route; + +return [ + Group::create() + ->routes( + Route::get('/') + ->action(Web\HomePage\Action::class) + ->name('home'), + ), +]; +``` + +Read more about it in ["Routes"](../runtime/routing.md). + +### Events + +Many services emit certain events that you can attach to. The default +template defines three event config groups in `config/configuration.php`: +`events`, `events-web`, and `events-console`. They are empty by default, but +you can populate them inline or point them to event config files. + +The configuration is an array where keys are event names and values are +arrays of handlers: + +```php +return [ + EventName::class => [ + // Just a regular closure, it will be called from the Dispatcher "as is". + static fn (EventName $event) => someStuff($event), + + // A regular closure with an extra dependency. All the parameters after the first one (the event itself) + // will be resolved from your DI container within `yiisoft/injector`. + static fn (EventName $event, DependencyClass $dependency) => someStuff($event), + + // An example with a regular callable. If the `staticMethodName` method has some dependencies, + // they will be resolved the same way as in the earlier example. + [SomeClass::class, 'staticMethodName'], + + // Non-static methods are allowed too. In this case, `SomeClass` will be instantiated by your DI container. + [SomeClass::class, 'methodName'], + + // An object of a class with the `__invoke` method implemented + new InvokableClass(), + + // In this case, the `InvokableClass` with the `__invoke` method will be instantiated by your DI container + InvokableClass::class, + + // Any invokable class definition may be here as long as `$container->has('the definition')` is true. + 'di-alias' + ], +]; +``` + +Read more about it in ["Events"](events.md). + + +### Parameters + +Base parameters are stored in `config/common/params.php`. They are then +extended by `config/web/params.php`, `config/console/params.php`, and +environment-specific files under `config/environments/`. + +> [!TIP] +> Don't use parameters, constants, or environment variables directly in your application, configure +> services instead. + +The default application `common/params.php` looks like the following: + +```php + require __DIR__ . '/application.php', + + 'yiisoft/aliases' => [ + 'aliases' => require __DIR__ . '/aliases.php', + ], + + 'yiisoft/view' => [ + 'basePath' => null, + 'parameters' => [ + 'assetManager' => Reference::to(AssetManager::class), + 'applicationParams' => Reference::to(ApplicationParams::class), + 'aliases' => Reference::to(Aliases::class), + 'urlGenerator' => Reference::to(UrlGeneratorInterface::class), + 'currentRoute' => Reference::to(CurrentRoute::class), + ], + ], + + 'yiisoft/yii-view-renderer' => [ + 'viewPath' => null, + 'layout' => '@src/Web/Shared/Layout/Main/layout.php', + 'injections' => [ + Reference::to(CsrfViewInjection::class), + ], + ], +]; +``` + +For convenience, there is a naming convention about parameters: + +1. Group parameters package name such as `yiisoft/cache-file`. +2. In case parameters are for the application itself, as in `application`, + skip package prefix. +3. In case there are many services in the package, such as `file-target` and + `file-rotator` in `yiisoft/log-target-file` package, group parameters by + service name. +4. Use `enabled` as parameter name to be able to disable or enable a + service, such as `yiisoft/yii-debug`. + +### Package configs + +Config plugin does not copy vendor package configs automatically. It loads +them directly from `vendor/` as the vendor layer and combines them with the +root package and environment-specific layers. + +If you want to customize a package config file in your application, use the +`yii-config-copy` Composer command to copy it into your `config/` directory, +usually under `config/packages/`. Once copied, the file becomes part of the +root package layer, so it can override vendor defaults. + +The merge plan stored in `.merge-plan.php` defines how config groups are +assembled. If you add new config files or directories and update the root +package configuration, rebuild the merge plan with `composer +yii-config-rebuild`. diff --git a/src/pt-BR/guide/concept/di-container.md b/src/pt-BR/guide/concept/di-container.md new file mode 100644 index 00000000..9cfc5312 --- /dev/null +++ b/src/pt-BR/guide/concept/di-container.md @@ -0,0 +1,346 @@ +# Dependency injection and container + +## Dependency injection + +There are two ways of re-using things in OOP: inheritance and composition. + +Inheritance is simple: + +```php +class Cache +{ + public function getCachedValue($key) + { + // .. + } +} + +final readonly class CachedWidget extends Cache +{ + public function render(): string + { + $output = $this->getCachedValue('cachedWidget'); + if ($output !== null) { + return $output; + } + // ... + } +} +``` + +The issue here is that these two are becoming unnecessarily coupled or +inter-dependent, making them more fragile. + +Another way to handle this is composition: + +```php +interface CacheInterface +{ + public function getCachedValue($key); +} + +final readonly class Cache implements CacheInterface +{ + public function getCachedValue($key) + { + // .. + } +} + +final readonly class CachedWidget +{ + public function __construct( + private CacheInterface $cache + ) + { + } + + public function render(): string + { + $output = $this->cache->getCachedValue('cachedWidget'); + if ($output !== null) { + return $output; + } + // ... + } +} +``` + +We've avoided unnecessary inheritance and used `CacheInterface` in the +`CacheWidget` to reduce coupling. You can replace cache implementation +without changing `CachedWidget` so it's becoming more stable. The less edits +are made to the code, the less chance of breaking it. + +The `CacheInterface` here is a dependency: a contract our object needs to +function. In other words, our object depends on the contract. + +The process of putting an instance of a contract into an object +(`CachedWidget`) is called dependency injection. There are many ways to +perform it: + +- Constructor injection. Best for mandatory dependencies. +- Method injection. Best for optional dependencies. +- Property injection. Better to be avoided in PHP except maybe data transfer + objects. + +### Why use private properties + +In the composition example above, note that the `$cache` property is +declared as `private`. + +This approach embraces composition by ensuring objects have well-defined +interfaces for interaction rather than direct property access, making the +code more maintainable and less prone to certain types of mistakes. + +This design choice provides several benefits: + +- **Encapsulation**: Private properties with getters/setters allow you to + control access and make future changes without breaking existing code. +- **Data integrity**: Setters can validate, normalize, or format values + before storing them, ensuring properties contain valid data. +- **Immutability**: Private properties enable immutable object patterns + where setter `with*()` methods return new instances rather than modifying + the current one. +- **Flexibility**: You can create read-only or write-only properties or add + additional logic to property access later. + + +## DI container + +Injecting basic dependencies is straightforward. You're choosing a place +where you don't care about dependencies, which is usually an action handler, +which you aren't going to unit-test ever, create instances of dependencies +needed and pass these to dependent classes. + +It works well when there are few dependencies overall and when there are no +nested dependencies. When there are many and each dependency has +dependencies itself, instantiating the whole hierarchy becomes a tedious +process, which requires lots of code and may lead to hardly debuggable +mistakes. + +Additionally, lots of dependencies, such as certain third-party API +wrappers, are the same for any class using it. So it makes sense to: + +- Define how to instantiate such common dependencies. +- Instantiate them when required and only once per request. + +That's what dependency containers are for. + +A dependency injection (DI) container is an object that knows how to +instantiate and configure objects and all objects they depend on. + +Yii provides the DI container feature through the +[yiisoft/di](https://github.com/yiisoft/di) package and +[yiisoft/injector](https://github.com/yiisoft/injector) package. + +> [!NOTE] +> The container contains only shared instances. If you need a factory, use the dedicated +> [yiisoft/factory](https://github.com/yiisoft/factory) package. + +> [!TIP] +> [Martin Fowler's article](https://martinfowler.com/articles/injection.html) has well +> explained why DI container is useful. Here we will mainly explain the usage of the DI container provided by Yii. + +### Configuring container + +Because to create a new object you need its dependencies, you should +register them as early as possible. You can do it in the application +configuration, `config/web.php`. For the following service: + +```php +final class MyService implements MyServiceInterface +{ + public function __construct(int $amount) + { + } + + public function setDiscount(int $discount): void + { + + } +} +``` + +configuration could be: + +```php +return [ + MyServiceInterface::class => [ + 'class' => MyService::class, + '__construct()' => [42], + 'setDiscount()' => [10], + ], +]; +``` + +That's equal to the following: + +```php +$myService = new MyService(42); +$myService->setDiscount(10); +``` + +You can provide arguments with names as well: + +```php +return [ + MyServiceInterface::class => [ + 'class' => MyService::class, + '__construct()' => ['amount' => 42], + 'setDiscount()' => ['discount' => 10], + ], +]; +``` + +That's basically it. You define a map of interfaces to classes and define +how to configure them. When an interface is requested in constructor or +elsewhere, container creates an instance of a class and configures it as per +the configuration: + +```php +final class MyAction +{ + public function __construct( + private readonly MyServiceInterface $myService + ) { + } + + public function __invoke() + { + $this->myService->doSomething(); + } +} +``` + +There are extra methods of declaring dependency configuration. + +For simplest cases where there are no custom values needed and all the +constructor dependencies could be obtained from a container, you can use a +class name as a value. + +```php +interface EngineInterface +{ + +} + +final class EngineMarkOne implements EngineInterface +{ + public function __construct(CacheInterface $cache) { + } +} +``` + +In the above example, if we already have cache defined in the container, +nothing besides the class name is needed: + +```php +return [ + // declare a class for an interface, resolve dependencies automatically + EngineInterface::class => EngineMarkOne::class, +]; +``` + +If you have a dependency that has public properties, you can configure it as +well. + + +```php +final class NameProvider +{ + public string $name; +} +``` + +Here's how to do it for the example above: + +```php +NameProvider::class => [ + 'class' => NameProvider::class, + '$name' => 'Alex', +], +``` + +In this example, you may notice `NameProvider` specified twice. The key is +what you may request as dependency and the value is how to create it. + +If the configuration is tricky and requires some logic, a closure can be +used: + +```php +MyServiceInterface::class => static function(ContainerInterface $container) { + return new MyService($container->get('db')); +}, +``` + +Additionally, to `ContainerInterface`, you can request any registered +service directly as a closure parameter. The injector will automatically +resolve and inject these: + +```php +MyServiceInterface::class => static function(ConnectionInterface $db) { + return new MyService($db); +}, +``` + +It's possible to use a static method call: + +```php +MyServiceInterface::class => [MyFactory::class, 'create'], +``` + +Or an instance of an object: + +```php +MyServiceInterface::class => new MyService(), +``` + +### Injecting dependencies properly + +Directly referencing a container in a class is a bad idea since the code +becomes non-generic, coupled to the container interface and, what's worse, +dependencies are becoming hidden. Because of that, Yii inverts the control +by automatically injecting objects from a container in some constructors and +methods based on method argument types. + +This is primarily done in constructor and handing method of action handlers: + +```php +use \Yiisoft\Cache\CacheInterface; + +final readonly class MyController +{ + public function __construct( + private CacheInterface $cache + ) + { + $this->cache = $cache; + } + + public function actionDashboard(RevenueReport $report) + { + $reportData = $this->cache->getOrSet('revenue_report', function() use ($report) { + return $report->getData(); + }); + + return $this->render('dashboard', [ + 'reportData' => $reportData, + ]); + } +} +``` + +Since it's [yiisoft/injector](https://github.com/yiisoft/injector) that +instantiates and calls action handler, it checks the constructor and method +argument types, gets dependencies of these types from a container and passes +them as arguments. That's usually called auto-wiring. It happens for +sub-dependencies as well, that's if you don't give dependency explicitly, +the container would check if it has such a dependency first. It's enough to +declare a dependency you need, and it would be got from a container +automatically. + + +## References + +- [Inversion of Control Containers and the Dependency Injection pattern by + Martin Fowler](https://martinfowler.com/articles/injection.html) diff --git a/src/pt-BR/guide/concept/events.md b/src/pt-BR/guide/concept/events.md new file mode 100644 index 00000000..0f3ac8fb --- /dev/null +++ b/src/pt-BR/guide/concept/events.md @@ -0,0 +1,197 @@ +# Events + +Events allow you to run custom code at certain execution points without +changing the code that emits the event. You attach a custom code called a +listener to an event. When the event is dispatched, the listener is +executed. + +For example, when a user signs up, you need to send a welcome email. You can +do it in `SignupService`. Later, when you also need to resize the user's +avatar image, the service has to know about that too. + +A cleaner flow is to dispatch a `UserSignedUp` event from +`SignupService`. The welcome email sender and the avatar processor listen to +this event. Additional signup-related work can be added by registering +another listener. + +Yii uses [yiisoft/yii-event](https://github.com/yiisoft/yii-event) for +application event configuration. It builds on the +[yiisoft/event-dispatcher](https://github.com/yiisoft/event-dispatcher) +package, which provides a [PSR-14](https://www.php-fig.org/psr/psr-14/) +compatible event dispatcher. + +## Event classes + +An event is an object. It usually contains data that listeners need: + +```php +final readonly class UserSignedUp +{ + public function __construct( + public SignupForm $form, + ) {} +} +``` + +## Event listeners + +An event listener is a [PHP +callable](https://www.php.net/manual/en/language.types.callable.php) that +receives an event: + +```php +static function (UserSignedUp $event): void { + // Send a welcome email. +} +``` + +You can also use an invokable class: + +```php +final readonly class WelcomeEmailSender +{ + public function __invoke(UserSignedUp $event): void + { + // Send a welcome email. + } +} +``` + +## Configuring event listeners + +In an application, configure listeners in: + +- `config/events.php` for all application types. +- `config/events-web.php` for web application events. +- `config/events-console.php` for console application events. + +The configuration is an array where keys are event class names and values +are lists of listeners: + +```php + [ + WelcomeEmailSender::class, + static fn (UserSignedUp $event, AvatarProcessor $avatarProcessor) => $avatarProcessor->resize($event->form), + ], +]; +``` + +The listener may be a closure, a callable array, an invokable object, an +invokable class name, or a DI alias. For closure and callable array +listeners, parameters after the first event parameter are resolved from the +DI container. Invokable class names are instantiated by the container. + +Dependencies are resolved when the event is dispatched. + +## Dispatching events + +To dispatch an event, use `Psr\EventDispatcher\EventDispatcherInterface`: + +```php +use Psr\EventDispatcher\EventDispatcherInterface; + +final readonly class SignupService +{ + public function __construct( + private EventDispatcherInterface $eventDispatcher, + ) {} + + public function signup(SignupForm $form): void + { + // Sign up the user. + + $this->eventDispatcher->dispatch(new UserSignedUp($form)); + } +} +``` + +The dispatcher asks a listener provider for listeners that match the event +and calls them one by one. + +## Event listener order + +When several listeners are configured for the same event, they are called in +the order they are listed in the config. If an event implements +`Psr\EventDispatcher\StoppableEventInterface`, the dispatcher checks +`isPropagationStopped()` before calling the next listener. When it returns +`true`, the dispatcher stops processing the event. + +Keep listeners independent where possible. Ordering is useful for technical +needs, but business logic is usually easier to maintain when each listener +can run on its own. + +## Event hierarchy + +Events don't have names or wildcard matching. Event class names, interfaces, +and inheritance can be used when one listener should handle several related +events: + +```php +interface DocumentEvent +{ +} + +final readonly class BeforeDocumentProcessed implements DocumentEvent +{ +} + +final readonly class AfterDocumentProcessed implements DocumentEvent +{ +} +``` + +With the interface, you can listen to all document-related events: + +```php +use Yiisoft\EventDispatcher\Provider\ListenerCollection; +use Yiisoft\EventDispatcher\Provider\Provider; + +$listeners = (new ListenerCollection()) + ->add(static function (DocumentEvent $event): void { + // Log document events. + }); + +$provider = new Provider($listeners); +``` + +## Manual listener provider setup + +In an application, use event configuration. For package-level code or tests, +you can create a listener provider manually: + +```php +use Yiisoft\EventDispatcher\Dispatcher\Dispatcher; +use Yiisoft\EventDispatcher\Provider\ListenerCollection; +use Yiisoft\EventDispatcher\Provider\Provider; + +$listeners = (new ListenerCollection()) + ->add(static function (UserSignedUp $event): void { + // Send a welcome email. + }); + +$provider = new Provider($listeners); +$dispatcher = new Dispatcher($provider); + +$dispatcher->dispatch(new UserSignedUp($form)); +``` + +`ListenerCollection::add()` returns a new collection instance. Assign the result when building a collection step by step: + +```php +$listeners = new ListenerCollection(); +$listeners = $listeners->add( + static function (UserSignedUp $event): void { + // Send a welcome email. + }, + UserSignedUp::class, +); +``` diff --git a/src/pt-BR/guide/concept/immutability.md b/src/pt-BR/guide/concept/immutability.md new file mode 100644 index 00000000..f1faeeed --- /dev/null +++ b/src/pt-BR/guide/concept/immutability.md @@ -0,0 +1,160 @@ +# Immutability + +Immutability means an object's state cannot change after it has been +created. Instead of modifying an instance, you create a new instance with +the desired changes. This approach is common for value objects such as +Money, IDs, and DTOs. It helps to avoid accidental side effects: methods +cannot silently change shared state, which makes code easier to reason +about. + +## Mutable pitfalls (what we avoid) + +```php +// A shared base query built once and reused: +$base = Post::find()->where(['status' => Post::STATUS_PUBLISHED]); + +// Somewhere deep in the code we only need one post: +$one = $base->limit(1)->one(); // mutates the underlying builder (sticky limit!) + +// Later we reuse the same $base expecting a full list: +$list = $base->orderBy(['created_at' => SORT_DESC])->all(); +// Oops: still limited to 1 because the previous limit(1) modified $base. +``` + +## Creating an immutable object in PHP + +There is no direct way to modify an instance, but you can use clone to +create a new instance with the desired changes. That is what `with*` +methods do. + +```php +final class Money +{ + public function __construct( + private int $amount, + private string $currency, + ) { + $this->validateAmount($amount); + $this->validateCurrency($currency); + } + + private function validateAmount(string $amount) + { + if ($amount < 0) { + throw new InvalidArgumentException('Amount must be positive.'); + } + } + + private function validateCurrency(string $currency) + { + if (!in_array($currency, ['USD', 'EUR'])) { + throw new InvalidArgumentException('Invalid currency. Only USD and EUR are supported.'); + } + } + + public function withAmount(int $amount): self + { + $this->validateAmount($amount); + + if ($amount === $this->amount) { + return $this; + } + + $clone = clone $this; + $clone->amount = $amount; + return $clone; + } + + public function withCurrency(string $currency): self + { + $this->validateCurrency($currency); + + if ($currency === $this->currency) { + return $this; + } + + $clone = clone $this; + $clone->currency = $currency; + return $clone; + } + + public function amount(): int + { + return $this->amount; + } + + public function currency(): string + { + return $this->currency; + } + + public function add(self $money): self + { + if ($money->currency !== $this->currency) { + throw new InvalidArgumentException('Currency mismatch. Cannot add money of different currency.'); + } + return $this->withAmount($this->amount + $money->amount); + } +} + +$price = new Money(1000, 'USD'); +$discounted = $price->withAmount(800); +// $price is still 1000 USD, $discounted is 800 USD +``` + +- We mark the class `final` to prevent subclass mutations; alternatively, + design for extension carefully. +- Validate in the constructor and `with*` methods so every instance is + always valid. + +> [!TIP] +> If you define a simple DTO, you can use modern PHP `readonly` and leave properties `public`. The `readonly` keyword +> would ensure that the properties cannot be modified after the object is created. + +## Using clone (and why it is inexpensive) + +PHP's clone performs a shallow copy of the object. For immutable value +objects that contain only scalars or other immutable objects, shallow +cloning is enough and fast. In modern PHP, cloning small value objects is +inexpensive in both time and memory. + +If your object holds mutable sub-objects that must also be copied, implement +`__clone` to deep-clone them: + +```php +final class Order +{ + public function __construct( + private Money $total + ) {} + + public function total(): Money + { + return $this->total; + } + + public function __clone(): void + { + // Money is immutable in our example, so a deep clone is not required. + // If it were mutable, you could do: $this->total = clone $this->total; + } + + public function withTotal(Money $total): self + { + $clone = clone $this; + $clone->total = $total; + return $clone; + } +} +``` + +## Usage style + +- Build a value object once and pass it around. If you need a change, use a + `with*` method that returns a new instance. +- Prefer scalar/immutable fields inside immutable objects; if a field can + mutate, isolate it and deep-clone in `__clone` when needed. + +Immutability aligns well with Yii's preference for predictable, +side-effect-free code and makes services, caching, and configuration more +robust. diff --git a/src/pt-BR/guide/databases/db-migrations.md b/src/pt-BR/guide/databases/db-migrations.md new file mode 100644 index 00000000..c5751ce0 --- /dev/null +++ b/src/pt-BR/guide/databases/db-migrations.md @@ -0,0 +1,450 @@ +# Migrations + +During the course of developing and maintaining a database-driven +application, the structure of the database being used evolves just like the +source code does. For example, during the development of an application, a +new table may be found necessary; after the application is deployed to +production, it may be discovered that an index should be created to improve +the query performance; and so on. Because a database structure change often +requires some source code changes, Yii supports the so-called *database +migration* feature that allows you to keep track of database changes in +terms of *database migrations* which are version-controlled together with +the source code. + +The following steps show how database migration can be used by a team during +development: + +1. Tim creates a new migration (e.g. creates a new table, changes a column + definition, etc.). +2. Tim commits the new migration into the source control system (e.g. Git, + Mercurial). +3. Doug updates his repository from the source control system and receives + the new migration. +4. Doug applies the migration to his local development database, thereby + synchronizing his database to reflect the changes that Tim has made. + +And the following steps show how to deploy a new release with database +migrations to production: + +1. Scott creates a release tag for the project repository that contains some + new database migrations. +2. Scott updates the source code on the production server to the release + tag. +3. Scott applies any accumulated database migrations to the production + database. + +```mermaid +sequenceDiagram + participant Tim + participant VCS as Source control + participant Doug + participant LocalDB as Local development database + participant Scott + participant ProdServer as Production server + participant ProdDB as Production database + + Tim->>Tim: Creates a new migration + Tim->>VCS: Commits the new migration + Doug->>VCS: Updates his repository and receives the new migration + Doug->>LocalDB: Applies the migration locally + + Scott->>VCS: Creates a release tag with new migrations + Scott->>ProdServer: Updates source code to the release tag + Scott->>ProdDB: Applies accumulated migrations +``` + +Yii provides a set of migration command line tools that allow you to: + +* create new migrations; +* apply migrations; +* revert migrations; +* re-apply migrations; +* show migration history and status. + +All these tools are accessible through the command `yii migrate`. In this +section we will describe in detail how to accomplish various tasks using +these tools. + +> [!TIP] +> Migrations could affect not only database schema but adjust existing data to fit new schema, create RBAC +hierarchy or clean up cache. + +> [!NOTE] +> When manipulating data using a migration you may find that using your Active Record or entity classes +> for this might be useful because some of the logic is already implemented there. Keep in mind however, that in contrast +> to code written in the migrations, whose nature is to stay constant forever, application logic is subject to change. +> So when using Active Record or entity classes in migration code, changes to the logic in the source code +> may accidentally break the existing migrations. For this reason migration code should be kept independent of other +> application logic such. + +## Initial configuration + +To use migrations, install +[yiisoft/db-migration](https://github.com/yiisoft/db-migration/) package: + +```shell +make composer require yiisoft/db-migration +``` + +Create a directory to store migrations `src/Migration` right in the project +root. + +Add the following configuration to `config/common/params.php`: + +```php +'yiisoft/db-migration' => [ + 'newMigrationNamespace' => 'App\\Migration', + 'sourceNamespaces' => ['App\\Migration'], +], +``` + +If you want to place migrations elsewhere, you can define the path in +`newMigrationPath`. If your migrations to be applied are from multiple +sources, such as external modules, `sourcePaths` could be used to define +these. + +You need a database connection configured as well. See [Working with +databases](../start/databases.md) for an example of configuring it for +PostgreSQL. + +## Creating a migration + +To create a new empty migration, run the following command: + +```sh +make shell +./yii migrate:create +``` + +The required `name` argument gives a brief description about the new +migration. For example, if the migration is about creating a new table named +*news*, you may use the name `create_news_table` and run the following +command: + +``` +make shell +./yii migrate:create create_news_table +``` + + +> [!NOTE] +> Because the `name` argument will be used as part of the generated migration class name, +> it should only contain letters, digits, and/or underscore characters. + +The above command will create a new PHP class file named +`src/Migration/M251225221906CreateNewsTable.php`. The file contains the +following code which mainly declares a migration class with the skeleton +code: + +```php +columnBuilder(); + + $b->createTable('news', [ + 'id' => $cb::uuidPrimaryKey(), + 'title' => $cb::string()->notNull(), + 'content' => $cb::text(), + ]); + } + + public function down(MigrationBuilder $b): void + { + $b->dropTable('news'); + } +} +``` + +Migration builder `$b` in the above manages database schema while the column +builder `$cb` manages column types. Both allow using *abstract types*. When +a migration is applied to a particular database, the abstract types will be +translated into the corresponding database physical types and corresponding +SQL to define them. + +Methods available in migration builder belong to the following types: + +- Raw queries + - getDb — to get database connection instance. + - execute — to execute raw SQL query. +- Data + - insert / update / delete + - batchInsert + - upsert +- Tables and views + - createTable / renameTable / dropTable + - truncateTable + - addCommentOnTable / dropCommentFromTable + - createView / dropView +- Columns + - addColumn / renameColumn / alterColumn / dropColumn + - addCommentOnColumn / dropCommentFromColumn +- Keys and indexes + - addPrimaryKey / dropPrimaryKey + - addForeignKey / dropForeignKey + - createIndex / dropIndex + +Additionally, there's a `columnBuilder()` which is used to obtain a column +builder as in example above. The builder has static methods that define +various column types: + +- Keys + - primaryKey + - smallPrimaryKey + - bigPrimaryKey + - uuidPrimaryKey +- Boolean + - boolean +- Numbers + - bit + - tinyint + - smallint + - integer + - bigint + - flat + - double + - decimal +- Strings + - char + - string + - text +- Date and time + - timestamp + - datetime + - datetimeWithTimezone + - time + - timeWithTimezone + - date +- Special types + - money + - binary + - uuid + - array + - structured + - json +- enum + +All the above methods create a base type which could be adjusted with +additional methods: + +- null / notNull +- defaultValue +- unique +- scale / size / unsigned +- primaryKey / autoIncrement +- check +- comment +- computed +- extra +- reference + +### Irreversible migrations + +Not all migrations are reversible. For example, if the `up()` method deletes +a row of a table, you may not be able to recover this row in the `down()` +method. Sometimes, you may be just too lazy to implement the `down()`, +because it is not very common to revert database migrations. In this case, +you should implement `Yiisoft\Db\Migration\MigrationInterface` that has +`up()` only. + + +### Transactional migrations + +While performing complex DB migrations, it is important to ensure each +migration to either succeed or fail as a whole so that the database can +maintain integrity and consistency. To achieve this goal, it is recommended +that you may enclose the DB operations of each migration in a transaction +automatically by adding `TransactionalMigrationInterface` to `implements` of +your migration. + +As a result, if any operation in the `up()` or `down()` method fails, all +prior operations will be rolled back automatically. + +> Note: Not all DBMS support transactions. And some DB queries cannot be put into a transaction. For some examples, +please refer to [implicit commit](https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html). + +## Generating a migration + +Instead of writing migrations by hand, the command provides a convenient way +generate some of the code. + +```shell +make shell +./yii migrate:create -- my_first_table --command=table --fields=name,example --table-comment=my_first_table +``` + +That would generate the following: + +```php +columnBuilder(); + + $b->createTable('my_first_table', [ + 'id' => $columnBuilder::primaryKey(), + 'name', + 'example', + ]); + + $b->addCommentOnTable('my_first_table', 'my_first_table'); + } + + public function down(MigrationBuilder $b): void + { + $b->dropTable('my_first_table'); + } +} +``` + +Commands available are: + +- create - empty migration. +- table - creating a table. Use `--fields` specify a list of fields to + use. Types could be specified as well such as + `id:primaryKey,name:string:defaultValue("Alex"),user_id:integer:foreignKey,category_id2:integer:foreignKey(category + id2)`. +- dropTable - dropping a table. +- addColumn - adding a column. +- dropColumn - dropping a column. +- junction - creating a junction table. Use `--and` specify a second table. + +## Applying Migrations + +To upgrade a database to its latest structure, you should apply all +available new migrations using the following command: + +``` +./yii migrate:up +``` + +This command will list all migrations that have not been applied so far. If +you confirm that you want to apply these migrations, it will run the `up()` +method in every new migration class, one after another, in the order of +their timestamp values. If any of the migrations fails, the command will +quit without applying the rest of the migrations. + +For each migration that has been successfully applied, the command will +insert a row into a database table named `migration` to record the +successful application of the migration. This will allow the migration tool +to identify which migrations have been applied and which have not. + +Sometimes, you may only want to apply one or a few new migrations, instead +of all available migrations. You can do so by specifying the number of +migrations that you want to apply when running the command. For example, +the following command will try to apply the next three available migrations: + +``` +./yii migrate:up --limit=3 +``` + +## Reverting Migrations + +To revert (undo) one or multiple migrations that have been applied before, +you can run the following command: + +``` +./yii migrate:down # revert the most recently applied migration +./yii migrate:down --limit=3 # revert the most 3 recently applied migrations +./yii migrate:down --all # revert all migrations +``` + +> Note: Not all migrations are reversible. Trying to revert such migrations will cause an error and stop the +entire reverting process. + + +## Redoing Migrations + +Redoing migrations means first reverting the specified migrations and then +applying again. This can be done as follows: + +``` +./yii migrate:redo # redo the last applied migration +./yii migrate:redo --limit=3 # redo the last 3 applied migrations +./yii migrate:redo --all # redo all migrations +``` + +> Note: If a migration is not reversible, you will not be able to redo it. + +## Listing Migrations + +To list which migrations have been applied and which are not, you may use +the following commands: + +``` +./yii migrate/history # showing the last 10 applied migrations +./yii migrate:history --limit=5 # showing the last 5 applied migrations +./yii migrate:history --all # showing all applied migrations + +./yii migrate:new # showing the first 10 new migrations +./yii migrate:new --limit=5 # showing the first 5 new migrations +./yii migrate:new --all # showing all new migrations +``` + +### Upgrading from Yii 2.0 + +Migrations in Yii 2.0 and the +[yiisoft/db-migration](https://github.com/yiisoft/db-migration/) package are +not compatible, and the `migration` table is also not compatible. + +A probable solution is to use structure dumps and rename the old `migration` +table. Upon the initial execution of migrations, a new `migration` table +with new fields will be created. All further changes in the database schema +are applied using the new `migration` component and recorded in the new +migration table. diff --git a/src/pt-BR/guide/glossary.md b/src/pt-BR/guide/glossary.md new file mode 100644 index 00000000..bbf357a0 --- /dev/null +++ b/src/pt-BR/guide/glossary.md @@ -0,0 +1,254 @@ +# A + +## action + +Action is a callable, class, or class method that handles a matched route +and returns a response. Read more in ["Actions"](structure/action.md). + +## alias + +Alias is a string used by Yii to refer to the class or directory such as +`@app/vendor`. Read more in ["Aliases"](concept/aliases.md). + +## application + +Application is an object that starts up, handles a request through +configured middleware, and shuts down. Read more in +["Application"](structure/application.md). + +## asset + +Asset refers to a resource file. Typically, it contains JavaScript or CSS +code but can be any static content accessed via HTTP. Read more in +["Assets"](views/asset.md). + +## asset bundle + +Asset bundle is a PHP class that declares a group of CSS, JavaScript, image, +or font files that should be published and registered together. Read more +in ["Asset Bundles"](views/asset.md#asset-bundles). + +## authentication + +Authentication is the process of determining the identity of the current +user. Read more in ["Authentication"](security/authentication.md). + +## authorization + +Authorization is the process of checking whether an authenticated or +anonymous user is allowed to perform an action. Read more in +["Authorization"](security/authorization.md). + +## autoloading + +Autoloading is the process of loading PHP classes automatically when they +are first used. Read more in ["Class autoloading"](concept/autoloading.md). + +# B + +## bootstrap + +Bootstrap is application startup code that prepares services, configuration, +and runtime state before request handling. Read more in +["Configuration"](concept/configuration.md). + +# C + +## configuration + +Configuration may refer either to the process of setting properties of an +object or to a configuration file that stores settings for an object, or a +class of objects. Read more in ["Configuration"](concept/configuration.md). + +## container + +Container is an object that creates services, resolves their dependencies, +and returns configured instances. Read more in ["DI +container"](concept/di-container.md#di-container). + +## controller + +Controller is a class that groups action methods for related routes. Read +more in ["Actions"](structure/action.md). + +## cookie + +Cookie is a small piece of data stored by a browser and sent with later +requests to the same site. Read more in ["Cookies"](runtime/cookies.md). + +## CSRF + +CSRF means cross-site request forgery, an attack where another site tries to +make a user's browser submit an unwanted request to your application. Read +more in ["Avoiding CSRF"](security/best-practices.md#avoiding-csrf). + +# D + +## DI + +Dependency injection is a programming technique where an object receives its +dependencies from the outside. Read more in ["Dependency injection and +container"](concept/di-container.md). + +# E + +## entry script + +Entry script is the first PHP script executed for a web or console +application. Read more in ["Entry scripts"](structure/entry-script.md). + +## event + +Event is an object that represents something that happened and can be passed +to listeners. Read more in ["Events"](concept/events.md). + +# H + +## handler + +Handler is callable code selected by routing or middleware to process a +request and produce a response. Read more in ["Routing and URL +generation"](runtime/routing.md). + +# I + +## installation + +Installation is a process of preparing something to work either by following +a readme file or by executing a specially prepared script. In the case of +Yii, it's setting permissions and fulfilling software requirements. + +# L + +## layout + +Layout is a view template that wraps page-specific content with shared page +structure. Read more in ["Working with +layouts"](views/view.md#working-with-layouts). + +# M + +## migration + +Migration is a versioned PHP class that applies or reverts a database schema +or data change. Read more in ["Migrations"](databases/db-migrations.md). + +## middleware + +Middleware is a processor in the request processing stack. Given a request, +it may either produce a response or do some action and pass processing to +the next middleware. Read more in ["Middleware"](structure/middleware.md). + +## model + +Model is an object that represents application data and usually contains +validation or business rules for that data. Read more in ["Working with +forms"](start/forms.md). + +## module + +The module is a namespace that groups some code based on a use-case. It's +typically used within the main application and may contain any source code, +define additional URL handlers or console commands. + +# N + +## namespace + +Namespace refers to a [PHP language +feature](https://www.php.net/manual/en/language.namespaces.php) to group +multiple classes under a certain name. + +# P + +## package + +A package usually refers to [Composer +package](https://getcomposer.org/doc/). It's code ready for reuse and +redistribution installable automatically via a package manager. + +## parameter + +Parameter is a configuration value that can be used by application or +package config files. Read more in +["Parameters"](concept/configuration.md#parameters). + +# Q + +## queue + +A queue is a data structure that processes items in first-in, first-out +order. Yii has a [yiisoft/queue](https://github.com/yiisoft/queue) package. + +# R + +## request + +Request is a PSR-7 object that represents an incoming HTTP message, +including method, URI, headers, body, uploaded files, and attributes. Read +more in ["Request"](runtime/request.md). + +## response + +Response is a PSR-7 object that represents an outgoing HTTP message, +including status code, headers, and body. Read more in +["Response"](runtime/response.md). + +## route + +Route describes which request method and URL pattern should be handled by +which action or middleware. Read more in ["Routing and URL +generation"](runtime/routing.md). + +## rule + +The rule usually refers to a validation rule of the +[yiisoft/validator](https://github.com/yiisoft/validator) package. It holds +a set of parameters for checking if a data set is valid. "Rule handler" +does the actual processing. + +# S + +## service + +Service is a focused object that performs application work or provides +infrastructure behavior and is usually stored in the DI container. Read +more in ["Service components"](structure/service.md). + +## service provider + +Service provider is a class that registers related service definitions for +the DI container. Read more in ["Service +providers"](concept/configuration.md#service-providers). + +## session + +Session is server-side storage associated with a browser across multiple +requests. Read more in ["Sessions"](runtime/sessions.md). + +# T + +## template + +Template is a file used by a view or template engine to produce presentation +output such as HTML. Read more in ["Views"](views/view.md). + +# V + +## vendor + +A vendor is an organization or individual developer providing code in the +form of packages. It also may refer to [Composer's `vendor` +directory](https://getcomposer.org/doc/). + +## view + +View is responsible for presenting data to end users, usually by executing a +template with provided data. Read more in ["Views"](views/view.md). + +# W + +## widget + +Widget is a reusable view component that renders a piece of user interface. +Read more in ["Widgets"](views/widget.md). diff --git a/src/pt-BR/guide/index.md b/src/pt-BR/guide/index.md new file mode 100644 index 00000000..0c17772d --- /dev/null +++ b/src/pt-BR/guide/index.md @@ -0,0 +1,162 @@ +# O guia definitivo do Yii3 + +Este guia é publicado sob os [Termos da documentação do +Yii](https://www.yiiframework.com/license#docs). + +## Introdução + +- [Sobre o Yii](intro/what-is-yii.md) +- [Atualizando a partir da versão 1.1](intro/upgrade-from-v1.md) +- [Atualizando a partir da versão 2.0](intro/upgrade-from-v2.md) + +## Primeiros passos + +- [O que você precisa saber?](start/prerequisites.md) +- [Criando um projeto](start/creating-project.md) +- [Fluxo da aplicação](start/workflow.md) +- [Dizendo olá](start/hello.md) +- [Trabalhando com formulários](start/forms.md) +- [Trabalhando com bancos de dados](start/databases.md) +- [Gerando código com o Gii](start/gii.md) TODO +- [Seguindo em frente](start/looking-ahead.md) +- [Aplicações de demonstração](start/demo-apps.md) + +## Conceitos principais + +- [Aliases](concept/aliases.md) +- [Autoload](concept/autoloading.md) +- [Configuração](concept/configuration.md) +- [Container de injeção de dependência](concept/di-container.md) +- [Eventos](concept/events.md) +- [Imutabilidade](concept/immutability.md) + +## Estrutura da aplicação + +- [Visão geral da estrutura da aplicação](structure/overview.md) +- [Scripts de entrada](structure/entry-script.md) +- [Aplicação](structure/application.md) +- [Módulos](structure/module.md) +- [Actions](structure/action.md) +- [Middleware](structure/middleware.md) + +## Pacotes + +- [Usando pacotes](structure/package.md) +- [Projetando pacotes](structure/designing-packages.md) + +## Tratando requisições + +- [Roteamento e geração de URLs](runtime/routing.md) +- [Requisição](runtime/request.md) +- [Resposta](runtime/response.md) +- [Sessões](runtime/sessions.md) +- [Cookies](runtime/cookies.md) +- [Tratamento de erros](runtime/handling-errors.md) +- [Logs](runtime/logging.md) + +## Segurança + +- [Visão geral de segurança](security/overview.md) +- [Autenticação](security/authentication.md) +- [Autorização](security/authorization.md) TODO: verify and complete! +- [Trabalhando com senhas](security/passwords.md) +- [Criptografia](security/cryptography.md) +- [Requisição confiável](security/trusted-request.md) +- [Boas práticas](security/best-practices.md) + +## Cache + +- [Visão geral do cache](caching/overview.md) +- [Cache de dados](caching/data.md) +- Cache de fragmentos TODO +- Cache de páginas TODO +- Cache HTTP TODO + +## Trabalhando com bancos de dados + +- [Yii + DB](https://github.com/yiisoft/db/blob/master/docs/guide/en/README.md) +- [Active + Record](https://github.com/yiisoft/active-record/blob/master/README.md) +- [Migrations](databases/db-migrations.md) TODO: verify/update! + +## Views + +- [View](views/view.md) +- [Assets](views/asset.md) TODO: verify! +- [Scripts, estilos e meta tags](views/script-style-meta.md) TODO: verify! +- [Template engines](views/template-engines.md) TODO: verify! +- [Injeções em views](views/view-injections.md) +- [Widgets](views/widget.md) TODO: verify! + +## Recebendo dados dos usuários + +- Criando formulários TODO +- [Validando + entradas](https://github.com/yiisoft/validator/blob/master/docs/guide/en/README.md) +- Upload de arquivos TODO +- Coletando dados tabulares TODO + +## Exibindo dados + +- Formatação de dados TODO +- Paginação TODO +- Ordenação TODO +- Data providers TODO +- Widgets de dados TODO + +## APIs REST + +- [Início rápido](rest/quick-start.md) +- Recursos TODO +- Controllers TODO +- Roteamento TODO +- Autenticação TODO +- Limitação de requisições TODO +- Versionamento TODO +- Tratamento de erros TODO + +## Ferramentas de desenvolvimento + +- Barra e painel de debug +- Gerando código com o Gii +- Gerando documentação da API + + +## Testes + +- [Visão geral de testes](testing/overview.md) +- [Configurando o ambiente de testes](testing/environment-setup.md) +- [Testes unitários](testing/unit.md) +- [Testes funcionais](testing/functional.md) +- [Testes end-to-end](testing/end-to-end.md) +- [Análise estática e testes de mutação](testing/quality-tools.md) + + +## Tópicos especiais + +- [Aplicações de console](tutorial/console-applications.md) +- [Envio de e-mails](tutorial/mailing.md) +- [Otimização de desempenho](tutorial/performance-tuning.md) +- [Usando o Yii com event loop](tutorial/using-with-event-loop.md) +- [Usando o Yii com FrankenPHP](tutorial/using-yii-with-frankenphp.md) +- [Usando o Yii com Rapira](tutorial/using-yii-with-rapira.md) +- [Usando o Yii com RoadRunner](tutorial/using-yii-with-roadrunner.md) +- [Usando o Yii com Swoole](tutorial/using-yii-with-swoole.md) +- [Docker nos templates de aplicação](tutorial/docker.md) +- [Internacionalização](tutorial/i18n.md) + +## Helpers + +- [Arrays](https://github.com/yiisoft/arrays/) +- [Arquivos](https://github.com/yiisoft/files/) +- [Html](https://github.com/yiisoft/html/) +- [Json](https://github.com/yiisoft/json) +- [Utilitários de rede](https://github.com/yiisoft/network-utilities/) +- [VarDumper](https://github.com/yiisoft/var-dumper) +- [Strings](https://github.com/yiisoft/strings) + +## Extras + +- [Cookbook](../cookbook/index.md) +- [Glossário](glossary.md) diff --git a/src/pt-BR/guide/intro/upgrade-from-v1.md b/src/pt-BR/guide/intro/upgrade-from-v1.md new file mode 100644 index 00000000..a4ae75a2 --- /dev/null +++ b/src/pt-BR/guide/intro/upgrade-from-v1.md @@ -0,0 +1,752 @@ +# Upgrading from Version 1.1 + +> If you haven't used Yii 1.1, you can skip this section and get directly to +> "[getting started](../start/prerequisites.md)" section. + +Yii3 is not an incremental upgrade from Yii 1.1. Yii 2.0 was a full rewrite, +and Yii3 changes the architecture again: Composer packages, namespaces, PHP +8, PSR interfaces, dependency injection, explicit routes, middleware, and +separate packages for features that were built into the framework in Yii +1.1. + +Treat this as building a new Yii3 application with the benefit of Yii 1.1 +experience. Reuse the domain knowledge, database schema, user workflows, and +selected code after refactoring. Do not try to reproduce the Yii 1.1 +application structure in Yii3. A direct search-and-replace conversion is not +realistic. + +For additional background, read the Yii 2.0 guide section [Upgrading from +Version +1.1](https://www.yiiframework.com/doc/guide/2.0/en/intro-upgrade-from-v1). +It explains the first major break from Yii 1.1: Composer, namespaces, object +configuration, view changes, controller return values, widgets, assets, +helpers, forms, query builder, Active Record, and URL management. Yii3 +builds on many of those changes and makes dependencies more explicit. + +## Recommended approach + +Choose one of these paths: + +- Build a new Yii3 application directly when the Yii 1.1 application is + small or you are already rewriting request flows. +- Move Yii 1.1 concepts to Yii 2.0 first when the team needs a smaller + conceptual step. +- Keep Yii 1.1 running and rebuild critical flows in Yii3 one by one. + +For most long-lived applications, the third option is the least +risky. Create a Yii3 application, connect it to the same database, and build +vertical slices: route, action, input validation, persistence, view, assets, +and tests. Each slice should be idiomatic Yii3, even when it is based on +behavior from the Yii 1.1 application. + +## Prepare the Yii 1.1 application + +Useful preparation can happen before the Yii3 application is ready. These +refactorings make old behavior easier to understand and reduce the amount of +Yii 1.1 framework state that crosses into the new code: + +- Remove direct `Yii::app()` access from reusable code where practical. If a + full refactoring is too large, keep `Yii::app()` calls near controllers, + widgets, and commands, then pass values and services to lower-level code + explicitly. +- Introduce repositories or query services for database reads currently + spread across controllers, views, `CActiveRecord` methods, and + widgets. Yii3 can use Active Record, but it does not require it for every + persistence task. +- Separate business rules from framework infrastructure. Code that does not + extend `CComponent`, read global application state, or render views is + easier to reuse as a specification for Yii3 code. +- Move reusable behavior out of large controllers and Active Record classes + into Yii 1.1 application components or plain services. Yii3 services are + configured and injected differently, but the responsibility boundary is + similar. +- Add tests or characterization checks around routes and workflows you plan + to rebuild first. They become the executable specification for the Yii3 + slice. + +For example, instead of reading post archive data directly from several +controllers or widgets, create a small service that describes the +application need: + +```php +class PostRepository extends CComponent +{ + public function getArchive() + { + // ... + } + + public function getTopForFrontPage($limit = 10) + { + // ... + } +} +``` + +The Yii3 implementation may use `yiisoft/active-record`, `yiisoft/db`, or +another persistence layer. The important point is that controllers and views +no longer need to know that detail. + +## Things to learn before starting + +Some Yii3 application-template choices are likely to be new in a Yii 1.1 +codebase: + +- [Composer](https://getcomposer.org/). Yii3 applications and packages are + installed through Composer and loaded with PSR-4 autoloading. +- [Namespaces](https://www.php.net/manual/en/language.namespaces.php). Yii3 + classes are namespaced instead of using Yii 1.1-style class prefixes and + path aliases for class loading. +- [Docker](https://www.docker.com/get-started/). The default Yii3 + application template includes Docker configuration. Using it gives each + application its own repeatable environment and reduces differences between + local development and production. +- [Environment + variables](https://en.wikipedia.org/wiki/Environment_variable). Yii3 + templates commonly use them for environment-specific settings and secrets, + especially in Docker-based deployments. This follows the same idea as + [12-factor app configuration](https://12factor.net/config). +- [Actions](../structure/action.md). Yii3 does not require controller + inheritance. A route can point to any callable, and the default template + uses invokable action classes. +- [Application structure](../structure/overview.md). Yii3's default + structure is different from Yii 1.1. Start with the Yii3 template and + change it only when the application needs it. + +## PHP, Composer, and namespaces + +Yii 1.1 applications commonly rely on PHP 5-era code, class prefixes such as +`CController`, and autoloading by class name. Yii3 applications require +modern PHP and Composer autoloading. + +Yii 1.1: + +```php +class SiteController extends CController +{ +} +``` + +Yii3: + +```php +namespace App\Web\HomePage; + +final readonly class Action +{ +} +``` + +Configure your application namespace with PSR-4: + +```json +{ + "autoload": { + "psr-4": { + "App\\": "src/" + } + } +} +``` + +Run: + +```shell +composer dump-autoload +``` + +When reusing a class, give it a namespace, add strict types, replace Yii 1.1 +base classes, and inject dependencies instead of reading them from global +application state. If these changes make the class awkward, use the old +class as a specification and write a new Yii3 class instead. + +## Project structure + +A Yii 1.1 application often uses: + +```text +protected/ + commands/ + components/ + config/ + controllers/ + extensions/ + messages/ + migrations/ + models/ + views/ +themes/ +webroot/ +``` + +The current Yii3 application template uses: + +```text +assets/ +config/ +public/ +runtime/ +src/ +tests/ +``` + +Typical mappings to consider are: + +| Yii 1.1 | Yii3 | +|---------|------| +| `protected/controllers` | `src/Web/*/Action.php` or controller-like services | +| `protected/models` | `src/Domain`, `src/Shared`, `src/Db`, or form models by responsibility | +| `protected/views` | templates near the feature, for example `src/Web/HomePage/template.php` | +| `protected/views/layouts` | layout templates and assets under `src/Web/Shared/Layout` | +| `protected/components` | services configured in the dependency injection container | +| `protected/extensions` | Composer packages or local packages | +| `protected/commands` | `src/Console/*Command.php` | +| `protected/messages` | translator message files | +| `protected/config` | `config/common`, `config/web`, `config/console`, `config/environments` | +| `webroot` | `public` | + +Do not recreate `protected` in Yii3. Put PHP source under `src`, public +files under `public`, generated/runtime files under `runtime`, and +configuration under `config`. + +## Configuration and application components + +Yii 1.1 configuration is usually one large array: + +```php +return [ + 'basePath' => dirname(__DIR__), + 'components' => [ + 'db' => [ + 'connectionString' => 'mysql:host=localhost;dbname=app', + 'username' => 'root', + 'password' => '', + ], + 'urlManager' => [ + 'urlFormat' => 'path', + 'rules' => [ + 'post/' => 'post/view', + ], + ], + ], +]; +``` + +In Yii3, configuration is split by purpose and services are wired through +the container: + +- aliases in `config/common/aliases.php`; +- parameters in `config/common/params.php` and environment files; +- shared service definitions in `config/common/di/*.php`; +- web-only service definitions in `config/web/di/*.php`; +- routes in `config/common/routes.php`; +- console commands in `config/console/*.php`. + +The default template's console DI group reuses shared definitions from +`config/common/di/*.php`. If you need console-only container definitions, +add files for them to the `di-console` group in `config/configuration.php` +and rebuild the merge plan. + +Replace `Yii::app()->componentName` with constructor-injected services: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; +use Yiisoft\Router\UrlGeneratorInterface; + +final readonly class PostRepository +{ + public function __construct( + private ConnectionInterface $db, + private UrlGeneratorInterface $urlGenerator, + ) { + } +} +``` + +See [Configuration](../concept/configuration.md), +[Aliases](../concept/aliases.md), and [Dependency injection +container](../concept/di-container.md). + +## Entry script + +Yii 1.1 entry scripts commonly load `yii.php` and create a web application: + +```php +require_once __DIR__ . '/../framework/yii.php'; + +Yii::createWebApplication($config)->run(); +``` + +Yii3 entry scripts load Composer and bootstrap the configured +application. Start with the `public/index.php` file from `yiisoft/app` and +adjust configuration instead of building the application manually in the +entry script. + +See [Entry scripts](../structure/entry-script.md) and [Application +workflow](../start/workflow.md). + +## Controllers, actions, and routes + +Yii 1.1 controllers extend `CController`, and actions are methods named +`actionName`: + +```php +class PostController extends CController +{ + public function actionView($id) + { + $post = Post::model()->findByPk($id); + + if ($post === null) { + throw new CHttpException(404); + } + + $this->render('view', ['post' => $post]); + } +} +``` + +Yii3 does not require controller inheritance. The current template uses +invokable action classes: + +```php +namespace App\Web\Post\View; + +use App\Post\PostRepository; +use Psr\Http\Message\ResponseInterface; +use Yiisoft\Router\CurrentRoute; +use Yiisoft\Yii\View\Renderer\WebViewRenderer; + +final readonly class Action +{ + public function __construct( + private CurrentRoute $currentRoute, + private PostRepository $posts, + private WebViewRenderer $viewRenderer, + ) { + } + + public function __invoke(): ResponseInterface + { + $post = $this->posts->findById((int) $this->currentRoute->getArgument('id')); + + return $this->viewRenderer->render(__DIR__ . '/template', [ + 'post' => $post, + ]); + } +} +``` + +The route is explicit: + +```php +use App\Web\Post\View; +use Yiisoft\Router\Route; + +return [ + Route::get('/post/{id:\d+}') + ->action(View\Action::class) + ->name('post/view'), +]; +``` + +Define routes before action bodies. It gives you a checklist of request +flows you decided to keep in the Yii3 application. + +See [Actions](../structure/action.md), +[Middleware](../structure/middleware.md), and [Routing and URL +generation](../runtime/routing.md). + +## Requests, responses, redirects, sessions, and cookies + +Yii 1.1 code often reads and writes through `Yii::app()`: + +```php +$id = Yii::app()->request->getParam('id'); +Yii::app()->user->setFlash('success', 'Saved.'); +$this->redirect(['post/view', 'id' => $id]); +``` + +Yii3 uses PSR-7 request and response objects and injectable +services. Request input is available from `ServerRequestInterface`; +redirects, sessions, cookies, and responses are explicit dependencies. + +See [Request](../runtime/request.md), [Response](../runtime/response.md), +[Sessions](../runtime/sessions.md), and [Cookies](../runtime/cookies.md). + +## Views and layouts + +Yii 1.1 views use `$this` as the controller or widget context. Layouts and +partials are rendered through controller methods: + +```php + + +

title); ?>

+``` + +In Yii3 templates, `$this` is a `Yiisoft\View\WebView` instance: + +```php +use Yiisoft\Html\Html; +use Yiisoft\View\WebView; + +/** + * @var WebView $this + * @var Post $post + */ + +$this->setTitle($post->getTitle()); +?> + +

getTitle()) ?>

+``` + +Move controller-specific view logic to the action or to a presenter. Pass +only the data a template needs. + +See [View](../views/view.md), [View +injections](../views/view-injections.md), and [Template +engines](../views/template-engines.md). + +## Assets and client scripts + +Yii 1.1 applications often use `CClientScript`, themes, and +extension-specific asset publishing: + +```php +Yii::app()->clientScript->registerCssFile('/css/site.css'); +Yii::app()->clientScript->registerScriptFile('/js/site.js'); +``` + +Yii3 uses asset bundles from `yiisoft/assets`: + +```php +namespace App\Web\Shared\Layout\Main; + +use Yiisoft\Assets\AssetBundle; + +final class MainAsset extends AssetBundle +{ + public ?string $basePath = '@assets/main'; + public ?string $baseUrl = '@assetsUrl/main'; + public ?string $sourcePath = '@assetsSource/main'; + + public array $css = ['site.css']; + public array $js = ['site.js']; +} +``` + +Register bundles through the asset manager in layouts or views. + +See [Assets](../views/asset.md) and [Scripts, styles and +metatags](../views/script-style-meta.md). + +## Models, forms, and validation + +Yii 1.1 has `CModel`, `CFormModel`, and `CActiveRecord`. It is common for +one model class to contain input data, labels, validation rules, database +persistence, and business logic. + +Yii3 works better when these responsibilities are split: + +- form data and labels: `yiisoft/form-model`; +- validation rules: `yiisoft/validator`; +- form rendering: `yiisoft/form`; +- persistence: repositories, `yiisoft/db`, or `yiisoft/active-record`; +- business workflows: application services. + +Yii 1.1 form model: + +```php +class ContactForm extends CFormModel +{ + public $name; + public $email; + + public function rules() + { + return [ + ['name, email', 'required'], + ['email', 'email'], + ]; + } +} +``` + +Yii3 form model: + +```php +use Yiisoft\FormModel\FormModel; +use Yiisoft\Validator\Rule\Email; +use Yiisoft\Validator\Rule\Required; + +final class ContactForm extends FormModel +{ + #[Required] + public ?string $name = null; + + #[Required] + #[Email] + public ?string $email = null; +} +``` + +See [Working with forms](../start/forms.md), [Validating +input](https://github.com/yiisoft/validator/blob/master/docs/guide/en/README.md), +[yiisoft/form](https://github.com/yiisoft/form), and +[yiisoft/form-model](https://github.com/yiisoft/form-model). + +## Active Record + +Yii 1.1 Active Record uses `CActiveRecord::model()` and dynamic attributes: + +```php +class Post extends CActiveRecord +{ + public static function model($className = __CLASS__) + { + return parent::model($className); + } + + public function tableName() + { + return '{{post}}'; + } + + public function rules() + { + return [ + ['title, body', 'required'], + ['title', 'length', 'max' => 255], + ]; + } +} +``` + +The incremental Yii3 option is +[yiisoft/active-record](https://github.com/yiisoft/active-record): + +```php +use Yiisoft\ActiveRecord\ActiveRecord; + +final class Post extends ActiveRecord +{ + protected int $id; + protected string $title; + protected string $body; + + public function tableName(): string + { + return '{{%post}}'; + } + + public function getTitle(): ?string + { + return $this->title ?? null; + } + + public function setTitle(string $title): void + { + $this->title = $title; + } +} +``` + +Move Yii 1.1 `rules()` to a form model, validator rules, or a service. Keep +Active Record focused on persistence: table mapping, properties, relations, +and database operations. + +For more complex applications, consider replacing Active Record-heavy code +with repositories and domain objects. That is more work initially, but it +avoids carrying Yii 1.1 form and persistence coupling into the new +application. + +See [Working with databases](../start/databases.md), +[Migrations](../databases/db-migrations.md), and +[yiisoft/active-record](https://github.com/yiisoft/active-record). + +## Database queries and migrations + +Yii 1.1 code may use `CDbCriteria`, `CDbCommand`, `CActiveDataProvider`, and +`CGridView` data providers. In Yii3, use `yiisoft/db` for database access +and query building, and `yiisoft/data` / `yiisoft/yii-dataview` for data +readers and widgets. + +Migrations are not compatible across Yii 1.1 and Yii3. For an existing +application, create a baseline from the current schema and use Yii3 +migrations for new changes. + +See [Working with databases](../start/databases.md) and +[Migrations](../databases/db-migrations.md). + +## GridView and data widgets + +Yii 1.1 `CGridView` is often configured with `CActiveDataProvider`: + +```php +$this->widget('zii.widgets.grid.CGridView', [ + 'dataProvider' => $dataProvider, + 'columns' => [ + 'id', + 'title', + [ + 'class' => 'CButtonColumn', + ], + ], +]); +``` + +Yii3 uses [yiisoft/yii-dataview](https://github.com/yiisoft/yii-dataview): + +```php +use Yiisoft\Data\Reader\ReadableDataInterface; +use Yiisoft\Yii\DataView\Column\DataColumn; +use Yiisoft\Yii\DataView\GridView\Column\ActionColumn; +use Yiisoft\Yii\DataView\GridView\GridView; + +/** + * @var ReadableDataInterface $dataReader + */ + +echo GridView::widget() + ->dataReader($dataReader) + ->columns( + new DataColumn('id'), + new DataColumn('title'), + new ActionColumn(), + ); +``` + +Replace the old data provider with a query service that returns a data +reader. Model filters as validator rules and route or query parameters. + +See [Using htmx for partial +reloads](../../cookbook/using-htmx-for-partial-reloads.md) and [yii-dataview +GridView +docs](https://github.com/yiisoft/yii-dataview/blob/master/docs/en/guide/gridview.md). + +## URL management + +Yii 1.1: + +```php +echo CHtml::link('View', ['post/view', 'id' => $post->id]); +$url = Yii::app()->createUrl('post/view', ['id' => $post->id]); +``` + +Yii3: + +```php +use Yiisoft\Html\Html; +use Yiisoft\Router\UrlGeneratorInterface; + +$url = $urlGenerator->generate('post/view', ['id' => $post->getId()]); + +echo Html::a('View', $url)->render(); +``` + +Prefer named routes. They make views and GridView action columns easier to +design and maintain. + +See [Routing and URL generation](../runtime/routing.md). + +## Filters, access control, and authentication + +Yii 1.1 controller filters are controller methods or filter classes: + +```php +public function filters() +{ + return [ + 'accessControl', + ]; +} +``` + +Yii3 uses middleware and focused packages. Move authentication, +authorization, CSRF, locale detection, and request body parsing out of +controllers and into middleware or services. + +See [Middleware](../structure/middleware.md), +[Authentication](../security/authentication.md), and +[Authorization](../security/authorization.md). + +## Widgets, helpers, and extensions + +Yii 1.1 widgets and helpers usually depend on Yii-specific base classes such +as `CWidget`, `CHtml`, and extension autoloading. In Yii3: + +- replace helper calls with `yiisoft/html`, `yiisoft/arrays`, + `yiisoft/strings`, or application helpers; +- replace extensions with Composer packages; +- rebuild custom widgets with `yiisoft/widget` or plain services/templates; +- replace jQuery UI and Bootstrap widgets with current frontend packages or + Yii3 widget packages where available. + +See [Widgets](../views/widget.md). + +## Console applications + +Yii 1.1 console commands extend `CConsoleCommand`: + +```php +class ReportCommand extends CConsoleCommand +{ + public function actionSend() + { + } +} +``` + +Yii3 console commands are Symfony Console commands configured as services: + +```php +namespace App\Console; + +use Symfony\Component\Console\Attribute\AsCommand; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +#[AsCommand(name: 'report/send')] +final class SendReportCommand extends Command +{ + protected function execute(InputInterface $input, OutputInterface $output): int + { + return Command::SUCCESS; + } +} +``` + +See [Console applications](../tutorial/console-applications.md). + +## Internationalization + +Yii 1.1 message files under `protected/messages` can usually be kept +conceptually, but configuration changes. Yii3 uses translator packages and +explicit message sources. Move message files into the structure expected by +the selected translator message package and inject translation services +where needed. + +See [Internationalization](../tutorial/i18n.md). + +## What to refactor before reusing + +These Yii 1.1 refactorings make the old behavior easier to understand and +reuse: + +- isolate database queries from controllers; +- remove direct `Yii::app()` access from domain code; +- move validation out of Active Record when it describes request input + rather than database invariants; +- replace large controller actions with services; +- document all routes and URL rules; +- add tests around the flows you plan to rebuild first; +- upgrade PHP syntax gradually if the old runtime allows it. + +The goal is not to make Yii 1.1 look like Yii3. The goal is to reduce hidden +coupling before the code crosses the framework boundary. diff --git a/src/pt-BR/guide/intro/upgrade-from-v2.md b/src/pt-BR/guide/intro/upgrade-from-v2.md new file mode 100644 index 00000000..daf46bb5 --- /dev/null +++ b/src/pt-BR/guide/intro/upgrade-from-v2.md @@ -0,0 +1,863 @@ +# Upgrading from Version 2.0 + +> If you haven't used Yii 2.0, you can skip this section and get directly to "[getting started](../start/prerequisites.md)" +> section. + +Yii3 keeps many Yii ideas, but it is not a drop-in replacement for Yii +2.0. It uses PHP 8 features, PSR interfaces, dependency injection, explicit +package composition, and a different application template. Use your Yii 2.0 +experience to design a new Yii3 application deliberately instead of trying +to reproduce the old application structure. + +For source applications, compare against: + +- [yiisoft/yii2-app-basic](https://github.com/yiisoft/yii2-app-basic) +- [yiisoft/yii2-app-advanced](https://github.com/yiisoft/yii2-app-advanced) + +For the target structure, compare against: + +- [yiisoft/app](https://github.com/yiisoft/app) +- [Yii3 guide](../index.md) + +Before starting, [check maintenance policy and end-of-life dates for Yii +2.0](https://www.yiiframework.com/release-cycle). Keeping a mature Yii 2.0 +application on Yii 2.0 can be a valid choice. A Yii3 project is most useful +when you want the new package ecosystem, stricter typing, PSR middleware, +and a more explicit architecture. + +## Recommended approach + +Think of the work as building a Yii3 application that is informed by the old +one. The old project tells you which routes, forms, database tables, +business rules, and user workflows matter. The Yii3 project should decide +again where these responsibilities belong. + +Build it in vertical slices: + +1. Create a new Yii3 application with `yiisoft/app`. +2. Configure Composer autoloading and add only the code needed for the slice + you are building. +3. Define configuration and routes before writing actions. +4. Build one request flow at a time: route, action, input model, service, + persistence, view, assets, tests. +5. Keep the Yii 2.0 application running until each flow is verified in Yii3. + +Avoid moving the whole directory tree first. Yii3's defaults are +intentionally different, and a mechanical copy tends to preserve Yii 2.0 +service-locator assumptions. Prefer small, reviewed decisions over carrying +old structure forward because it is familiar. + +## Prepare the Yii 2.0 application + +Useful preparation can happen before the Yii3 application is ready. These +refactorings improve the Yii 2.0 project itself and make the later rewrite +less dependent on hidden framework state: + +- Replace `Yii::$app` access in reusable code with constructor arguments + where practical. If a full dependency injection refactoring is too large, + keep `Yii::$app` calls near controllers and widgets, then pass values and + services to lower-level code explicitly. +- Introduce repositories or query services for database reads that are + currently scattered across controllers, views, widgets, and Active Record + methods. Yii3 does not require Active Record for persistence, so a + repository boundary gives you a natural place to change the implementation + later. +- Separate business rules from framework infrastructure. Domain code that + does not extend Yii classes, read global application state, or render + views is much easier to reuse or rewrite. +- Move reusable behavior into Yii 2.0 components or services instead of + keeping it inside large controllers and Active Record classes. Yii3 + services are configured and injected differently, but the responsibility + boundary is similar. +- Add tests around routes and workflows you plan to rebuild first. They + become the executable specification for the Yii3 slice. + +For example, instead of reading post archive data directly from several +controllers or widgets, create a small service that describes the +application need: + +```php +final class PostRepository +{ + public function getArchive(): array + { + // ... + } + + public function getTopForFrontPage(int $limit = 10): array + { + // ... + } +} +``` + +The Yii3 implementation may still use Active Record, or it may use +`yiisoft/db` queries. The important point is that controllers and views no +longer need to know that detail. + +## Things to learn before starting + +Some Yii3 application-template choices are worth learning before you start +moving features: + +- [Docker](https://www.docker.com/get-started/). The default Yii3 + application template includes Docker configuration. Using it gives each + application its own repeatable environment and reduces differences between + local development and production. +- [Environment + variables](https://en.wikipedia.org/wiki/Environment_variable). Yii3 + templates commonly use them for environment-specific settings and secrets, + especially in Docker-based deployments. This follows the same idea as + [12-factor app configuration](https://12factor.net/config). +- [Actions](../structure/action.md). Yii3 does not require controller + inheritance. A route can point to any callable, and the default template + uses invokable action classes. +- [Application structure](../structure/overview.md). Yii3's default + structure is different from Yii 2.0. The structure is flexible, but start + with the Yii3 template and change it only when the application needs it. + +## PHP requirements + +Yii3 application templates require PHP 8.2 or above. As a result, +application code can use language features that were not common in Yii 2.0 +applications: + +- [Type + declarations](https://www.php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration) +- [Return type + declarations](https://www.php.net/manual/en/functions.returning-values.php#functions.returning-values.type-declaration) +- [Class constant + visibility](https://www.php.net/manual/en/language.oop5.constants.php) +- [Named + arguments](https://www.php.net/manual/en/functions.arguments.php#functions.named-arguments) +- [Anonymous + classes](https://www.php.net/manual/en/language.oop5.anonymous.php) +- [::class](https://www.php.net/manual/en/language.oop5.basic.php#language.oop5.basic.class.class) +- [Generators](https://www.php.net/manual/en/language.generators.php) +- [Variadic + functions](https://www.php.net/manual/en/functions.arguments.php#functions.variable-arg-list) +- [Readonly + properties](https://www.php.net/manual/en/language.oop5.properties.php#language.oop5.properties.readonly-properties) +- [Readonly + classes](https://www.php.net/manual/en/language.oop5.basic.php#language.oop5.basic.class.readonly) +- [Constructor property + promotion](https://www.php.net/manual/en/language.oop5.decon.php#language.oop5.decon.constructor.promotion) +- [Attributes](https://www.php.net/manual/en/language.attributes.php) + +Run static analysis and tests on Yii 2.0 before reusing code in Yii3. Code +with explicit types, small services, and few implicit `Yii::$app` +dependencies is easier to understand and easier to place in the new +application. + +## Project structure + +Yii 2.0 applications commonly keep framework roles in top-level directories: + +```text +assets/ +commands/ +config/ +controllers/ +models/ +runtime/ +views/ +web/ +widgets/ +``` + +The Yii 2.0 advanced template splits the same roles by application: + +```text +backend/ +common/ +console/ +frontend/ +``` + +The current Yii3 application template is organized around source code, +configuration, public files, and runtime files: + +```text +assets/ +config/ +public/ +runtime/ +src/ +tests/ +``` + +Typical mappings to consider are: + +| Yii 2.0 basic | Yii 2.0 advanced | Yii3 | +|---------------|------------------|------| +| `controllers/` | `frontend/controllers/`, `backend/controllers/` | `src/Web/*/Action.php` or controller-like classes | +| `models/` | `common/models/`, app-specific models | `src/Domain`, `src/Shared`, `src/Web/*`, or `src/Db` by responsibility | +| `views/` | `frontend/views/`, `backend/views/` | templates near the feature, for example `src/Web/HomePage/template.php` | +| `views/layouts/` | app layout directories | layout classes/templates, for example `src/Web/Shared/Layout/Main` | +| `assets/` | app asset bundles | `assets/` for source files and `src/Web/.../*Asset.php` for bundles | +| `web/` | `frontend/web/`, `backend/web/` | `public/` | +| `commands/` | `console/controllers/` | `src/Console/*Command.php` | +| `config/*.php` | app and common config files | `config/common`, `config/web`, `config/console`, `config/environments` | + +There is no single required layout. The important change is that Yii3 +applications should group code by responsibility and make dependencies +explicit. If you are coming from the advanced template, treat `frontend` and +`backend` as separate web contexts. Shared domain code can live in +`src/Shared` or in application-specific packages. + +## Composer and autoloading + +Yii 2.0 applications usually require `vendor/autoload.php` and +`vendor/yiisoft/yii2/Yii.php` in `web/index.php`. Yii3 applications require +only Composer's autoloader and application bootstrap code. + +Configure your application namespace with PSR-4: + +```json +{ + "autoload": { + "psr-4": { + "App\\": "src/" + } + } +} +``` + +Then rebuild Composer autoload files: + +```shell +composer dump-autoload +``` + +Install Yii3 packages intentionally. Yii3 is split into focused packages, so +features such as database access, forms, validation, assets, data widgets, +authentication, and caching are separate Composer dependencies. + +## Configuration and services + +In Yii 2.0, many services are configured as application components and +accessed through the service locator: + +```php +$cache = Yii::$app->cache; +$db = Yii::$app->db; +$url = Yii::$app->urlManager->createUrl(['post/view', 'id' => $id]); +``` + +In Yii3, services are configured for the container and injected where they +are needed: + +```php +use Psr\SimpleCache\CacheInterface; +use Yiisoft\Db\Connection\ConnectionInterface; +use Yiisoft\Router\UrlGeneratorInterface; + +final readonly class PostService +{ + public function __construct( + private ConnectionInterface $db, + private CacheInterface $cache, + private UrlGeneratorInterface $urlGenerator, + ) { + } +} +``` + +Move configuration in groups: + +- aliases to `config/common/aliases.php`; +- route definitions to `config/common/routes.php`; +- shared service definitions to `config/common/di/*.php`; +- web-only service definitions to `config/web/di/*.php`; +- console parameters and commands to `config/console/*.php`; +- shared parameters to `config/common/params.php`; +- environment overrides to `config/environments`. + +The default template's `di-console` group reuses shared definitions from +`config/common/di/*.php`. If you need console-only container definitions, +add the corresponding files to the `di-console` group in +`config/configuration.php` and rebuild the merge plan. + +See [Configuration](../concept/configuration.md), +[Aliases](../concept/aliases.md), and [Dependency injection +container](../concept/di-container.md). + +## Entry script and bootstrap + +A Yii 2.0 basic entry script commonly creates the application directly: + +```php +defined('YII_DEBUG') or define('YII_DEBUG', true); +defined('YII_ENV') or define('YII_ENV', 'dev'); + +require __DIR__ . '/../vendor/autoload.php'; +require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php'; + +$config = require __DIR__ . '/../config/web.php'; + +(new yii\web\Application($config))->run(); +``` + +In Yii3, use the application template entry script as the source of +truth. It loads Composer and bootstraps the configured application +runner. Avoid recreating the old `yii\web\Application` pattern in +`public/index.php`; put configuration in config files and dependencies in +the container. + +See [Entry scripts](../structure/entry-script.md) and [Application +workflow](../start/workflow.md). + +## Controllers, actions, and routing + +Yii 2.0 routes usually point to controller action methods: + +```php +namespace app\controllers; + +use yii\web\Controller; + +final class SiteController extends Controller +{ + public function actionIndex(): string + { + return $this->render('index'); + } +} +``` + +Yii3 does not require controller base classes. The current application +template uses invokable action classes: + +```php +namespace App\Web\HomePage; + +use Psr\Http\Message\ResponseInterface; +use Yiisoft\Yii\View\Renderer\WebViewRenderer; + +final readonly class Action +{ + public function __construct( + private WebViewRenderer $viewRenderer, + ) { + } + + public function __invoke(): ResponseInterface + { + return $this->viewRenderer->render(__DIR__ . '/template'); + } +} +``` + +Routes are explicit: + +```php +use App\Web; +use Yiisoft\Router\Group; +use Yiisoft\Router\Route; + +return [ + Group::create() + ->routes( + Route::get('/') + ->action(Web\HomePage\Action::class) + ->name('home'), + ), +]; +``` + +When redesigning a controller flow, list all Yii 2.0 actions and create +named routes for the flows you still need. Then implement each flow as an +invokable class or a controller-like service. Constructor injection replaces +calls to `Yii::$app` and controller properties. + +See [Actions](../structure/action.md), +[Middleware](../structure/middleware.md), and [Routing and URL +generation](../runtime/routing.md). + +## Requests, responses, sessions, and cookies + +Yii 2.0 actions often read request data and write response data through +application components: + +```php +$id = Yii::$app->request->get('id'); +Yii::$app->session->setFlash('success', 'Saved.'); + +return $this->redirect(['post/view', 'id' => $id]); +``` + +Yii3 uses PSR-7 request and response objects and injectable services: + +```php +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\ResponseFactoryInterface; +use Psr\Http\Message\ServerRequestInterface; +use Yiisoft\Http\Status; +use Yiisoft\Router\UrlGeneratorInterface; + +final readonly class SavePostAction +{ + public function __construct( + private ResponseFactoryInterface $responseFactory, + private UrlGeneratorInterface $urlGenerator, + ) { + } + + public function __invoke(ServerRequestInterface $request): ResponseInterface + { + $id = (int) ($request->getQueryParams()['id'] ?? 0); + $url = $this->urlGenerator->generate('post/view', ['id' => $id]); + + return $this->responseFactory + ->createResponse(Status::SEE_OTHER) + ->withHeader('Location', $url); + } +} +``` + +Design request handling early because it affects forms, filters, REST +endpoints, redirects, and tests. + +See [Request](../runtime/request.md), [Response](../runtime/response.md), +[Sessions](../runtime/sessions.md), and [Cookies](../runtime/cookies.md). + +## Views, layouts, assets, and URLs + +In Yii 2.0, controller rendering finds files under `views/{controller}` and +layouts under `views/layouts`: + +```php +return $this->render('view', [ + 'model' => $model, +]); +``` + +In Yii3, the template path is explicit in the action: + +```php +return $this->viewRenderer->render(__DIR__ . '/view', [ + 'post' => $post, +]); +``` + +A Yii3 template receives a `Yiisoft\View\WebView` instance as `$this`: + +```php +use App\Shared\ApplicationParams; +use Yiisoft\Html\Html; +use Yiisoft\View\WebView; + +/** + * @var WebView $this + * @var ApplicationParams $applicationParams + * @var string $title + */ + +$this->setTitle($title . ' - ' . $applicationParams->name); +?> + +

+``` + +Asset bundles move from `yii\web\AssetBundle` to +`Yiisoft\Assets\AssetBundle`: + +```php +namespace App\Web\Shared\Layout\Main; + +use Yiisoft\Assets\AssetBundle; + +final class MainAsset extends AssetBundle +{ + public ?string $basePath = '@assets/main'; + public ?string $baseUrl = '@assetsUrl/main'; + public ?string $sourcePath = '@assetsSource/main'; + + public array $css = [ + 'site.css', + ]; +} +``` + +Register assets in a layout or view via the asset manager: + +```php +$assetManager->register(MainAsset::class); + +$this->addCssFiles($assetManager->getCssFiles()); +$this->addJsFiles($assetManager->getJsFiles()); +``` + +Replace `yii\helpers\Url` and `Yii::$app->urlManager` usage with named routes and +`Yiisoft\Router\UrlGeneratorInterface`: + +```php +$url = $urlGenerator->generate('post/view', ['id' => $post->getId()]); +``` + +See [View](../views/view.md), [Assets](../views/asset.md), [Scripts, styles +and metatags](../views/script-style-meta.md), and [Template +engines](../views/template-engines.md). + +## Forms and validation + +Yii 2.0 frequently combines form data, labels, validation, and sometimes +persistence in a `yii\base\Model` or `yii\db\ActiveRecord` class: + +```php +final class ContactForm extends \yii\base\Model +{ + public $name; + public $email; + + public function rules(): array + { + return [ + [['name', 'email'], 'required'], + ['email', 'email'], + ]; + } +} +``` + +Yii3 separates these concerns. Use `yiisoft/form-model` for form data and +metadata, and `yiisoft/validator` for rules: + +```php +use Yiisoft\FormModel\FormModel; +use Yiisoft\Validator\Rule\Email; +use Yiisoft\Validator\Rule\Required; + +final class ContactForm extends FormModel +{ + #[Required] + public ?string $name = null; + + #[Required] + #[Email] + public ?string $email = null; +} +``` + +For form rendering, replace `yii\widgets\ActiveForm` with `yiisoft/form` +fields and form model integration. For input hydration, prefer the +form-model and hydrator packages instead of mass-assigning arbitrary request +data to persistence objects. + +See [Working with forms](../start/forms.md), [Validating +input](https://github.com/yiisoft/validator/blob/master/docs/guide/en/README.md), +[yiisoft/form](https://github.com/yiisoft/form), and +[yiisoft/form-model](https://github.com/yiisoft/form-model). + +## Active Record and persistence + +There are two common Yii3 choices for code that used Yii 2.0 Active Record +classes. + +The first path is architectural: move business logic to services and domain +objects, then use repositories for persistence. This is recommended when the +Yii 2.0 model contains validation, form scenarios, authorization checks, +mailing, file uploads, and database access in the same class. + +The second path is incremental: represent the database model with +[yiisoft/active-record](https://github.com/yiisoft/active-record). This is +closer to Yii 2.0 and can be significantly faster when your Active Record +classes mostly describe tables and relations. + +Yii 2.0: + +```php +final class Post extends \yii\db\ActiveRecord +{ + public static function tableName(): string + { + return '{{%post}}'; + } + + public function rules(): array + { + return [ + [['title', 'body'], 'required'], + ['title', 'string', 'max' => 255], + ]; + } +} +``` + +Yii3 Active Record: + +```php +use Yiisoft\ActiveRecord\ActiveRecord; + +final class Post extends ActiveRecord +{ + protected int $id; + protected string $title; + protected string $body; + + public function tableName(): string + { + return '{{%post}}'; + } + + public function getId(): ?int + { + return $this->id ?? null; + } + + public function getTitle(): ?string + { + return $this->title ?? null; + } + + public function setTitle(string $title): void + { + $this->title = $title; + } +} +``` + +Do not move Yii 2.0 `rules()` directly into the Active Record class. In +Yii3, validation belongs to validator rules, form models, command objects, +or services: + +```php +use Yiisoft\FormModel\FormModel; +use Yiisoft\Validator\Rule\Length; +use Yiisoft\Validator\Rule\Required; + +final class PostInput extends FormModel +{ + #[Required] + #[Length(max: 255)] + public ?string $title = null; + + #[Required] + public ?string $body = null; +} +``` + +Then copy validated data into the record or pass it to an application +service: + +```php +$post = new Post(); +$post->setTitle($input->title); +$post->save(); +``` + +When deciding what to reuse, check each Active Record method: + +- table mapping and relations can usually move to `yiisoft/active-record`; +- validation should move to `yiisoft/validator`; +- form labels and hints should move to `yiisoft/form-model`; +- search models should become query/data-reader services; +- business workflows should become services; +- events should use PSR-14 events or package-specific events; +- direct `Yii::$app->db` usage should become injected database dependencies. + +Yii 2.0 migrations and Yii3 `yiisoft/db-migration` migrations are not +compatible. Start a new migration history or create structure dumps for the +current schema, then use Yii3 migrations for future schema changes. + +See [Working with databases](../start/databases.md), +[Migrations](../databases/db-migrations.md), and +[yiisoft/active-record](https://github.com/yiisoft/active-record). + +## GridView and data widgets + +Yii 2.0 `GridView` is commonly used with `ActiveDataProvider`: + +```php +use yii\grid\GridView; + +echo GridView::widget([ + 'dataProvider' => $dataProvider, + 'filterModel' => $searchModel, + 'columns' => [ + 'id', + 'title', + 'created_at:datetime', + ['class' => 'yii\grid\ActionColumn'], + ], +]); +``` + +Yii3 uses +[yiisoft/yii-dataview](https://github.com/yiisoft/yii-dataview). It renders +data from a data reader and uses fluent widget configuration: + +```php +use Yiisoft\Data\Reader\ReadableDataInterface; +use Yiisoft\Yii\DataView\Column\DataColumn; +use Yiisoft\Yii\DataView\GridView\Column\ActionColumn; +use Yiisoft\Yii\DataView\GridView\GridView; + +/** + * @var ReadableDataInterface $dataReader + */ + +echo GridView::widget() + ->dataReader($dataReader) + ->columns( + new DataColumn('id'), + new DataColumn('title', header: 'Title'), + new DataColumn('created_at', header: 'Created'), + new ActionColumn(), + ); +``` + +For sorting, pagination, filtering, and action URLs, wire the widget to Yii +Router: + +```php +use Yiisoft\Yii\DataView\YiiRouter\ActionColumnUrlConfig; +use Yiisoft\Yii\DataView\YiiRouter\ActionColumnUrlCreator; +use Yiisoft\Yii\DataView\YiiRouter\UrlCreator; +use Yiisoft\Yii\DataView\YiiRouter\UrlParameterProvider; + +echo GridView::widget() + ->dataReader($dataReader) + ->urlParameterProvider(new UrlParameterProvider($currentRoute)) + ->urlCreator(new UrlCreator($urlGenerator)) + ->columns( + new DataColumn('id'), + new DataColumn('title'), + new ActionColumn( + urlCreator: new ActionColumnUrlCreator($urlGenerator, $currentRoute), + urlConfig: new ActionColumnUrlConfig(baseRouteName: 'post'), + ), + ); +``` + +A Yii 2.0 search model usually becomes a query service that: + +1. reads filter and sort parameters from the request; +2. validates them with `yiisoft/validator`; +3. builds a database query or repository query; +4. exposes a data reader to GridView. + +See [Using htmx for partial +reloads](../../cookbook/using-htmx-for-partial-reloads.md) for a complete +Yii3 GridView workflow and [yii-dataview GridView +docs](https://github.com/yiisoft/yii-dataview/blob/master/docs/en/guide/gridview.md). + +## Filters, middleware, and access control + +Yii 2.0 controller filters and behaviors usually look like this: + +```php +public function behaviors(): array +{ + return [ + 'access' => [ + 'class' => \yii\filters\AccessControl::class, + 'rules' => [ + ['allow' => true, 'roles' => ['@']], + ], + ], + ]; +} +``` + +In Yii3, request processing is middleware-based. Move cross-cutting concerns +such as authentication, authorization, body parsing, locale negotiation, +CSRF checks, and error handling to middleware or dedicated services. Keep +actions focused on the request flow they implement. + +See [Middleware](../structure/middleware.md), +[Authentication](../security/authentication.md), and +[Authorization](../security/authorization.md). + +## Console commands + +Yii 2.0 console commands extend `yii\console\Controller`: + +```php +final class ReportController extends \yii\console\Controller +{ + public function actionSend(): int + { + // ... + return self::EXIT_CODE_NORMAL; + } +} +``` + +Yii3 console commands are services in `src/Console`: + +```php +namespace App\Console; + +use Symfony\Component\Console\Attribute\AsCommand; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +#[AsCommand(name: 'report/send')] +final class SendReportCommand extends Command +{ + protected function execute(InputInterface $input, OutputInterface $output): int + { + // ... + return Command::SUCCESS; + } +} +``` + +Move command dependencies to constructor injection and register commands in +console configuration. + +See [Console applications](../tutorial/console-applications.md). + +## APIs REST + +Yii 2.0 REST controllers, serializers, and response formatters do not move +directly to Yii3. Start from PSR-7 responses and explicit routing. Build one +resource at a time: + +1. define routes for collection and item operations; +2. inject request, persistence, serializer, and response factory + dependencies; +3. validate input with `yiisoft/validator`; +4. return JSON responses through Yii3 response helpers or PSR-7 factories; +5. move authentication and rate limiting to middleware. + +See [Response](../runtime/response.md), +[Authentication](../security/authentication.md), and +[Authorization](../security/authorization.md). + +## Testes + +Do not postpone tests until the whole Yii3 application is done. For each new +request flow, add: + +- unit tests for services and validators; +- functional tests for actions and middleware; +- end-to-end tests for critical browser flows; +- static analysis for stricter type checks. + +Yii3 code is more explicit, so tests should assert services directly instead +of constructing large application component arrays. + +See [Testing overview](../testing/overview.md), [Unit +tests](../testing/unit.md), [Functional tests](../testing/functional.md), +and [End-to-end tests](../testing/end-to-end.md). + +## Refactoring Yii 2.0 code before reusing it + +These changes are useful even if the old application stays on Yii 2.0 for a +while: + +- Replace `Yii::$app` access in domain code with constructor arguments. +- Move queries out of controllers and views into repositories or query + services. +- Move business workflows out of Active Record classes. +- Separate form models from persistence models. +- Add return types and parameter types. +- Replace route arrays scattered in views with named route constants or + helper methods. +- Add tests around each flow before rebuilding it in Yii3. + +The less framework state your Yii 2.0 code assumes, the easier it is to +understand what should be reused and what should be redesigned for Yii3. diff --git a/src/pt-BR/guide/intro/what-is-yii.md b/src/pt-BR/guide/intro/what-is-yii.md new file mode 100644 index 00000000..1cd24513 --- /dev/null +++ b/src/pt-BR/guide/intro/what-is-yii.md @@ -0,0 +1,72 @@ +# O que é o Yii + +O Yii é um framework PHP de alto desempenho, baseado em pacotes, para +desenvolver aplicações modernas. O nome Yii (pronuncia-se `Yee` ou `[ji:]`) +significa "simples e evolutivo" em chinês. Você também pode pensar nele +como um acrônimo de **Yes It Is**! + +## Para que o Yii é mais indicado + +O Yii é um framework genérico de programação web. Você pode usá-lo para +desenvolver todo tipo de aplicação web com PHP. Por causa da sua +arquitetura e do suporte sofisticado a cache, ele é especialmente indicado +para aplicações de grande porte, como portais, sistemas de gerenciamento de +conteúdo, e-commerce, APIs REST etc. + +## Como o Yii se compara a outros frameworks? + +Se você já conhece outro framework, talvez queira saber como o Yii se +compara a ele: + +- O Yii segue a [filosofia de ser prático e + útil](../../internals/001-yii-values.md), buscando: + - Desempenho tanto no desenvolvimento quanto na execução. + - Padrões convenientes e personalizáveis. + - Foco na prática. + - Simplicidade. + - Clareza. + - Consistência. + + O Yii nunca tenta complicar o design só para seguir algum padrão de projeto. +- O Yii usa amplamente as interfaces PSR, o que permite reaproveitar o que a comunidade PHP criou e até + substituir implementações do core quando necessário. +- O Yii é ao mesmo tempo um conjunto de bibliotecas e um framework full-stack com muitos recursos testados e prontos para uso: + cache, logs, template engine, abstração de dados, ferramentas de desenvolvimento, geração de código e mais. +- O Yii é extensível. Você pode personalizar ou substituir qualquer parte do código do core. Também pode + aproveitar a arquitetura sólida do Yii para usar ou desenvolver pacotes redistribuíveis. +- Alto desempenho é sempre um objetivo principal do Yii. + +O Yii conta com um [time principal de desenvolvedores +sólido](https://www.yiiframework.com/team/), apoiado financeiramente pela +[fundação no OpenCollective](https://opencollective.com/yiisoft), e com uma +grande comunidade de profissionais que contribuem constantemente para o +desenvolvimento do Yii. O time do Yii acompanha de perto as tendências mais +recentes do desenvolvimento web e as boas práticas e recursos de outros +frameworks e projetos. As boas práticas e os recursos mais relevantes +encontrados em outros lugares são incorporados ao core do framework e +expostos por meio de interfaces simples e elegantes. + + +## Versões do Yii + +Atualmente o Yii tem três versões principais disponíveis: 1.1, 2.0 e 3.0. + +- A versão 1.1 é a geração antiga e está congelada, recebendo apenas + correções de bugs. +- A versão 2.0 é a versão estável atual e está congelada, recebendo apenas + correções de bugs. +- A versão 3.0 é a versão atual em desenvolvimento. Este guia trata + principalmente da versão 3. + + +## Requisitos e pré-requisitos + +O Yii3 exige PHP 8.2 ou superior, mas alguns pacotes funcionam com versões +mais antigas, como o PHP 7.4. + +Usar o Yii exige conhecimento básico de programação orientada a objetos +(POO), já que o Yii é um framework totalmente orientado a objetos. O Yii3 +também usa recursos recentes do PHP, como declarações de tipo e +generators. Entender esses conceitos vai ajudar você a aprender o Yii3 mais +rápido. + diff --git a/src/pt-BR/guide/rest/quick-start.md b/src/pt-BR/guide/rest/quick-start.md new file mode 100644 index 00000000..4805a677 --- /dev/null +++ b/src/pt-BR/guide/rest/quick-start.md @@ -0,0 +1,357 @@ +# Quick start + +Yii works with JSON APIs through the same PSR-7 request and response objects +used by web pages. For API endpoints, the usual flow is: + +* Parse the request body when the client sends JSON. +* Map request data to a typed input object. +* Validate the input object. +* Return a response whose data is formatted as JSON. + +This guide assumes that you use the [API application +template](https://github.com/yiisoft/app-api). It already includes request +body parsing, request input resolving, JSON data responses, and presenter +examples. For complete applications with different structures, see [Demo +applications](../start/demo-apps.md). + +## Creating request input + +Use [yiisoft/input-http](https://github.com/yiisoft/input-http) to describe +request data as a typed input object. Attach `#[FromBody]` when all values +should come from the parsed request body. + +Create `src/Api/Post/CreatePostInput.php`: + +```php +getValidationResult(); + + if (!$result->isValid()) { + return $responseFactory->failValidation($result); + } + + return $responseFactory + ->success([ + 'title' => $input->title, + 'content' => $input->content, + ]) + ->withStatus(Status::CREATED); + } +} +``` + +You can validate the input in the action as shown above. Alternatively, +configure `RequestInputParametersResolver` to throw +`Yiisoft\Input\Http\InputValidationException` and convert that exception to +a JSON response in one error handler. The API application template uses +this centralized approach. + +## Returning JSON responses + +For small endpoints, you can write JSON to a PSR-7 response manually as +shown in [Responding with +JSON](../runtime/response.md#responding-with-json). For APIs, prefer +[yiisoft/data-response](https://github.com/yiisoft/data-response), which +formats response data and sets the `Content-Type` header. + +The API application template keeps response formatting in +`src/Api/Shared/ResponseFactory.php`: + +```php +dataResponseFactory->createResponse([ + 'status' => 'success', + 'data' => $presenter->present($data), + ]); + } + + public function failValidation(Result $result): ResponseInterface + { + return $this->dataResponseFactory + ->createResponse([ + 'status' => 'failed', + 'error_message' => 'Validation failed.', + 'error_data' => (new ValidationResultPresenter())->present($result), + ]) + ->withStatus(Status::UNPROCESSABLE_ENTITY); + } +} +``` + +Presenters are application-level abstractions that transform application +objects to API output arrays. Keep them separate from domain entities so +changing an API response doesn't force changes in business objects. + +Create `src/Api/Post/PostPresenter.php`: + +```php + + */ +final readonly class PostPresenter implements PresenterInterface +{ + public function present(mixed $value): array + { + return [ + 'id' => $value->id, + 'title' => $value->title, + 'content' => $value->content, + ]; + } +} +``` + +The API template contains a fuller implementation of [response +factory](https://github.com/yiisoft/app-api/blob/master/src/Api/Shared/ResponseFactory.php) +and +[presenters](https://github.com/yiisoft/app-api/tree/master/src/Api/Shared/Presenter). + +## Routing an endpoint + +Register API routes in `config/common/routes.php`: + +```php +use App\Api\Post\CreatePostAction; +use Yiisoft\Http\Method; +use Yiisoft\Router\Route; + +return [ + Route::methods([Method::POST], '/posts') + ->action(CreatePostAction::class) + ->name('api/posts/create'), +]; +``` + +Send JSON by setting `Content-Type: application/json`. Ask for JSON +responses with `Accept: application/json`. + +```shell +curl -X POST http://localhost:8080/posts \ + -H 'Content-Type: application/json' \ + -H 'Accept: application/json' \ + -d '{"title":"First post","content":"Text"}' +``` + +Validation errors are returned as JSON with HTTP status `422 Unprocessable +Entity`. Successful creation usually returns `201 Created`. + +## Existing applications + +If you add JSON API endpoints to an existing web application, install the +API packages first: + +```shell +composer require yiisoft/input-http yiisoft/request-body-parser yiisoft/data-response +``` + +If you use Docker: + +```shell +make composer require yiisoft/input-http yiisoft/request-body-parser yiisoft/data-response +``` + +In `config/web/di/application.php`, add `RequestBodyParser` before `Router` +so JSON requests are parsed before actions run: + +```php +use Yiisoft\Request\Body\RequestBodyParser; +use Yiisoft\Router\Middleware\Router; + +return [ + RequestBodyParser::class, + Router::class, +]; +``` + +In the same file, add JSON data response middleware before error handling +and routing: + +```php +use Yiisoft\DataResponse\Formatter\JsonFormatter; +use Yiisoft\DataResponse\Middleware\ContentNegotiatorDataResponseMiddleware; + +return [ + static fn() => new ContentNegotiatorDataResponseMiddleware( + formatters: [ + 'application/json' => new JsonFormatter(), + ], + fallback: new JsonFormatter(), + ), + // error handling, request body parser, router, and not-found middleware +]; +``` + +Also in `config/web/di/application.php`, configure action parameter +resolvers: + +```php +use Yiisoft\Definitions\Reference; +use Yiisoft\Input\Http\HydratorAttributeParametersResolver; +use Yiisoft\Input\Http\RequestInputParametersResolver; +use Yiisoft\Middleware\Dispatcher\CompositeParametersResolver; +use Yiisoft\Middleware\Dispatcher\ParametersResolverInterface; + +return [ + ParametersResolverInterface::class => [ + 'class' => CompositeParametersResolver::class, + '__construct()' => [ + Reference::to(HydratorAttributeParametersResolver::class), + Reference::to(RequestInputParametersResolver::class), + ], + ], +]; +``` + +Use the [API application template +configuration](https://github.com/yiisoft/app-api/blob/master/config/web/di/application.php) +as the complete reference for middleware order and resolver setup. diff --git a/src/pt-BR/guide/runtime/cookies.md b/src/pt-BR/guide/runtime/cookies.md new file mode 100644 index 00000000..9a8ff8a1 --- /dev/null +++ b/src/pt-BR/guide/runtime/cookies.md @@ -0,0 +1,211 @@ +# Cookies + +Cookies are for persisting data between requests by sending it to the client +browser using HTTP headers. The client sends data back to the server in +request headers. Thus, cookies are handy to store small amounts of data, +such as tokens or flags. + +## Reading cookies + +You could obtain Cookie values from server request that's available as route +handler (such as controller action) argument: + +```php +private function actionProfile(\Psr\Http\Message\ServerRequestInterface $request) +{ + $cookieValues = $request->getCookieParams(); + $cookieValue = $cookieValues['cookieName'] ?? null; + // ... +} +``` + +In addition to getting cookie values directly from the server request, you +can also use the +[yiisoft/request-provider](https://github.com/yiisoft/request-provider) +package, which provides a more structured way to handle cookies through the +`\Yiisoft\RequestProvider\RequestCookieProvider`. This approach can +simplify your code and improve readability. + +Here’s an example of how to work with cookies using the +`\Yiisoft\RequestProvider\RequestCookieProvider`: + +```php +final readonly class MyService +{ + public function __construct( + private \Yiisoft\RequestProvider\RequestCookieProvider $cookies + ) {} + + public function go(): void + { + // Check if a specific cookie exists + if ($this->cookies->has('foo')) { + // Retrieve the value of the cookie + $fooValue = $this->cookies->get('foo'); + // Do something with the cookie value + } + + // Retrieve another cookie value + $barValue = $this->cookies->get('bar'); + // Do something with the bar cookie value + } +} + +## Sending cookies + +Since sending cookies is, in fact, sending a header but since forming the header isn't trivial, there is +`\Yiisoft\Cookies\Cookie` class to help with it: + +```php +$cookie = (new \Yiisoft\Cookies\Cookie('cookieName', 'value')) + ->withPath('/') + ->withDomain('yiiframework.com') + ->withHttpOnly(true) + ->withSecure(true) + ->withSameSite(\Yiisoft\Cookies\Cookie::SAME_SITE_STRICT) + ->withMaxAge(new \DateInterval('P7D')); + +return $cookie->addToResponse($response); +``` + +After forming a cookie call `addToResponse()` passing an instance of +`\Psr\Http\Message\ResponseInterface` to add corresponding HTTP headers to +it. + +## Signing and encrypting cookies + +To prevent the substitution of the cookie value, the package provides two +implementations: + +`Yiisoft\Cookies\CookieSigner` - signs each cookie with a unique prefix hash +based on the value of the cookie and a secret key. +`Yiisoft\Cookies\CookieEncryptor` - encrypts each cookie with a secret key. + +Encryption is more secure than signing but has lower performance. + +```php +$cookie = new \Yiisoft\Cookies\Cookie('identity', 'identityValue'); + +// The secret key used to sign and validate cookies. +$key = '0my1xVkjCJnD_q1yr6lUxcAdpDlTMwiU'; + +$signer = new \Yiisoft\Cookies\CookieSigner($key); +$encryptor = new \Yiisoft\Cookies\CookieEncryptor($key); + +$signedCookie = $signer->sign($cookie); +$encryptedCookie = $encryptor->encrypt($cookie); +``` + +To validate and get back the pure value, use the `validate()` and +`decrypt()` method. + +```php +$cookie = $signer->validate($signedCookie); +$cookie = $encryptor->decrypt($encryptedCookie); +``` + +If the cookie value is tampered with or hasn't been signed/encrypted before, +a `\RuntimeException` will be thrown. Therefore, if you aren't sure that +the cookie value was signed/encrypted earlier, first use the `isSigned()` +and `isEncrypted()` methods, respectively. + +```php +if ($signer->isSigned($cookie)) { + $cookie = $signer->validate($cookie); +} + +if ($encryptor->isEncrypted($cookie)) { + $cookie = $encryptor->decrypt($cookie); +} +``` + +It makes sense to sign or encrypt the value of a cookie if you store +important data that a user shouldn't change. + +### Automating encryption and signing + +To automate the encryption/signing and decryption/validation of cookie +values, use an instance of `Yiisoft\Cookies\CookieMiddleware`, which is +[PSR-15](https://www.php-fig.org/psr/psr-15/) middleware. + +This middleware provides the following features: + +- Validates and decrypts the cookie parameter values from the request. +- Excludes the cookie parameter from the request if it was tampered with and + logs information about it. +- Encrypts/signs cookie values and replaces their clean values in the + `Set-Cookie` headers in the response. + +In order for the middleware to know which values of which cookies need to be +encrypted/signed, an array of settings must be passed to its +constructor. The array keys are cookie name patterns and values are constant +values of `CookieMiddleware::ENCRYPT` or `CookieMiddleware::SIGN`. + +```php +use Yiisoft\Cookies\CookieMiddleware; + +$cookiesSettings = [ + // Exact match with the name `identity`. + 'identity' => CookieMiddleware::ENCRYPT, + // Matches any number from 1 to 9 after the underscore. + 'name_[1-9]' => CookieMiddleware::SIGN, + // Matches any string after the prefix, including an + // empty string, except for the delimiters "/" and "\". + 'prefix*' => CookieMiddleware::SIGN, +]; +``` + +For more information on using the wildcard pattern, see the +[yiisoft/strings](https://github.com/yiisoft/strings#wildcardpattern-usage) +package. + +Creating and using middleware: + +```php +/** + * @var \Psr\Http\Message\ServerRequestInterface $request + * @var \Psr\Http\Server\RequestHandlerInterface $handler + * @var \Psr\Log\LoggerInterface $logger + */ + +// The secret key used to sign and validate cookies. +$key = '0my1xVkjCJnD_q1yr6lUxcAdpDlTMwiU'; +$signer = new \Yiisoft\Cookies\CookieSigner($key); +$encryptor = new \Yiisoft\Cookies\CookieEncryptor($key); + +$cookiesSettings = [ + 'identity' => \Yiisoft\Cookies\CookieMiddleware::ENCRYPT, + 'session' => \Yiisoft\Cookies\CookieMiddleware::SIGN, +]; + +$middleware = new \Yiisoft\Cookies\CookieMiddleware( + $logger + $encryptor, + $signer, + $cookiesSettings, +); + +// The cookie parameter values from the request are decrypted/validated. +// The cookie values are encrypted/signed and appended to the response. +$response = $middleware->process($request, $handler); +``` + +If the `$cookiesSettings` array is empty, no cookies will be encrypted and +signed. + +## Cookies security + +You should configure each cookie to be secure. Important security settings +are: + +- `httpOnly`. Setting it to `true` would prevent JavaScript to access cookie + value. +- `secure`. Setting it to `true` would prevent sending cookie via `HTTP`. It + will be sent via `HTTPS` only. +- `sameSite`, if set to either `SAME_SITE_LAX` or `SAME_SITE_STRICT` would + prevent sending a cookie in cross-site browsing context. `SAME_SITE_LAX` + would prevent cookie sending during CSRF-prone request methods (e.g., + POST, PUT, PATCH, etc.). `SAME_SITE_STRICT` would prevent cookies sending + for all methods. +- Sign or encrypt the value of the cookie to prevent spoofing of values if + the data in the value shouldn't be tampered with. diff --git a/src/pt-BR/guide/runtime/handling-errors.md b/src/pt-BR/guide/runtime/handling-errors.md new file mode 100644 index 00000000..b508d56d --- /dev/null +++ b/src/pt-BR/guide/runtime/handling-errors.md @@ -0,0 +1,318 @@ +# Handling errors + +Yii has a [yiisoft/error-handler](https://github.com/yiisoft/error-handler) +package that makes error handling a much more pleasant experience than +before. In particular, the Yii error handler provides the following: + +- [PSR-15](https://www.php-fig.org/psr/psr-15/) middleware for catching + unhandled errors. +- PSR-15 middleware for mapping certain exceptions to custom responses. +- Production and debug modes. +- Debug mode displays details, stacktrace, has dark and light themes and + handy buttons to search for error without typing. +- Takes PHP settings into account. +- Handles out of memory errors, fatal errors, warnings, notices, and + exceptions. +- Can use any [PSR-3](https://www.php-fig.org/psr/psr-3/) compatible logger + for error logging. +- Detects a response format based on a mime type of the request. +- Supports responding with HTML, plain text, JSON, XML, and headers out of + the box. +- You can implement your own error rendering for extra types. + +This guide describes how to use the error handler in the [Yii +framework](https://www.yiiframework.com/), for information about using it +separate from Yii, see the [package +description](https://github.com/yiisoft/error-handler). + +## Using error handler + +The error handler consists of two parts. One part is +`Yiisoft\ErrorHandler\Middleware\ErrorCatcher` middleware that, when +registered, catches exceptions that may appear during middleware stack +execution and passes them to the handler. Another part is the error handler +itself, `Yiisoft\ErrorHandler\ErrorHandler`, that's catching exceptions +occurring outside the middleware stack and fatal errors. The handler also +converts warnings and notices to exceptions and does more handy things. + +Error handler is registered in the application itself. Usually it happens in +`ApplicationRunner`. By default, the handler configuration comes from the +container. You may configure it in the application configuration, +`config/web.php` like the following: + +```php +use Psr\Log\LoggerInterface; +use Yiisoft\ErrorHandler\ErrorHandler; +use Yiisoft\ErrorHandler\Renderer\HtmlRenderer; +use Yiisoft\ErrorHandler\ThrowableRendererInterface; + +return [ + // ... + ErrorHandler::class => static function (LoggerInterface $logger, ThrowableRendererInterface $renderer) { + $errorHandler = new ErrorHandler($logger, $renderer); + // Set the size of the reserved memory to 512 KB. Defaults to 256KB. + $errorHandler->memoryReserveSize(524_288); + return $errorHandler; + }, + + ThrowableRendererInterface::class => static fn () => new HtmlRenderer([ + // Defaults to the package file "templates/production.php". + 'template' => '/full/path/to/production/template/file', + // Defaults to package file "templates/development.php". + 'verboseTemplate' => '/full/path/to/development/template/file', + // Maximum number of source code lines to be displayed. Defaults to 19. + 'maxSourceLines' => 20, + // Maximum number of trace source code lines to be displayed. Defaults to 13. + 'maxTraceLines' => 5, + // Trace the header line with placeholders (file, line, icon) to be substituted. Defaults to `null`. + 'traceHeaderLine' => '{icon}', + ]), + // ... +]; +``` + +As aforementioned, the error handler turns all non-fatal PHP errors into +catchable exceptions (`Yiisoft\ErrorHandler\Exception\ErrorException`). This +means you can use the following code to deal with PHP errors: + +```php +try { + 10 / 0; +} catch (\Yiisoft\ErrorHandler\Exception\ErrorException $e) { + // Write a log or something else. +} +// execution continues... +``` + +The package has another middleware, +`Yiisoft\ErrorHandler\Middleware\ExceptionResponder`. This middleware maps +certain exceptions to custom responses. Configure it in the application +configuration as follows: + +```php +use Psr\Http\Message\ResponseFactoryInterface; +use Yiisoft\ErrorHandler\Middleware\ExceptionResponder; +use Yiisoft\Injector\Injector; + +return [ + // ... + ExceptionResponder::class => static function (ResponseFactoryInterface $responseFactory, Injector $injector) { + $exceptionMap = [ + // Status code with which the factory creates the response. + MyNotFoundException::class => 404, + // PHP callable that must return a `Psr\Http\Message\ResponseInterface`. + MyHttpException::class => static fn (MyHttpException $exception) => new MyResponse($exception), + // ... + ]; + + return new ExceptionResponder($exceptionMap, $responseFactory, $injector); + }, +]; +``` + +Note that when configuring application middleware stack, you must place +`Yiisoft\ErrorHandler\Middleware\ExceptionResponder` before +`Yiisoft\ErrorHandler\Middleware\ErrorCatcher`. + +## Rendering error data + +One of the renderers could render error data into a certain format. The +following renderers are available out of the box: + +- `Yiisoft\ErrorHandler\Renderer\HeaderRenderer` - Renders error into HTTP + headers. It's used for `HEAD` request. +- `Yiisoft\ErrorHandler\Renderer\HtmlRenderer` - Renders error into HTML. +- `Yiisoft\ErrorHandler\Renderer\JsonRenderer` - Renders error into JSON. +- `Yiisoft\ErrorHandler\Renderer\PlainTextRenderer` - Renders error into + plain text. +- `Yiisoft\ErrorHandler\Renderer\XmlRenderer` - Renders error into XML. + +The renderer produces detailed error data depending on whether debug mode is +enabled or disabled. + +An Example of header rendering with a debugging mode turned off: + +``` +... +X-Error-Message: An internal server error occurred. +... +``` + +An Example of header rendering with a debugging mode turned on: + +``` +... +X-Error-Type: Error +X-Error-Message: Call to undefined function App\Controller\myFunc() +X-Error-Code: 0 +X-Error-File: /var/www/yii/app/src/Controller/SiteController.php +X-Error-Line: 21 +... +``` + +Example of JSON rendering output with a debugging mode turned off: + +```json +{"message":"An internal server error occurred."} +``` + +An Example of JSON rendering output with debugging mode turned on: + +```json +{ + "type": "Error", + "message": "Call to undefined function App\\Controller\\myFunc()", + "code": 0, + "file": "/var/www/yii/app/src/Controller/SiteController.php", + "line": 21, + "trace": [ + { + "function": "index", + "class": "App\\Controller\\SiteController", + "type": "->" + }, + { + "file": "/var/www/yii/app/vendor/yiisoft/injector/src/Injector.php", + "line": 63, + "function": "invokeArgs", + "class": "ReflectionFunction", + "type": "->" + }, + ... + ] +} +``` + +Example of HTML rendering with debugging mode turned off: + +![View production](/images/guide/runtime/view-production.png) + +Example of HTML rendering with debugging mode on and a light theme: + +![View development with light +theme](/images/guide/runtime/view-development-light.png) + +Example of HTML rendering with debugging mode on and a dark theme: + +![View development with dark +theme](/images/guide/runtime/view-development-dark.png) + +The error catcher chooses how to render an exception based on `accept` HTTP +header. If it's `text/html` or any unknown content type, it will use the +error or exception HTML template to display errors. For other mime types, +the error handler will choose different renderers registered in a renderer +provider. By default, it supports JSON, XML, and plain text. + +### Implementing your own renderer + +You may customize the error response format by implementing +`Yiisoft\ErrorHandler\ThrowableRendererInterface`. The renderer converts a +throwable into `Yiisoft\ErrorHandler\ErrorData`, which contains the response +body and headers. + +```php +use Psr\Http\Message\ServerRequestInterface; +use Throwable; +use Yiisoft\ErrorHandler\ErrorData; +use Yiisoft\ErrorHandler\ThrowableRendererInterface; +use Yiisoft\Http\Header; + +final readonly class MyRenderer implements ThrowableRendererInterface +{ + public function render(Throwable $t, ?ServerRequestInterface $request = null): ErrorData + { + return new ErrorData( + '{"message":"An internal server error occurred."}', + [Header::CONTENT_TYPE => 'application/problem+json'], + ); + } + + public function renderVerbose(Throwable $t, ?ServerRequestInterface $request = null): ErrorData + { + return new ErrorData( + json_encode( + [ + 'type' => $t::class, + 'message' => $t->getMessage(), + 'file' => $t->getFile(), + 'line' => $t->getLine(), + ], + JSON_THROW_ON_ERROR | JSON_UNESCAPED_SLASHES, + ), + [Header::CONTENT_TYPE => 'application/problem+json'], + ); + } +} +``` + +Register the renderer in `config/common/di/error-handler.php`: + +```php +use Psr\Container\ContainerInterface; +use App\Error\MyRenderer; +use Yiisoft\Definitions\DynamicReference; +use Yiisoft\ErrorHandler\Renderer\HtmlRenderer; +use Yiisoft\ErrorHandler\Renderer\JsonRenderer; +use Yiisoft\ErrorHandler\Renderer\PlainTextRenderer; +use Yiisoft\ErrorHandler\Renderer\XmlRenderer; +use Yiisoft\ErrorHandler\RendererProvider\CompositeRendererProvider; +use Yiisoft\ErrorHandler\RendererProvider\ContentTypeRendererProvider; +use Yiisoft\ErrorHandler\RendererProvider\HeadRendererProvider; +use Yiisoft\ErrorHandler\ThrowableResponseFactory; +use Yiisoft\ErrorHandler\ThrowableResponseFactoryInterface; + +return [ + ThrowableResponseFactoryInterface::class => [ + 'class' => ThrowableResponseFactory::class, + '__construct()' => [ + 'rendererProvider' => DynamicReference::to( + static fn (ContainerInterface $container) => new CompositeRendererProvider( + new HeadRendererProvider(), + new ContentTypeRendererProvider($container, [ + 'application/problem+json' => MyRenderer::class, + 'application/json' => JsonRenderer::class, + 'application/xml' => XmlRenderer::class, + 'text/xml' => XmlRenderer::class, + 'text/plain' => PlainTextRenderer::class, + 'text/html' => HtmlRenderer::class, + '*/*' => HtmlRenderer::class, + ]), + ), + ), + ], + ], +]; +``` + +The `renderers` array maps `Accept` header content types to renderer class +names. When you provide this array, it replaces the default map, so include +the default renderer classes you still need. + +## Friendly exceptions + +Yii error renderer supports [friendly +exceptions](https://github.com/yiisoft/friendly-exception) that make error +handling an even more pleasant experience for your team. The idea is to +offer a readable name and possible solutions to the problem: + +```php +use Yiisoft\FriendlyException\FriendlyExceptionInterface; + +final readonly class RequestTimeoutException extends \RuntimeException implements FriendlyExceptionInterface +{ + public function getName(): string + { + return 'Request timed out'; + } + + public function getSolution(): ?string + { + return <<<'SOLUTION' +Likely it is a result of resource request is not responding in a timely fashion. Try increasing timeout. +SOLUTION; + } +} +``` + +When the application throws such an exception, the error renderer would +display the name and the solution if the debug mode is on. diff --git a/src/pt-BR/guide/runtime/logging.md b/src/pt-BR/guide/runtime/logging.md new file mode 100644 index 00000000..b4b27193 --- /dev/null +++ b/src/pt-BR/guide/runtime/logging.md @@ -0,0 +1,496 @@ +# Logging + +Yii relies on [PSR-3 interfaces](https://www.php-fig.org/psr/psr-3/) for +logging, so you could configure any PSR-3 compatible logging library to do +the actual job. + +Yii provides its own logger that's highly customizable and extensible. +Using it, you can log various types of messages, filter them, and gather +them at different targets, such as files or emails. + +Using the Yii logging framework involves the following steps: + +* Record [log messages](#log-messages) at various places in your code; +* Configure [log targets](#log-targets) in the application configuration to + filter and export log messages; +* Examine the filtered logged messages exported by different targets + (e.g. the Yii debugger). + +In this section, the focus in on the first two steps. + +## Default log destination + +Yii3 application templates +([web](https://github.com/yiisoft/app/blob/master/config/common/di/logger.php) +and +[API](https://github.com/yiisoft/app-api/blob/master/config/common/di/logger.php)) +configure `Yiisoft\Log\StreamTarget`, which writes to standard output +(`stdout`, or `php://stdout`) by default. They don't create application log +files, such as `runtime/logs/app.log`. `StreamTarget` also supports +standard error (`stderr`, or `php://stderr`), but you must configure it +explicitly. + +This works well with Docker, which [collects container output](https://docs.docker.com/engine/logging/). +Use `docker logs ` to read it when the container's logging driver supports that command. + +Without containers, the destination depends on how you start PHP and capture +its output. For example, PHP-FPM discards worker output by default unless +you enable `catch_workers_output`. See [web server logging +configuration](../../cookbook/configuring-webservers/general.md#application-logs). +To have Yii write application log files directly, configure a [file +target](#logging-to-files). + +## Log Messages + +To record log messages, you need an instance of PSR-3 logger. A class that +writes log messages should receive it as a dependency: + +```php +class MyService +{ + private $logger; + + public function __construct(\Psr\Log\LoggerInterface $logger) + { + $this->logger = $logger; + } +} +``` + +Recording a log message is as simple as calling one of the following logging +methods that correspond to log levels: + +- `emergency` - System is unusable. +- `alert` - Action must be taken immediately. Example: Entire website down, + database unavailable, etc. This should trigger the SMS alerts and wake + you up. +- `critical` - Critical conditions. Example: Application component + unavailable, unexpected exception. +- `error` - Runtime errors that don't require immediate action but should + typically be logged and monitored. +- `warning` - Exceptional occurrences that aren't errors. Example: Use of + deprecated APIs, poor use of an API, undesirable things that aren't + necessarily wrong. +- `notice` - Normal but significant events. +- `info` - Interesting events. Example: User logs in, SQL logs. +- `debug` - Detailed debug information. + +Each method has two arguments. The first is a message. The Second is a +context array that typically has structured data that doesn't fit a message +well but still does offer important information. In case you provide an +exception as context, you should pass the "exception" key. Another special +key is "category." Categories are handy to better organize and filter log +messages. + +```php +use \Psr\Log\LoggerInterface; + +final readonly class MyService +{ + public function __construct( + private LoggerInterface $logger + ) + { + } + + public function serve(): void + { + $this->logger->info('MyService is serving', ['context' => __METHOD__]); + } +} +``` + +When deciding on a category for a message, you may choose a hierarchical +naming scheme, which will make it easier for [log targets](#log-targets) to +filter messages based on their categories. A simple yet effective naming +scheme is to use the PHP magic constant `__METHOD__` for the category +names. This is also the approach used in the core Yii framework code. + +The `__METHOD__` constant evaluates as the name of the method (prefixed with +the fully qualified class name) where the constant appears. For example, +it's equal to the string `'App\\Service\\MyService::serve'` if the above +line of code is called within this method. + +> [!IMPORTANT] +> The logging methods described above are actually shortcuts to the [[\Psr\Log\LoggerInterface::log()]]. + +Note that PSR-3 package provides `\Psr\Log\NullLogger` class that provides +the same set of methods but doesn't log anything. That means that you don't +have to check if logger is configured with `if ($logger !== null)` and, +instead, can assume that logger is always present. + + +## Log targets + +A log target is an instance of a class that extends the +[[\Yiisoft\Log\Target]]. It filters the log messages by their severity +levels and categories and then exports them to some medium. For example, a +[[\Yiisoft\Log\Target\File\FileTarget|file target]]exports the filtered log +messages to a file, while a [[Yiisoft\Log\Target\Email\EmailTarget|email +target]] exports the log messages to specified email addresses. + +You can register many log targets in an application by configuring them +through the `\Yiisoft\Log\Logger` constructor: + +```php +use \Psr\Log\LogLevel; + +$fileTarget = new \Yiisoft\Log\Target\File\FileTarget('/path/to/app.log'); +$fileTarget->setLevels([LogLevel::ERROR, LogLevel::WARNING]); + +$emailTarget = new \Yiisoft\Log\Target\Email\EmailTarget($mailer, ['to' => 'log@example.com']); +$emailTarget->setLevels([LogLevel::EMERGENCY, LogLevel::ALERT, LogLevel::CRITICAL]); +$emailTarget->setCategories(['Yiisoft\Cache\*']); + +$logger = new \Yiisoft\Log\Logger([ + $fileTarget, + $emailTarget +]); +``` + +In the above code, two log targets are registered: + +* the first target selects error and warning messages and writes them to + `/path/to/app.log` file; +* the second target selects emergency, alert, and critical messages under the categories whose names start with +`Yiisoft\Cache\`, and sends them in an email to both `admin@example.com` and `developer@example.com`. + +Yii comes with the following built-in log targets. Please refer to the API +documentation about these classes to learn how to configure and use them. + +* [[\Yiisoft\Log\PsrTarget]]: passes log messages to another PSR-3 + compatible logger. +* [[\Yiisoft\Log\StreamTarget]]: writes log messages into a specified output + stream. +* [[\Yiisoft\Log\Target\Db\DbTarget]]: saves log messages in database. +* [[\Yiisoft\Log\Target\Email\EmailTarget]]: sends log messages to + pre-specified email addresses. +* [[\Yiisoft\Log\Target\File\FileTarget]]: saves log messages in files. +* [[\Yiisoft\Log\Target\Syslog\SyslogTarget]]: saves log messages to syslog + by calling the PHP function `syslog()`. + +### Logging to files + +To write application logs to a file, install the file target package: + +```shell +composer require yiisoft/log-target-file +``` + +In your application's `config/common/di/logger.php`, replace the +`StreamTarget` reference with `FileTarget`: + +```php +use Psr\Log\LoggerInterface; +use Yiisoft\Definitions\ReferencesArray; +use Yiisoft\Log\Logger; +use Yiisoft\Log\Target\File\FileTarget; + +return [ + LoggerInterface::class => [ + 'class' => Logger::class, + '__construct()' => [ + 'targets' => ReferencesArray::from([ + FileTarget::class, + ]), + ], + ], +]; +``` + +The package's default configuration writes to `@runtime/logs/app.log` and +enables log rotation. To change the path, set +`$params['yiisoft/log-target-file']['fileTarget']['file']` in +`config/common/params.php`. Ensure that the PHP process can write to the +log directory, and keep it outside the web server's document root. + +The file target package's default configuration also filters out `alert`, +`critical`, and `notice` messages. The templates' `StreamTarget` accepts +all eight log levels. To keep that behavior, add the following entry to the +array that `config/common/params.php` returns: + +```php +use Psr\Log\LogLevel; + +return [ + // Other application parameters... + 'yiisoft/log-target-file' => [ + 'fileTarget' => [ + 'levels' => [ + LogLevel::EMERGENCY, + LogLevel::ALERT, + LogLevel::CRITICAL, + LogLevel::ERROR, + LogLevel::WARNING, + LogLevel::NOTICE, + LogLevel::INFO, + LogLevel::DEBUG, + ], + ], + ], +]; +``` + +In the following, we will describe the features common to all log targets. + +### Message Filtering + +For each log target, you can configure its levels and categories to specify +which severity levels and categories of the messages the target should +process. + +The target `setLevels()` method takes an array consisting of one or several +of `\Psr\Log\LogLevel` constants. + +By default, the target will process messages of *any* severity level. + +The target `setCategories()` method takes an array consisting of message +category names or patterns. A target will only process messages whose +category can be found or match one of the patterns in this array. A +category pattern is a category name prefix with an asterisk `*` at its +end. A category name matches a category pattern if it starts with the same +prefix of the pattern. For example, `Yiisoft\Cache\Cache::set` and +`Yiisoft\Cache\Cache::get` both match the pattern `Yiisoft\Cache\*`. + +By default, the target will process messages of *any* category. + +Besides allowing the categories by the `setCategories()` method, you may +also deny certain categories by the `setExcept()` method. If the category +of a message is found or matches one of the patterns in this property, the +target will NOT process it. + +The following target configuration specifies that the target should only +process error and warning messages under the categories whose names match +either `Yiisoft\Cache\*` or `App\Exceptions\HttpException:*`, but not +`App\Exceptions\HttpException:404`. + +```php +$fileTarget = new \Yiisoft\Log\Target\File\FileTarget('/path/to/app.log'); +$fileTarget->setLevels([LogLevel::ERROR, LogLevel::WARNING]); +$fileTarget->setCategories(['Yiisoft\Cache\*', 'App\Exceptions\HttpException:*']); +$fileTarget->setExcept(['App\Exceptions\HttpException:404']); +``` + +### Message Formatting + +Log targets export the filtered log messages in a certain format. For +example, if you install a log target of the class +[[\Yiisoft\Log\Target\File\FileTarget]], you may find a log message similar +to the following in the log file: + +``` +2020-12-05 09:27:52.223800 [info][application] Some message + +Message context: + +time: 1607160472.2238 +memory: 4398536 +category: 'application' +``` + +By default, log messages have the following format: + +``` +Timestamp Prefix[Level][Category] Message Context +``` + +You may customize this format by calling +[[\Yiisoft\Log\Target::setFormat()|setFormat()]] method, which takes a PHP +callable returning a custom-formatted message. + +```php +$fileTarget = new \Yiisoft\Log\Target\File\FileTarget('/path/to/app.log'); + +$fileTarget->setFormat(static function (\Yiisoft\Log\Message $message) { + $category = strtoupper($message->context('category')); + return "({$category}) [{$message->level()}] {$message->message()}"; +}); + +$logger = new \Yiisoft\Log\Logger([$fileTarget]); +$logger->info('Text message', ['category' => 'app']); + +// Result: +// (APP) [info] Text message +``` + +In addition, if you're comfortable with the default message format but need +to change the timestamp format or add custom data to the message, you can +call the [[\Yiisoft\Log\Target::setTimestampFormat()|setTimestampFormat()]] +and [[\Yiisoft\Log\Target::setPrefix()|setPrefix()]] methods. For example, +the following code changes the timestamp format and configures a log target +to prefix each log message with the current user ID (IP address and Session +ID are removed for privacy reasons). + +```php +$fileTarget = new \Yiisoft\Log\Target\File\FileTarget('/path/to/app.log'); +$userId = '123e4567-e89b-12d3-a456-426655440000'; + +// Default: 'Y-m-d H: i: s.u' +$fileTarget->setTimestampFormat('D d F Y'); +// Default: '' +$fileTarget->setPrefix(static fn () => "[{$userId}]"); + +$logger = new \Yiisoft\Log\Logger([$fileTarget]); +$logger->info('Text', ['category' => 'user']); + +// Result: +// Fri 04 December 2020 [123e4567-e89b-12d3-a456-426655440000][info][user] Text +// Message context: ... +// Common context: ... +``` + +The PHP callable that's passed to the +[[\Yiisoft\Log\Target::setFormat()|setFormat()]] and +[[\Yiisoft\Log\Target::setPrefix()|setPrefix()]] methods has the following +signature: + +```php +function (\Yiisoft\Log\Message $message, array $commonContext): string; +``` + +Besides message prefixes, log targets also append some common context information to each of the log messages. +You may adjust this behavior by calling target [[\Yiisoft\Log\Target::setCommonContext()|setCommonContext()]] +method, passing an array of data in the `key => value` format that you want to include. +For example, the following log target configuration specifies that only the +value of the `$_SERVER` variable will be appended to the log messages. + +```php +$fileTarget = new \Yiisoft\Log\Target\File\FileTarget('/path/to/app.log'); +$fileTarget->setCommonContext(['server' => $_SERVER]); +``` + + +### Message Trace Level + +During development, it's often desirable to see where each log message is +coming from. You can achieve this by calling the +[[\Yiisoft\Log\Logger::setTraceLevel()|setTraceLevel()]] method like the +following: + +```php +$logger = new \Yiisoft\Log\Logger($targets); +$logger->setTraceLevel(3); +``` + +This application configuration sets the trace level to be 3, so each log +message will be appended with at most three levels of the call stack at +which the log message is recorded. You can also set a list of paths to +exclude from the trace by calling the +[[\Yiisoft\Log\Logger::setExcludedTracePaths()|setExcludedTracePaths()]] +method. + +```php +$logger = new \Yiisoft\Log\Logger($targets); +$logger->setExcludedTracePaths(['/path/to/file', '/path/to/folder']); +``` + +> [!IMPORTANT] +> Getting call stack information isn't trivial. Therefore, you should only use this feature during development +or when debugging an application. + + +### Message flushing and exporting + +As aforementioned, log messages are maintained in an array by +[[\Yiisoft\Log\Logger|logger object]]. To limit the memory consumption by +this array, the logger will flush the recorded messages to the [log +targets](#log-targets) each time the array accumulates a certain number of +log messages. You can customize this number by calling the +[[\Yiisoft\Log\Logger::setFlushInterval()]] method: + + +```php +$logger = new \Yiisoft\Log\Logger($targets); +$logger->setFlushInterval(100); // default is 1000 +``` + +> [!IMPORTANT] +> Message flushing also occurs when the application ends, +which ensures log targets can receive complete log messages. + +When the [[\Yiisoft\Log\Logger|logger object]] flushes log messages to [log targets](#log-targets), +they don't get exported immediately. Instead, the message exporting only occurs when a log target + accumulates a certain number of the filtered messages. You can customize this number by calling the +[[\Yiisoft\Log\Target::setExportInterval()|setExportInterval()]] method of individual +[log targets](#log-targets), like the following: + +```php +$fileTarget = new \Yiisoft\Log\Target\File\FileTarget('/path/to/app.log'); +$fileTarget->setExportInterval(100); // default is 1000 +``` + +Because of the flushing and exporting level setting, by default when you +call any logging method, you will NOT see the log message immediately in the +log targets. This could be a problem for some long-running console +applications. To make each log message appear immediately in the log +targets, you should set both flush interval and export interval to be 1, as +shown below: + +```php +$fileTarget = new \Yiisoft\Log\Target\File\FileTarget('/path/to/app.log'); +$fileTarget->setExportInterval(1); + +$logger = new \Yiisoft\Log\Logger([$fileTarget]); +$logger->setFlushInterval(1); +``` + +> [!NOTE] +> Frequent message flushing and exporting will degrade the performance of your application. + + +### Toggling log targets + +You can enable or disable a log target by calling its +[[\Yiisoft\Log\Target::enable()|enable()] ] and +[[\Yiisoft\Log\Target::disable()|disable()]] methods. You may do so via the +log target configuration or by the following PHP statement in your code: + +```php +$fileTarget = new \Yiisoft\Log\Target\File\FileTarget('/path/to/app.log'); +$logger = new \Yiisoft\Log\Logger([$fileTarget, /*Other targets*/]); + +foreach ($logger->getTargets() as $target) { + if ($target instanceof \Yiisoft\Log\Target\File\FileTarget) { + $target->disable(); + } +} +``` + +To check whether the log target is enabled, call the `isEnabled()` method. +You also may pass callable to +[[\Yiisoft\Log\Target::setEnabled()|setEnabled()]] to define a dynamic +condition for whether the log target should be enabled or not. + + +### Creating new targets + +Creating a new log target class is straightforward. You mainly need to +implement the [[\Yii\Log\Target::export()]] abstract method that sends all +accumulated log messages to a designated medium. + +The following protected methods will also be available for child targets: + +- `getMessages` - Get a list of log messages ([[\Yii\Log\Message]] + instances). +- `getFormattedMessages` - Get a list of log messages formatted as strings. +- `formatMessages` - Get all log messages formatted as a string. +- `getCommonContext` - Get an array with common context data in the `key => + value` format. + +For more details, you may refer to any of the log target classes included in +the package. + +> [!TIP] +> Instead of creating your own loggers, you may try any PSR-3 compatible logger such +as [Monolog](https://github.com/Seldaek/monolog) by using [[\Yii\Log\PsrTarget]]. + +```php +/** + * @var \Psr\Log\LoggerInterface $psrLogger + */ + +$psrTarget = new \Yiisoft\Log\PsrTarget($psrLogger); +$logger = new \Yiisoft\Log\Logger([$psrTarget]); + +$logger->info('Text message'); +``` diff --git a/src/pt-BR/guide/runtime/request.md b/src/pt-BR/guide/runtime/request.md new file mode 100644 index 00000000..bd8ffae6 --- /dev/null +++ b/src/pt-BR/guide/runtime/request.md @@ -0,0 +1,336 @@ +# Request + +HTTP request has a method, URI, a set of headers and a body: + +``` +POST /contact HTTP/1.1 +Host: example.org +Accept-Language: en-us +Accept-Encoding: gzip, deflate + +{ + "subject": "Hello", + "body": "Hello there, we need to build Yii application together!" +} +``` + +The method is `POST`, URI is `/contact`. Extra headers are specifying host, +preferred language and encoding. The body could be anything. In this case, +it's a JSON payload. + +Yii uses [PSR-7 `ServerRequest`](https://www.php-fig.org/psr/psr-7/) as +request representation. The object is available in controller actions and +other types of middleware: + +```php +public function view(ServerRequestInterface $request): ResponseInterface +{ + // ... +} +``` + +## Method + +The method could be obtained from a request object: + +```php +$method = $request->getMethod(); +``` + +Usually it's one of the: + +- GET +- POST +- PUT +- DELETE +- HEAD +- PATCH +- OPTIONS + +In case you want to make sure the request method is of a certain type, there +is a special class with method names: + +```php +use Yiisoft\Http\Method; + +if ($request->getMethod() === Method::POST) { + // method is POST +} +``` + +## URI + +A URI has: + +- Scheme (`http`, `https`) +- Host (`yiiframework.com`) +- Port (`80`, `443`) +- Path (`/posts/1`) +- Query string (`page=1&sort=+id`) +- Fragment (`#anchor`) + +You can obtain `UriInterface` from request like the following: + +```php +$uri = $request->getUri(); +``` + +Then you can get various details from its methods: + +- `getScheme()` +- `getAuthority()` +- `getUserInfo()` +- `getHost()` +- `getPort()` +- `getPath()` +- `getQuery()` +- `getFragment()` + +## Headers + +There are various methods to inspect request headers. To get all headers as +an array: + +```php +$headers = $request->getHeaders(); +foreach ($headers as $name => $values) { + // ... +} +``` + +To get a single header: + +```php +$values = $request->getHeader('Accept-Encoding'); +``` + + +Also, you could get value as a comma-separated string instead of an array. +That's especially handy if a header has a single value: + +```php +if ($request->getHeaderLine('X-Requested-With') === 'XMLHttpRequest') { + // This is an AJAX request made with jQuery. + // Note that header presence and name may vary depending on the library used. +} +``` + +To check if a header is present in the request: + +```php +if ($request->hasHeader('Accept-Encoding')) { + // ... +} +``` + +## Body + +There are two methods to get body contents. The first is getting the body as +it is without parsing: + +```php +$body = $request->getBody(); +``` + +The `$body` would be an instance of `Psr\Http\Message\StreamInterface`. + +Also, you could get a parsed body: + +```php +$bodyParameters = $request->getParsedBody(); +``` + +Parsing depends on PSR-7 implementation and may require middleware for +custom body formats. + +```php +getHeaderLine('Content-Type'); + + if (strpos($contentType, 'application/json') !== false) { + $body = $request->getBody(); + $parsedBody = $this->parse($body); + $request = $request->withParsedBody($parsedBody); + + } + + return $next->handle($request); + } +} +``` + +## File uploads + +Uploaded files that user submitted from a form with `enctype` attribute +equals to `multipart/form-data` are handled via special request method: + +```php +$files = $request->getUploadedFiles(); +foreach ($files as $file) { + if ($file->getError() === UPLOAD_ERR_OK) { + $file->moveTo('path/to/uploads/new_filename.ext'); + } +} +``` + +Always validate the upload before reading the stream or moving the file. The +file may be missing, too large for PHP configuration, only partially +uploaded, rejected by a PHP extension, or not match the file type and size +your application expects. Yii Validator provides the +`Yiisoft\Validator\Rule\File` rule for this. It accepts PSR-7 +`UploadedFileInterface` values and validates upload error codes, extension, +MIME type, and size. Use `Yiisoft\Validator\Rule\Each` when a field contains +several files. + +The following example handles a single `avatar` upload. It validates the +uploaded file with Yii Validator, stores the file outside the public +directory, and generates its own file name instead of trusting the +client-provided name. + +```php + + */ + private const EXTENSIONS = [ + 'image/jpeg' => 'jpg', + 'image/png' => 'png', + 'image/webp' => 'webp', + ]; + + public function __construct( + private Aliases $aliases, + private ResponseFactoryInterface $responseFactory, + ) { + } + + public function __invoke(ServerRequestInterface $request): ResponseInterface + { + $file = $request->getUploadedFiles()['avatar'] ?? null; + + $result = (new Validator())->validate( + ['avatar' => $file], + [ + 'avatar' => [ + new File( + extensions: ['jpg', 'jpeg', 'png', 'webp'], + mimeTypes: array_keys(self::EXTENSIONS), + maxSize: self::MAX_SIZE, + ), + new Image(skipOnError: true), + ], + ], + ); + + if (!$result->isValid() || !$file instanceof UploadedFileInterface) { + $messages = $result->getPropertyErrorMessages('avatar'); + return $this->badRequest( + $messages === [] ? 'Upload a file in the "avatar" field.' : implode(' ', $messages), + ); + } + + $uploadDirectory = $this->aliases->get('@runtime/uploads/avatars'); + $this->ensureDirectory($uploadDirectory); + + $temporaryPath = $uploadDirectory . DIRECTORY_SEPARATOR . bin2hex(random_bytes(16)) . '.upload'; + $file->moveTo($temporaryPath); + + $mediaType = (new finfo(FILEINFO_MIME_TYPE))->file($temporaryPath); + + if (!is_string($mediaType) || !isset(self::EXTENSIONS[$mediaType])) { + unlink($temporaryPath); + return $this->badRequest('Only JPEG, PNG, and WebP images are allowed.'); + } + + $fileName = bin2hex(random_bytes(16)) . '.' . self::EXTENSIONS[$mediaType]; + $targetPath = $uploadDirectory . DIRECTORY_SEPARATOR . $fileName; + + if (!rename($temporaryPath, $targetPath)) { + unlink($temporaryPath); + throw new RuntimeException('Unable to store uploaded file.'); + } + + $response = $this->responseFactory->createResponse(Status::CREATED); + $response->getBody()->write('Stored as ' . $fileName); + + return $response; + } + + private function badRequest(string $message): ResponseInterface + { + $response = $this->responseFactory->createResponse(Status::BAD_REQUEST); + $response->getBody()->write($message); + + return $response; + } + + private function ensureDirectory(string $directory): void + { + if (!is_dir($directory) && !mkdir($directory, 0775, true) && !is_dir($directory)) { + throw new RuntimeException(sprintf('Directory "%s" was not created.', $directory)); + } + } +} +``` + +Notes: + +- Store uploads under `@runtime` or another non-public directory unless the + files are intentionally public. +- Do not use `getClientFilename()` as a storage path. A browser controls it, + so it may contain unsafe characters, path-like values, or duplicate names. +- Do not rely on `getClientMediaType()` alone. It comes from the client. Use + `File` MIME type validation, `Image` for image validation and dimension + checks, or another server-side parser appropriate for the file format. +- Check PHP limits such as `upload_max_filesize`, `post_max_size`, and + `max_file_uploads` when expected files are rejected before the action + runs. +- When a form uploads several files, the array returned by + `getUploadedFiles()` has the same shape as the file input names. Validate + them with `Each(new File(...))` and move each `UploadedFileInterface` + separately. +- `File` can also validate string file paths and `SplFileInfo` instances. Do + not pass user-submitted paths directly: use PSR-7 uploaded file objects + from the request, or perform upload provenance checks before validating + filesystem paths. + +## Attributes + +Application middleware may set custom request attributes using +`withAttribute()` method. You can get these attributes with +`getAttribute()`. + +Route arguments, such as `id` from a `/posts/{id}` route pattern, aren't +request attributes. Use `#[RouteArgument]` in an action parameter or inject +`Yiisoft\Router\CurrentRoute` when you need route arguments or route +metadata. diff --git a/src/pt-BR/guide/runtime/response.md b/src/pt-BR/guide/runtime/response.md new file mode 100644 index 00000000..d5bfb9e8 --- /dev/null +++ b/src/pt-BR/guide/runtime/response.md @@ -0,0 +1,134 @@ +# Response + +HTTP response has status code and message, a set of headers and a body: + +``` +HTTP/1.1 200 OK +Date: Mon, 27 Jul 2009 12:28:53 GMT +Server: Apache/2.2.14 (Win32) +Last-Modified: Wed, 22 Jul 2009 19:15:56 GMT +Content-Length: 6 +Content-Type: text/html +Connection: Closed + +Hello! +``` + +Yii uses [PSR-7 `Response`](https://www.php-fig.org/psr/psr-7/) in the web +application to represent response. + +The object should be constructed and returned as a result of the execution +of controller actions or other middleware. Usually, the middleware has a +response factory injected into its constructor. + +```php +use Psr\Http\Message\ResponseFactoryInterface; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\ServerRequestInterface; + +final readonly class PostAction +{ + public function __construct( + private ResponseFactoryInterface $responseFactory + ) + { + } + + public function view(ServerRequestInterface $request): ResponseInterface + { + $response = $this->responseFactory->createResponse(); + $response->getBody()->write('Hello!'); + return $response; + } +} +``` + +## Status code + +You can set a status code like the following: + +```php +use Yiisoft\Http\Status; + +$response = $response->withStatus(Status::NOT_FOUND); +``` + +Majority of status codes are available from `Status` class for convenience +and readability. + +Router may return a response before an action runs. For example, an +`OPTIONS` request to a known route path gets an automatic `204 No Content` +response with an `Allow` header that lists supported methods. See +[Automatic OPTIONS responses](routing.md#automatic-options-responses) for +routing details. + +## Headers + +You can set headers like this: + +```php +$response = $response->withHeader('Content-type', 'application/json'); +``` + +If there is a need to append a header value to the existing header: + +```php +$response = $response->withAddedHeader('Set-Cookie', 'qwerty=219ffwef9w0f; Domain=somecompany.co.uk; Path=/; Expires=Wed, 30 Aug 2019 00:00:00 GMT'); +``` + +And, if needed, headers could be removed: + +```php +$response = $response->withoutHeader('Set-Cookie'); +``` + +## Body + +Response body is an object implementing `Psr\Http\Message\StreamInterface`. + +You can write to it via the interface itself: + +```php +$body = $response->getBody(); +$body->write('Hello'); +``` + + +## Examples + +### Redirecting + +```php +use Yiisoft\Http\Status; + +return $response + ->withStatus(Status::PERMANENT_REDIRECT) + ->withHeader('Location', 'https://www.example.com'); +``` + +Note that there are different statuses used for redirection: + +| Code | Usage | What is it for | +|------|------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 301 | `Status::MOVED_PERMANENTLY` | Permanently changed a URL structure. Search engines update their indexes, and browsers cache it. | +| 308 | `Status::PERMANENT_REDIRECT` | Like 301, but guarantees the HTTP method won't change. | +| 302 | `Status::FOUND` | Temporary changes like maintenance pages. Original URL should still be used for future requests. Search engines typically don't update their indexes. | +| 307 | `Status::TEMPORARY_REDIRECT` | Like 302, but guarantees the HTTP method won't change. | +| 303 | `Status::SEE_OTHER` | After form submissions to prevent duplicate submissions if the user refreshes. Explicitly tells to use `GET` for the redirect, even if the original request was `POST`. | + +### Responding with JSON + +```php +use Yiisoft\Http\Status; +use Yiisoft\Json\Json; + +$data = [ + 'account' => 'samdark', + 'value' => 42 +]; + +$response->getBody()->write(Json::encode($data)); +return $response + ->withStatus(Status::OK) + ->withHeader('Content-Type', 'application/json'); +``` diff --git a/src/pt-BR/guide/runtime/routing.md b/src/pt-BR/guide/runtime/routing.md new file mode 100644 index 00000000..55940f32 --- /dev/null +++ b/src/pt-BR/guide/runtime/routing.md @@ -0,0 +1,582 @@ +# Routing and URL generation + +Usually, a Yii application processes certain requests with certain +handlers. It selects a handler based on the request URL. The part of the +application that does the job is a router, and the process of selecting a +handler, instantiating it and running a handler method is *routing*. + +The reverse process of routing is *URL generation*, which creates a URL from +a given named route, route arguments, and query parameters. When you later +request the created URL, the routing process can resolve it back into the +original route arguments and query parameters. + +Routing and URL generation are separate services, but they use a common set +of routes for both URL matching and URL generation. + +## Configuring routes + +By configuring routes, you can let your application recognize arbitrary URL +formats without modifying your existing application code. You can configure +routes in `/config/routes.php`. The structure of the file is the following: + +```php +action([SiteController::class, 'index']) + ->name('site/index') +]; +``` + +The file returns an array of routes. When defining a route, you start with a +method corresponding to a certain HTTP request type: + +- get +- post +- put +- delete +- patch +- head +- options + +If you need many methods, you can use `methods()`: + +```php +action([SiteController::class, 'user']) + ->name('site/user') +]; +``` + +All these methods accept a route pattern. The route pattern defines how the +router matches the URL when routing and how it generates URL based on route +name and parameters. You will learn about the actual syntax later in this +guide. Specify a handler with `action()` as: + +- [Middleware](../structure/middleware.md) class name. +- Handler action (an array of [HandlerClass, handlerMethod]). +- A callable. + +In case of a handler action, a class of type `HandlerClass` is instantiated +and its `handlerMethod` is called: + +```php +use Psr\Http\Message\ServerRequestInterface; +use Psr\Http\Message\ResponseInterface; + +final readonly class HandlerClass +{ + public function handle(ServerRequestInterface $request): ResponseInterface + { + // ... + } +} +``` + +The callable is called as is: + +```php +static function (ServerRequestInterface $request, RequestHandlerInterface $next) use ($responseFactory) { + $response = $responseFactory->createResponse(); + $response->getBody()->write('You are at homepage.'); + return $response; +} +``` + +For handler action and callable typed parameters are automatically injected +using the dependency injection container passed to the route. + +Get current request and handler by type-hinting for `ServerRequestInterface` +and `RequestHandlerInterface`. + +### Route arguments in actions + +Named route parameters are stored in `CurrentRoute`. To pass a route +parameter to an action method parameter, use the `RouteArgument` attribute: + +```php +action([PostController::class, 'view']) + ->name('post/view') +]; + +final readonly class PostController +{ + public function view(#[RouteArgument('id')] int $id): ResponseInterface + { + // $id contains the value from the {id} route parameter. + } +} +``` + +If a parameter has the same name as the action parameter, you can omit the +attribute name: + +```php +public function view(#[RouteArgument] int $id): ResponseInterface +{ + // ... +} +``` + +You can also inject `CurrentRoute` into an action or a service when you need +several arguments or route metadata: + +```php +getArgument('id'); + $routeName = $currentRoute->getName(); + + // ... + } +} +``` + +Route arguments aren't request attributes. Read them from `CurrentRoute` or +action parameters marked with `RouteArgument`. + +For optional route parameters, provide a default value either in the route +with `defaults()` or in the action method signature. + +You could add extra handlers to wrap primary one with `middleware()` method: + +```php +action([DownloadController::class, 'download']) + ->name('download/id') + ->middleware(LimitDownloadRate::class) +]; +``` + +Check ["the middleware"](../structure/middleware.md) guide to learn more +about how to implement middleware. + +This is especially useful when grouping routes: + +```php +middleware(ApiDataWrapper::class) + ->routes( + Route::get('/info/v2') + ->action(ApiInfo::class) + ->name('api/info/v2') + ->middleware(JsonDataResponseMiddleware::class), + Route::get('/user') + ->action([ApiUserController::class, 'index']) + ->name('api/user/index'), + Route::get('/user/{login}') + ->action([ApiUserController::class, 'profile']) + ->middleware(JsonDataResponseMiddleware::class) + ->name('api/user/profile'), + ) +]; +``` + +Router executes `ApiDataWrapper` before handling any URL starting with +`/api`. + +You could name a route with a `name()` method. It's a good idea to choose a +route name based on the handler's name. + +You can set a default value for a route parameter. For example: + + +```php +action([SiteController::class, 'user']) + ->name('site/user') + ->defaults(['id' => '42']) +]; +``` + +This configuration would result in a match with both `/user` and +`/user/123`. In both cases `CurrentRoute` service will contain `id` +argument filled. In the first case it will be default `42` and in the +second case it will be `123`. + +In cause URL should be valid for a single host, you can specify it with +`host()`. + +## Routing + +Yii routing is flexible, and internally it may use different routing +implementations. The actual matching algorithm may vary, but the basic idea +stays the same. + +Router matches routes defined in config from top to bottom. If there is a +match, further matching isn't performed and the router executes the route +handler to get the response. If there is no match at all, router passes +handling to the next middleware in the [application middleware +set](../structure/middleware.md). + +### Automatic OPTIONS responses + +When the request path matches a route but the HTTP method doesn't, router +returns a `405 Method Not Allowed` response with an `Allow` header: + +```http +HTTP/1.1 405 Method Not Allowed +Allow: GET +``` + +For an `OPTIONS` request to the same path, router returns an empty `204 No +Content` response with the same `Allow` header: + +```http +HTTP/1.1 204 No Content +Allow: GET +``` + +This response is generated from the configured routes before the route +action runs. If an API endpoint needs CORS headers, attach CORS middleware +to a route group: + +```php +withCors(CorsMiddleware::class) + ->routes( + Route::methods([Method::GET, Method::POST], '/posts') + ->action([PostController::class, 'index']) + ->name('api/posts') + ) +]; +``` + +## Generating URLs + +To generate URL based on a route, a route should have a name: + +```php +action([TestController::class, 'index']) + ->name('test/index'), + Route::post('/test/submit/{id}') + ->action([TestController::class, 'submit']) + ->name('test/submit') +]; +``` + + +The generation looks like the following: + +```php +generate('test/submit', ['id' => '42']); + // ... + } +} +``` + +In the above code, we get a generator instance with the help of [automatic +dependency injection](../concept/di-container.md) that works with action +handlers. In another service, you can get the instance with similar +constructor injection. In views URL generator is available as `$url`. + +Then we use `generate()` method to get the actual URL. It accepts a route +name, route arguments, query parameters, and a hash fragment. The code will +return `/test/submit/42`. + +Route arguments are used to fill placeholders in the route pattern. +Arguments that aren't used in the pattern are added to the query string when +the query parameters array doesn't already contain the same name: + +```php +$url = $urlGenerator->generate( + 'test/submit', + ['id' => '42', 'utm' => 'newsletter'], + ['page' => '1'] +); +// $url is "/test/submit/42?page=1&utm=newsletter". +``` + +If you need absolute URL, use `generateAbsolute()` instead. + +### Generating URL from the current route + +Use `generateFromCurrent()` when a link should keep the current route and +most of its arguments. For example, a detail page can link to another page +number while keeping the current route name and `id` argument: + +```php +$url = $urlGenerator->generateFromCurrent(['page' => '2']); +``` + +The method also keeps query parameters from the current request. Pass +explicit query parameters when a link should replace or add query string +values. + +### Locale-based URLs + +When the locale is part of the URL path, define it as a route argument. For +a Yii application with routes in `config/common/routes.php`, wrap localized +routes in a group with a locale parameter: + +```php +routes( + Route::get('/') + ->action(HomePageAction::class) + ->name('home'), + Route::get('/posts/{slug}') + ->action(PostViewAction::class) + ->name('post/view') + ) +]; +``` + +The route `/de/posts/welcome` matches the `post/view` route and stores +`_locale` as a route argument with the `de` value. + +In middleware that chooses the request locale, read this argument from +`CurrentRoute`: + +```php +currentRoute->getArgument('_locale', self::DEFAULT_LOCALE); + + $this->translator->setLocale($locale); + $this->view->setLocale($locale); + $this->urlGenerator->setDefaultArgument('_locale', $locale); + + return $handler->handle($request); + } +} +``` + +Register this middleware in the localized route group before the route +action: + +```php +use App\Web\HomePage\Action as HomePageAction; +use App\Web\Middleware\LocaleMiddleware; +use Yiisoft\Router\Group; +use Yiisoft\Router\Route; + +return [ + Group::create('/{_locale:en-US|de}') + ->middleware(LocaleMiddleware::class) + ->routes( + Route::get('/') + ->action(HomePageAction::class) + ->name('home') + ) +]; +``` + +After the middleware sets the default `_locale` argument, URL generation can +omit it: + +```php +$url = $urlGenerator->generate('post/view', ['slug' => 'welcome']); +// On a German page, $url is "/de/posts/welcome". +``` + +For a language switcher, use `generateFromCurrent()` and replace only the +locale argument: + +```php +$url = $urlGenerator->generateFromCurrent( + ['_locale' => 'en-US'], + fallbackRouteName: 'home' +); +``` + +## Route patterns + +Route patterns used depend on the underlying implementation used. The +default implementation is +[nikic/FastRoute](https://github.com/nikic/FastRoute). + +Basic patterns are static like `/test`. That means they must match exactly +in order for a route match. + +### Named Parameters + +A pattern can include one or more named parameters which are specified in +the pattern in the format of `{ParamName:RegExp}`, where `ParamName` +specifies the parameter name and `RegExp` is an optional regular expression +used to match parameter values. If `RegExp` isn't specified, it means the +parameter value should be a string without any slash. + +> [!NOTE] +> You can only use regular expressions inside parameters. The rest of the pattern is considered plain text. + +You can't use capturing groups. For example `{lang:(en|de)}` isn't a valid +placeholder, because `()` is a capturing group. Instead, you can use either +`{lang:en|de}` or `{lang:(?:en|de)}`. + +On a route match router fills `CurrentRoute` arguments with values matching +the corresponding parts of the URL. When you use the rule to create a URL, +it will take the values of the provided parameters and insert them at the +places where the parameters are declared. + +Let's use some examples to illustrate how named parameters work. Assume +you've declared the following three patterns: + + +1. `'posts/{year:\d{4}}/{category}` +2. `'posts'` +3. `'post/{id:\d+}'` + +- `/posts` match the second pattern; +- `/posts/2014/php` match a first pattern. Parameters are the `year` whose + value is 2014 and the `category` whose value is `php`; +- `/post/100` match a third pattern. The `id` parameter value is 100; +- `/posts/php` doesn't match. + +When generating URLs, you should use the following parameters: + +```php +echo $url->generate('first', ['year' => '2020', 'category' => 'Virology']); +echo $url->generate('second'); +echo $url->generate('third', ['id' => '42']); +``` + +### Optional parts + +You should wrap optional pattern parts with `[` and `]`. For example, +`/posts[/{id}]` pattern would match both `http://example.com/posts` and +`http://example.com/posts/42`. Router would fill `id` argument of +`CurrentRoute` service in the second case only. In this case, you could +specify the default value: + +```php +use \Yiisoft\Router\Route; + +Route::get('/posts[/{id}]')->defaults(['id' => '1']); +``` + +Optional parts are only supported in a trailing position, not in the middle +of a route. diff --git a/src/pt-BR/guide/runtime/sessions.md b/src/pt-BR/guide/runtime/sessions.md new file mode 100644 index 00000000..46c4a053 --- /dev/null +++ b/src/pt-BR/guide/runtime/sessions.md @@ -0,0 +1,161 @@ +# Sessions + +Sessions persist data between requests without passing them to the client +and back. Yii has [a session package](https://github.com/yiisoft/session) +to work with session data. + +To add it to your application, use composer: + +```shell +composer require yiisoft/session +``` + +## Configuring middleware + +To keep a session between requests, you need to add `SessionMiddleware` to +your route group or application middlewares. You should prefer a route +group when you have both API with token-based authentication and regular web +routes in the same application. Having it this way avoids starting the +session for API endpoints. + +To add a session for a certain group of routes, edit `config/routes.php` +like the following: + +```php +middleware(SessionMiddleware::class) + ->routes( + // ... + ) +]; +``` + +To add a session to the whole application, edit `config/application.php` +like the following: + +```php +return [ + Yiisoft\Yii\Web\Application::class => [ + '__construct()' => [ + 'dispatcher' => DynamicReference::to(static function (Injector $injector) { + return ($injector->make(MiddlewareDispatcher::class)) + ->withMiddlewares( + [ + Router::class, + CsrfTokenMiddleware::class, + SessionMiddleware::class, // <-- add this + ErrorCatcher::class, + ] + ); + }), + ], + ], +]; +``` + +## Opening and closing session + +```php +public function actionProfile(\Yiisoft\Session\SessionInterface $session) +{ + // start a session if it's not yet started + $session->open(); + + // work with session + + // write session values and then close it + $session->close(); +} +``` + +> [!NOTE] +> Closing session as early as possible is a good practice since many session implementations are blocking other +> requests while the session is open. + +There are two more ways to close a session: + +```php +public function actionProfile(\Yiisoft\Session\SessionInterface $session) +{ + // discard changes and close the session + $session->discard(); + + // destroy the session completely + $session->destroy(); +} +``` + +## Working with session data + +Usually you will use the following methods to work with session data: + +```php +public function actionProfile(\Yiisoft\Session\SessionInterface $session) +{ + // get a value + $lastAccessTime = $session->get('lastAccessTime'); + + // get all values + $sessionData = $session->all(); + + // set a value + $session->set('lastAccessTime', time()); + + // check if the value exists + if ($session->has('lastAccessTime')) { + // ... + } + + // remove value + $session->remove('lastAccessTime'); + + // get value and then remove it + $sessionData = $session->pull('lastAccessTime'); + + // clear session data from runtime + $session->clear(); +} +``` + +## Flash messages + +In case you need some data to remain in session until read, such as in case +of displaying a message on the next page, "flash" messages are what you +need. A flash message is a special type of data that's available only in +the current request and the next request. After that, it will be deleted +automatically. + +`FlashInteface` usage is the following: + +```php +/** @var Yiisoft\Session\Flash\FlashInterface $flash */ + +// request 1 +$flash->set('warning', 'Oh no, not again.'); + +// request 2 +$warning = $flash->get('warning'); +if ($warning !== null) { + // do something with it +} +``` + +## Custom session storage + +When using `Yiisoft\Session\Session`, you can use your own storage +implementation: + +```php +$handler = new MySessionHandler(); +$session = new \Yiisoft\Session\Session([], $handler); +``` + +Custom storage must implement `\SessionHandlerInterface`. diff --git a/src/pt-BR/guide/security/authentication.md b/src/pt-BR/guide/security/authentication.md new file mode 100644 index 00000000..e2a7bfb0 --- /dev/null +++ b/src/pt-BR/guide/security/authentication.md @@ -0,0 +1,258 @@ +# Authentication + +Authentication is the process of verifying the identity of a user. It +usually uses an identifier (for example, a username or an email address) and +a secret token (such as a password or an access token) to judge if the user +is the one whom he claims as. Authentication is the basis of the login +feature. + +Yii provides an authentication framework which wires up various components +to support login. To use this framework, you mainly need to do the following +work: + +* Configure the `Yiisoft\User\CurrentUser` service; +* Create a class implementing the `\Yiisoft\Auth\IdentityInterface` + interface; +* Create a class implementing the + `\Yiisoft\Auth\IdentityRepositoryInterface` interface; + +To use the `Yiisoft\User\CurrentUser` service, install +[yiisoft/user](https://github.com/yiisoft/user) package: + +```shell +composer require yiisoft/user +``` + +## Configuring `Yiisoft\User\CurrentUser` + +The `Yiisoft\User\CurrentUser` application service manages the user +authentication status. It depends on +`Yiisoft\Auth\IdentityRepositoryInterface` that should return an instance of +`\Yiisoft\Auth\IdentityInterface` which has the actual authentication logic. + +```php +use Yiisoft\Session\Session; +use Yiisoft\Session\SessionInterface; +use Yiisoft\Auth\IdentityRepositoryInterface; +use Yiisoft\Definitions\Reference; + +return [ + // ... + + SessionInterface::class => [ + 'class' => Session::class, + '__construct()' => [ + $params['session']['options'] ?? [], + $params['session']['handler'] ?? null, + ], + ], + IdentityRepositoryInterface::class => IdentityRepository::class, + CurrentUser::class => [ + 'withSession()' => [Reference::to(SessionInterface::class)] + ], +]; +``` + +## Implementing`\Yiisoft\Auth\IdentityInterface` + +The identity class must implement the `\Yiisoft\Auth\IdentityInterface` +which has a single method: + +* [[yii\web\IdentityInterface::getId()|getId()]]: it returns the ID of the + user represented by this identity instance. + +In the following example, an identity class is implemented as a pure PHP +object. + +```php +id; + } +} +``` + +## Implementing`\Yiisoft\Auth\IdentityRepositoryInterface` + +The identity repository class must implement the +`\Yiisoft\Auth\IdentityRepositoryInterface` which has the following methods: + +* `findIdentity(string $id): ?IdentityInterface`: it looks for an instance + of the identity class using the specified ID. This method is used when you + need to keep the login status via session. +* `findIdentityByToken(string $token, string $type): ?IdentityInterface`: it + looks for an instance of the identity class using the specified access + token. This method is used when you need to authenticate a user by a + single secret token (for example, in a stateless REST API). + +A dummy implementation may look like the following: + +```php +namespace App\User; + +use App\User\Identity; +use \Yiisoft\Auth\IdentityInterface; +use \Yiisoft\Auth\IdentityRepositoryInterface; + +final readonly class IdentityRepository implements IdentityRepositoryInterface +{ + private const USERS = [ + [ + 'id' => 1, + 'token' => '12345' + ], + [ + 'id' => 42, + 'token' => '54321' + ], + ]; + + public function findIdentity(string $id) : ?IdentityInterface + { + foreach (self::USERS as $user) { + if ((string)$user['id'] === $id) { + return new Identity($id); + } + } + + return null; + } + + public function findIdentityByToken(string $token, string $type) : ?IdentityInterface + { + foreach (self::USERS as $user) { + if ($user['token'] === $token) { + return new Identity((string)$user['id']); + } + } + + return null; + } +} +``` + +## Using `Yiisoft\User\CurrentUser` + +You can use `Yiisoft\User\CurrentUser` service to get current user +identity. As any service, it could be auto-wired in either action handler +constructor or method: + +```php +use Psr\Http\Message\ServerRequestInterface; +use Yiisoft\User\CurrentUser; + +final readonly class SiteController +{ + public function __construct(private CurrentUser $user) {} + + public function index(ServerRequestInterface $request): ResponseInterface + { + if ($this->user->isGuest()) { + // user is guest + } else { + $identity = $this->user->getIdentity(); + // do something based on identity + } + } +} +``` + +`isGuest()` determines if user is logged in or not. `getIdentity()` returns +an instance of identity. + +To log in a user, you may use the following code: + +```php +$identity = $identityRepository->findByEmail($email); + +/* @var $user \Yiisoft\User\CurrentUser */ +$user->login($identity); +``` + +The `login()` method sets the identity to the User service. It stores +identity into session so user authentication status is maintained. + +To log out a user, call + +```php +/* @var $user \Yiisoft\User\CurrentUser */ +$user->logout(); +``` + +## Protecting Routes + +The `Yiisoft\Auth\Middleware\Authentication` middleware can be used to +restrict access to a given route to authenticated users only. + +First, configure the `Yiisoft\Auth\AuthenticationMethodInterface`: + +```php +use Yiisoft\Auth\AuthenticationMethodInterface; +use Yiisoft\User\Method\WebAuth; + +return [ + // ... + AuthenticationMethodInterface::class => WebAuth::class, +]; +``` + +Then, apply the `Yiisoft\Auth\Middleware\Authentication` middleware to a +route: + +```php +use Yiisoft\Auth\Middleware\Authentication; + +Route::post('/create') + ->middleware(Authentication::class) + ->action([SiteController::class, 'create']) + ->name('site/create') +``` + + Or to a group of routes: + +```php +use Yiisoft\Auth\Middleware\Authentication; + +Group::create() + ->middleware(Authentication::class) + ->routes( + Route::post('/create') + ->action([SiteController::class, 'create']) + ->name('site/create'), + Route::put('/update/{id}') + ->action([SiteController::class, 'update']) + ->name('site/update') + ) +``` + +## Authentication Events + +The user service raises a few events during the login and logout processes. + + +* `\Yiisoft\User\Event\BeforeLogin`: raised at the beginning of `login()`. + If the event handler calls `invalidate()` on an event object, the login + process will be cancelled. +* `\Yiisoft\User\Event\AfterLogin`: raised after a successful login. +* `\Yiisoft\User\Event\BeforeLogout`: raised at the beginning of + `logout()`. If the event handler calls `invalidate()` on an event object, + the logout process will be cancelled. +* `\Yiisoft\User\Event\AfterLogout`: raised after a successful logout. + +You may respond to these events to implement features such as login audit, +online user statistics. For example, in the handler for +`\Yiisoft\User\Event\AfterLogin`, you may record the login time and IP +address in the `user` database table. diff --git a/src/pt-BR/guide/security/authorization.md b/src/pt-BR/guide/security/authorization.md new file mode 100644 index 00000000..f68d8560 --- /dev/null +++ b/src/pt-BR/guide/security/authorization.md @@ -0,0 +1,608 @@ +# Authorization + +Authorization is the process of verifying that a user has enough permission +to do something. + +## Checking for permission + +You can check if a user has certain permissions by using +`\Yiisoft\User\CurrentUser` service: + +```php +namespace App\Blog\Post; + +use Yiisoft\User\CurrentUser; +use Yiisoft\Router\HydratorAttribute\RouteArgument; +use Psr\Http\Message\ResponseInterface; + +final readonly class PostController +{ + public function __construct( + private PostRepositoryInterface $postRepository, + private CurrentUser $user + ) + { + } + + public function update(#[RouteArgument('id')] int $id): ResponseInterface + { + $post = $this->postRepository->findByPK($id); + if ($post === null) { + // respond with 404 + } + + if (!$this->canCurrentUserUpdatePost($post)) { + // respond with 403 + } + + // continue with updating the post + } + + private function canCurrentUserUpdatePost(Post $post): bool + { + return $post->getAuthorId() === $this->user->getId() && + $this->user->can('updatePost'); + } +} +``` + +Behind the scenes, `Yiisoft\User\CurrentUser::can()` method calls +`Yiisoft\Access\AccessCheckerInterface::userHasPermission()` so you should +provide an implementation in dependency container in order for it to work. + +## Role-based access control (RBAC) + +Role-Based Access Control (RBAC) provides a simple yet powerful centralized +access control. Please refer to the +[Wikipedia](https://en.wikipedia.org/wiki/Role-based_access_control) for +details about comparing RBAC with other more traditional access control +schemes. + +Yii implements a General Hierarchical RBAC, following the [NIST RBAC +model](https://csrc.nist.gov/CSRC/media/Publications/conference-paper/2000/07/26/the-nist-model-for-role-based-access-control-towards-a-unified-/documents/sandhu-ferraiolo-kuhn-00.pdf). + +Using RBAC involves two parts of work. The first part is to build up the +RBAC authorization data, and the second part is to use the authorization +data to perform access check in places where it's necessary. Since RBAC +implements `\Yiisoft\Access\AccessCheckerInterface`, using it's similar to +using any other implementation of an access checker. + +To ease description next, there are some basic RBAC concepts first. + +### Basic concepts + +A role represents a collection of *permissions* (for example, creating +posts, updating posts). You may assign a role to one or many users. To +check if a user has a specified permission, you may check if the user has a +role with that permission. + +Associated with each role or permission, there may be a *rule*. A rule +represents a piece of code that an access checker will execute to decide if +the corresponding role or permission applies to the current user. For +example, the "update post" permission may have a rule that checks if the +current user is the post creator. During access checking, if the user is +NOT the post creator, there's no "update post" permission. + +Both roles and permissions are in a hierarchy. In particular, a role may +consist of other roles or permissions. And a permission may consist of +other permissions. Yii implements a *partial order* hierarchy which +includes the more special *tree* hierarchy. While a role can contain a +permission, it isn't `true` vice versa. + +### Configuring RBAC + +Yii RBAC requires storage to be provided. + +One of the following storages could be installed: + +- [PHP storage](https://github.com/yiisoft/rbac-php) - PHP file storage; +- [DB storage](https://github.com/yiisoft/rbac-db) - database storage based + on [Yii DB](https://github.com/yiisoft/db); +- [Cycle DB storage](https://github.com/yiisoft/rbac-cycle-db) - database + storage based on [Cycle DBAL](https://github.com/cycle/database). + +You can also provide your own storage using the +[yiisoft/rbac](https://github.com/yiisoft/rbac) package. + +#### Configuring RBAC with the [PHP storage](https://github.com/yiisoft/rbac-php) + +Install [yiisoft/rbac-php](https://github.com/yiisoft/rbac-php) package: + +``` +composer require yiisoft/rbac-php +``` + +Before we set off to define authorization data and perform access checking, +you need to configure the `Yiisoft\Access\AccessCheckerInterface` in +dependency container: + +```php +use Yiisoft\Rbac\ItemsStorageInterface; +use Yiisoft\Rbac\AssignmentsStorageInterface; +use Yiisoft\Rbac\ManagerInterface; +use Yiisoft\Rbac\Php\ItemsStorage; +use Yiisoft\Rbac\Php\AssignmentsStorage; +use Yiisoft\Access\AccessCheckerInterface; +use Yiisoft\User\CurrentUser; + +return [ + // ... + ItemsStorageInterface::class => [ + 'class' => ItemsStorage::class, + '__construct()' => [ + 'filePath' => $params['rbacItemsStorageFilePath'] + ] + ], + AssignmentsStorageInterface::class => [ + 'class' => AssignmentsStorage::class, + '__construct()' => [ + 'filePath' => $params['rbacAssignmentsStorageFilePath'] + ] + ], + AccessCheckerInterface::class => ManagerInterface::class, + + CurrentUser::class => [ + 'withAccessChecker()' => [Reference::to(AccessCheckerInterface::class)] + ], +]; +``` + +`Yiisoft\Rbac\Manager` uses PHP script files to store authorization data. +Make sure the directory and all the files in it are writable by the Web +server process if you want to change permission hierarchy online. + +#### Configuring RBAC with the [DB storage](https://github.com/yiisoft/rbac-db) + +Install [yiisoft/rbac-db](https://github.com/yiisoft/rbac-db) package: + +``` +composer require yiisoft/rbac-db +``` + +Install one of the following drivers: + - [SQLite](https://github.com/yiisoft/db-sqlite) (minimal required version is 3.8.3) + - [MySQL](https://github.com/yiisoft/db-mysql) + - [PostgreSQL](https://github.com/yiisoft/db-pgsql) + - [Microsoft SQL Server](https://github.com/yiisoft/db-mssql) + - [Oracle](https://github.com/yiisoft/db-oracle) + +[Configure +connection](https://yiisoft.github.io/docs/guide/start/databases.html#configuring-connection). + +Before we set off to define authorization data and perform access checking, +you need to configure the `Yiisoft\Access\AccessCheckerInterface` in +dependency container: + +```php +use Yiisoft\Rbac\ItemsStorageInterface; +use Yiisoft\Rbac\AssignmentsStorageInterface; +use Yiisoft\Rbac\ManagerInterface; +use Yiisoft\Rbac\Db\ItemsStorage; +use Yiisoft\Rbac\Db\AssignmentsStorage; +use Yiisoft\Access\AccessCheckerInterface; + +return [ + // ... + ItemsStorageInterface::class => ItemsStorage::class, + AssignmentsStorageInterface::class => AssignmentsStorage::class, + AccessCheckerInterface::class => ManagerInterface::class, +]; +``` + +Add the RBAC [DB storage](https://github.com/yiisoft/rbac-db) migration +paths to params.php: + +```php +return [ + // ... + 'yiisoft/db-migration' => [ + 'sourcePaths' => [ + __DIR__ . '/../../vendor/yiisoft/rbac-db/migrations/items', + __DIR__ . '/../../vendor/yiisoft/rbac-db/migrations/assignments', + ], + ], +]; +``` + +Apply migrations: + +``` +./yii migrate:up +``` + +### Building authorization data + +Building authorization data is all about the following tasks: + +- defining roles and permissions; +- establishing relations between roles and permissions; +- defining rules; +- associating rules with roles and permissions; +- assigning roles to users. + +Depending on authorization flexibility requirements, you can do the tasks in +different ways. If only developers change your permission hierarchy, you +can use either migrations or a console command. Migration advantage is that +you could execute it along with other migrations. The Console command +advantage is that you have a good overview of the hierarchy in the code +without a need to read many migrations. + +Either way, in the end, you'll get the following RBAC hierarchy: + +![Simple RBAC hierarchy](/images/guide/security/rbac-hierarchy-1.svg "Simple +RBAC hierarchy") + +In case you want to build permission hierarchy dynamically, you need a UI or +a console command. The API used to build the hierarchy itself won't be +different. + +### Using console command + +If your permission hierarchy doesn't change at all, and you have a fixed +number of users, you can create a [console +command](../tutorial/console-applications.md) that will initialize +authorization data once via APIs offered by +`\Yiisoft\Rbac\ManagerInterface`: + +```php +removeAll(); + + $this->manager->addPermission((new Permission(RbacCommand::CREATE_POST_PERMISSION))->withDescription('Create a post')); + $this->manager->addPermission((new Permission(RbacCommand::UPDATE_POST_PERMISSION))->withDescription('Update post')); + + // add the "author" role and give this role the "createPost" permission + $this->manager->addRole(new Role(RbacCommand::ROLE_AUTHOR)); + $this->manager->addChild(RbacCommand::ROLE_AUTHOR, RbacCommand::CREATE_POST_PERMISSION); + + // add the "admin" role and give this role the "updatePost" permission + // as well as the permissions of the "author" role + $this->manager->addRole(new Role(RbacCommand::ROLE_ADMIN)); + $this->manager->addChild(RbacCommand::ROLE_ADMIN, RbacCommand::UPDATE_POST_PERMISSION); + $this->manager->addChild(RbacCommand::ROLE_ADMIN, RbacCommand::ROLE_AUTHOR); + + // Assign roles to users. 1 and 2 are IDs returned by IdentityInterface::getId() + // usually implemented in your User model. + $this->manager->assign(RbacCommand::ROLE_AUTHOR, 2); + $this->manager->assign(RbacCommand::ROLE_ADMIN, 1); + + return ExitCode::OK; + } + + private function removeAll(): void + { + $this->manager->revokeAll(2); + $this->manager->revokeAll(1); + + $this->manager->removeRole(RbacCommand::ROLE_ADMIN); + $this->manager->removeRole(RbacCommand::ROLE_AUTHOR); + + $this->manager->removePermission(RbacCommand::CREATE_POST_PERMISSION); + $this->manager->removePermission(RbacCommand::UPDATE_POST_PERMISSION); + } +} +``` + +Add the command to `config/console/commands.php`: + +```php +return [ + // ... + 'rbac:init' => App\Command\RbacCommand::class +]; +``` + +You can execute the command above from the console the following way: + +``` +./yii rbac:init +``` + +> If you don't want to hardcode what users have certain roles, don't put `->assign()` calls into the command. Instead, + create either UI or console command to manage assignments. + +#### Using migrations + +**TODO**: finish it when migrations are implemented. + +You can use [migrations](../databases/db-migrations.md) to initialize and +change hierarchy via APIs offered by `\Yiisoft\Rbac\ManagerInterface`. + +Create new migration using `./yii migrate:create init_rbac` then implement +creating a hierarchy: + +```php +manager->addPermission((new Permission(M260112125812InitRbac::CREATE_POST_PERMISSION))->withDescription('Create a post')); + $this->manager->addPermission((new Permission(M260112125812InitRbac::UPDATE_POST_PERMISSION))->withDescription('Update post')); + + // add the "author" role and give this role the "createPost" permission + $this->manager->addRole(new Role(M260112125812InitRbac::ROLE_AUTHOR)); + $this->manager->addChild(M260112125812InitRbac::ROLE_AUTHOR, M260112125812InitRbac::CREATE_POST_PERMISSION); + + // add the "admin" role and give this role the "updatePost" permission + // as well as the permissions of the "author" role + $this->manager->addRole(new Role(M260112125812InitRbac::ROLE_ADMIN)); + $this->manager->addChild(M260112125812InitRbac::ROLE_ADMIN, M260112125812InitRbac::UPDATE_POST_PERMISSION); + $this->manager->addChild(M260112125812InitRbac::ROLE_ADMIN, M260112125812InitRbac::ROLE_AUTHOR); + + // Assign roles to users. 1 and 2 are IDs returned by IdentityInterface::getId() + // usually implemented in your User model. + $this->manager->assign(M260112125812InitRbac::ROLE_AUTHOR, 2); + $this->manager->assign(M260112125812InitRbac::ROLE_ADMIN, 1); + } + + public function down(MigrationBuilder $b): void + { + $this->manager->revokeAll(2); + $this->manager->revokeAll(1); + + $this->manager->removeRole(M260112125812InitRbac::ROLE_ADMIN); + $this->manager->removeRole(M260112125812InitRbac::ROLE_AUTHOR); + + $this->manager->removePermission(M260112125812InitRbac::CREATE_POST_PERMISSION); + $this->manager->removePermission(M260112125812InitRbac::UPDATE_POST_PERMISSION); + } +} +``` + +> If you don't want to hardcode which users have certain roles, don't put `->assign()` calls in migrations. Instead, + create either UI or console command to manage assignments. + +You could apply migration by using `./yii migrate:up`. + +## Assigning roles to users + +TODO: update when signup implemented in demo / template. + +The author can create a post, admin can update the post and do everything +the author can. + +If your application allows user signup, you need to assign roles to these +new users at once. For example, in order for all signed-up users to become +authors in your advanced project template, you need to change +`frontend\models\SignupForm::signup()` as follows: + +```php +public function signup() +{ + if ($this->validate()) { + $user = new User(); + $user->username = $this->username; + $user->email = $this->email; + $user->setPassword($this->password); + $user->generateAuthKey(); + $user->save(false); + + // the following three lines were added: + $authorRole = $this->manager->getRole('author'); + if ($authorRole !== null) { + $this->manager->assign($authorRole->getName(), $user->getId()); + } + + return $user; + } + + return null; +} +``` + +For applications that require complex access control with dynamically +updated authorization data (such as an admin panel), you many need to +develop special user interfaces using APIs offered by +`Yiisoft\Rbac\Manager`. + + +### Using rules + +As aforementioned, rules add extra constraint to roles and permissions. A +rule is a class extending from `\Yiisoft\Rbac\Rule`. It must implement the +`execute()` method. In the hierarchy you've created before, the author +can't edit his own post. Let's fix it. First, you need a rule to verify +that the user is the post author: + +```php +namespace App\User\Rbac; + +use Yiisoft\Rbac\Item; +use Yiisoft\Rbac\RuleContext; +use Yiisoft\Rbac\RuleInterface; + +/** + * Checks if the authorID matches user passed via params. + */ +final readonly class AuthorRule implements RuleInterface +{ + public function execute(?string $userId, Item $item, RuleContext $context): bool + { + $post = $context->getParameterValue('post'); + return $post !== null && $post->getAuthorId() == $userId; + } +} +``` + +The rule checks if user created the `post`. Create a special permission +`updateOwnPost` in the command you've used before: + +```php +use Yiisoft\Rbac\Permission; +use Yiisoft\Rbac\ManagerInterface; + +// add the "updateOwnPost" permission and associate the rule with it. +$updateOwnPost = (new Permission('updateOwnPost')) + ->withDescription('Update own post') + ->withRuleName(AuthorRule::class); +$this->manager->addPermission($updateOwnPost); + +// "updateOwnPost" will be used from "updatePost" +$this->manager->addChild($updateOwnPost->getName(), $updatePost->getName()); + +// allow "author" to update their own posts +$this->manager->addChild($authorRole->getName(), $updateOwnPost->getName()); + +// Remove this line since we don't want the AuthorRule to be applied to the 'admin' role +$this->manager->addChild('admin', 'author'); +``` + +Now you've got the following hierarchy: + +![RBAC hierarchy with a rule](/images/guide/security/rbac-hierarchy-2.svg +"RBAC hierarchy with a rule") + + +### Access check + +The check is done similarly to how it was done in the first section of this +guide: + +```php +namespace App\Blog\Post; + +use Yiisoft\User\CurrentUser; +use Yiisoft\Router\HydratorAttribute\RouteArgument; +use Psr\Http\Message\ResponseInterface; + +final readonly class PostController +{ + public function __construct( + private PostRepositoryInterface $postRepository, + private CurrentUser $user + ) + { + } + + public function update(#[RouteArgument('id')] int $id): ResponseInterface + { + $post = $this->postRepository->findByPK($id); + if ($post === null) { + // respond with 404 + } + + if (!$this->canCurrentUserUpdatePost($post)) { + // respond with 403 + } + + // continue with updating the post + } + + private function canCurrentUserUpdatePost(Post $post): bool + { + return $this->user->can('updatePost', ['post' => $post]); + } +} +``` + +The difference is that now checking for a user's own post is part of the +RBAC. + +If the current user is Jane with `ID=1` you are starting at `createPost` and +trying to get to `Jane`: + +![Access check](/images/guide/security/rbac-access-check-1.svg "Access +check") + +To check if a user can update a post, you need to pass an extra parameter +that's required by `AuthorRule` described before: + +```php +if ($user->can('updatePost', ['post' => $post])) { + // update post +} +``` + +Here is what happens if the current user is John: + + +![Access check](/images/guide/security/rbac-access-check-2.svg "Access +check") + +You're starting with the `updatePost` and going through `updateOwnPost`. To pass the access check, `AuthorRule` +should return `true` from its `execute()` method. The method receives its `$params` from the `can()` method call, so the value is +`['post' => $post]`. +If everything is fine, you will get to `author` assigned to John. + +In the case of Jane, it's a bit simpler since she is an admin: + +![Access check](/images/guide/security/rbac-access-check-3.svg "Access +check") + +## Implementing your own access checker + +If RBAC doesn't suit your needs, you can implement your own access checker +without changing the application code: + + +```php +namespace App\User; + +use \Yiisoft\Access\AccessCheckerInterface; + +final readonly class AccessChecker implements AccessCheckerInterface +{ + private const PERMISSIONS = [ + [ + 1 => ['editPost'], + 42 => ['editPost', 'deletePost'], + ], + ]; + + public function userHasPermission($userId, string $permissionName, array $parameters = []) : bool + { + if (!array_key_exists($userId, self::PERMISSIONS)) { + return false; + } + + return in_array($permissionName, self::PERMISSIONS[$userId], true); + } +} +``` diff --git a/src/pt-BR/guide/security/best-practices.md b/src/pt-BR/guide/security/best-practices.md new file mode 100644 index 00000000..32ae9410 --- /dev/null +++ b/src/pt-BR/guide/security/best-practices.md @@ -0,0 +1,282 @@ +# Security best practices + +Below, we'll review common security principles and describe how to avoid +threats when developing applications using Yii. Most of these principles +aren't unique to Yii alone but apply to website or software development in +general, so you will also find links for further reading on the general +ideas behind these. + + +## Basic principles + +There are two main principles when it comes to security no matter which +application is being developed: + +1. Filter input. +2. Escape output. + + +### Filter input + +Filter input means that you should never consider input safe, and you should +always check if the value you've got is actually among allowed ones. For +example, if you know that you sort by three fields `title`, `created_at` and +`status` and the field came from user input, it's better to check the value +you've got right where you're receiving it. In terms of basic PHP, that +would look like the following: + +```php +$sortBy = $_GET['sort']; +if (!in_array($sortBy, ['title', 'created_at', 'status'])) { + throw new \InvalidArgumentException('Invalid sort value.'); +} +``` + +In Yii, most probably you'll use form validation to do similar checks. + +Further reading on the topic: + +- +- + + +### Escape output + +Escape output means that, depending on the context where you're using data, +you should prepend it with special characters to negate its special meaning. +In context of HTML you should escape `<`, `>` and alike special characters. +In the context of JavaScript or SQL, it will be a different set of characters. +Since it's error-prone to escape manually, Yii provides various tools to perform escaping in different contexts. + +Further reading on the topic: + +- +- +- + + +## Avoiding SQL injections + +SQL injection happens when you form a query text by concatenating unescaped +strings such as the following: + +```php +$username = $_GET['username']; +$sql = "SELECT * FROM user WHERE username = '$username'"; +``` + +Instead of supplying correct username attacker could give your applications +something like `'; DROP TABLE user; --`. The Resulting SQL will be the +following: + +```sql +SELECT * FROM user WHERE username = ''; DROP TABLE user; --' +``` + +This is a valid query that will search for users with empty username and +then will drop `user` table most probably resulting in a broken website and +data loss (you've set up regular backups, right?). + +Make sure to either use PDO prepared statements directly or ensure that the +library you prefer is doing it. In the case of prepared statements, it's +impossible to manipulate the query as was demonstrated above. + +If you use data to specify column names or table names, the best thing to do +is to allow only a predefined set of values: + +```php +function actionList($orderBy = null) +{ + if (!in_array($orderBy, ['name', 'status'])) { + throw new \InvalidArgumentException('Only name and status are allowed to order by.'); + } + + // ... +} +``` + +Further reading on the topic: + +- + + +## Avoiding XSS + +XSS or cross-site scripting happens when output isn't escaped properly when outputting HTML to the browser. For example, +if user can enter his name and instead of `Alexander` he enters ``, every page that +outputs username without escaping it will execute JavaScript `alert('Hello!');` resulting in alert box popping up +in a browser. Depending on the website instead of innocent alert, such a script could send messages using your name or even +perform bank transactions. + +Avoiding XSS is quite easy in Yii. There are two cases: + +1. You want to output data as plain text. +2. You want to output data as HTML. + +If all you need is plain text, then escaping is as easy as the following: + + +```php + +``` + +If it should be HTML, you could get some help from +[HtmlPurifier](http://htmlpurifier.org/). Note that HtmlPurifier processing +is quite heavy, so consider adding caching. + +Further reading on the topic: + +- + + +## Avoiding CSRF + +CSRF is an abbreviation for cross-site request forgery. The idea is that +many applications assume that requests coming from a user browser are made +by the user themselves. This assumption could be false. + +For example, the website `an.example.com` has a `/logout` URL that, when accessed using a simple GET request, logs the user out. As long +as it's requested by the user themselves everything is OK, but one day bad guys are somehow posting +`` on a forum the user often visits. The browser doesn't make any difference between +requesting an image or requesting a page so when the user opens a page with such a manipulated `` tag, +the browser will send the GET request to that URL and the user will be logged out from `an.example.com`. + +That's the basic idea of how a CSRF attack works. One can say that logging out a user isn't a serious thing. +However, this was just an example. +There are many more things one could do using this approach. +For example, triggering payments or changing data. Imagine that some website has a URL +`http://an.example.com/purse/transfer?to=anotherUser&amount=2000`. Accessing it using GET request, causes transfer of $2000 +from an authorized user account to user `anotherUser`. +You know that the browser will always send a GET request to load an image, +so you can change the code to accept only POST requests on that URL. +Unfortunately, this won't save you, because an attacker +can put some JavaScript code instead of `` tag, which allows sending POST requests to that URL as well. + +For this reason, Yii applies extra mechanisms to protect against CSRF +attacks. + +To avoid CSRF, you should always: + +1. Follow HTTP specification. GET shouldn't change the application state. + See [RFC2616](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html) for + more details. +2. Keep Yii CSRF protection enabled. + +Yii has CSRF protection via `Yiisoft\Csrf\CsrfTokenMiddleware` from the +[`yiisoft/csrf`](https://github.com/yiisoft/csrf) package. Make sure it's +in your application middleware stack. For AJAX/SPA backends that use +cookie-based authentication, the same package provides +`Yiisoft\Csrf\CsrfHeaderMiddleware` — an alternative approach that relies on +custom request headers and the CORS preflight mechanism instead of +token-in-form. + +Further reading on the topic: + +- +- + + +## Avoiding file exposure + +By default, server webroot is meant to be pointed to `public` directory where `index.php` is. In the case of shared hosting + environments, it could be impossible to achieve, so you'll end up with all the code, configs and logs in server webroot. + +If so, remember to deny access to everything except `web`. If it's +impossible, consider hosting your application elsewhere. + + +## Avoiding debug info and tools in production + +In debug mode, Yii shows quite verbose errors which are certainly helpful +for development. The thing is that these verbose errors are handy for +attacker as well since these could reveal database structure, configuration +values and parts of your code. + +Never run production applications with debugger or Gii accessible to +everyone. One could use it to get information about database structure, +code and to simply rewrite code with what's generated by Gii. + +You should avoid the debug toolbar in production unless necessary. It +exposes all the application and config details possible. If you absolutely +need it, check twice you restrict access to your IP only. + +Further reading on the topic: + +- +- + + +## Using secure connection over TLS + +Yii provides features that rely on cookies and/or PHP sessions. These can be +vulnerable in case your connection is compromised. The risk is reduced if +the app uses secure connection via TLS (often referred to as +[SSL](https://en.wikipedia.org/wiki/Transport_Layer_Security)). + +Nowadays, anyone can get a certificate for free and automatically update it +thanks to [Let's Encrypt](https://letsencrypt.org/). + +## Secure server configuration + +The purpose of this section is to highlight risks that need to be considered +when creating a server configuration for serving a Yii-based +website. Besides the points covered here, there may be other +security-related configuration options to be considered, so don't consider +this section to be complete. + +### Avoiding `Host`-header attacks + +If the webserver is configured to serve the same site independent of the +value of the `Host` header, this information mayn't be reliable and [may be +faked by the user sending the HTTP +request](https://www.acunetix.com/vulnerabilities/web/host-header-attack). +In such situations, you should fix your webserver configuration to serve the +site only for specified host names. + +For more information about the server configuration, please refer to the +documentation of your webserver: + +- Apache 2: + +- Nginx: + + +### Configuring SSL peer validation + +There is a typical misconception about how to solve SSL certificate +validation issues such as: + +``` +cURL error 60: SSL certificate problem: unable to get local issuer certificate +``` + +or + +``` +stream_socket_enable_crypto(): SSL operation failed with code 1. OpenSSL Error messages: error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed +``` + +Many sources wrongly suggest disabling SSL peer verification. That +shouldn't be ever done since it enables man-in-the middle type of attacks. +Instead, PHP should be configured properly: + +1. Download + [https://curl.haxx.se/ca/cacert.pem](https://curl.haxx.se/ca/cacert.pem). +2. Add the following to your php.ini: + ``` + openssl.cafile="/path/to/cacert.pem" + curl.cainfo="/path/to/cacert.pem". + ``` + +Note that you should keep the file up to date. + +## References + +- [OWASP top 10](https://owasp.org/Top10/) +- [The Basics of Web Application + Security](https://martinfowler.com/articles/web-security-basics.html) by + Martin Fowler +- [PHP manual: security](https://www.php.net/manual/en/security.php) +- [Information security at + STackExchange](https://security.stackexchange.com/) + diff --git a/src/pt-BR/guide/security/cryptography.md b/src/pt-BR/guide/security/cryptography.md new file mode 100644 index 00000000..4b596bab --- /dev/null +++ b/src/pt-BR/guide/security/cryptography.md @@ -0,0 +1,123 @@ +# Cryptography + +In this section, we'll review the following security aspects: + +- Generating random data +- Encryption and Decryption +- Confirming Data Integrity + +To use these features, you need to install `yiisoft/security` package: + +``` +composer install yiisoft/security +``` + +## Generating pseudorandom data + +Pseudorandom data are useful in many situations. For example, when resetting +a password via email, you need to generate a token, save it to the database, +and send it via email to the end user, which in turn will allow them to +prove ownership of that account. It's important that this token be unique +and hard to guess, else there is a possibility that an attacker can predict +the token's value and reset the user's password. + +`\Yiisoft\Security\Random` makes generating pseudorandom data simple: + +```php +$key = \Yiisoft\Security\Random::string(42); +``` + +The code above would give you a random string consisting of 42 characters. + +If you need bytes or integers, use PHP functions directly: + +- `random_bytes()` for bytes. Note that the output may not be ASCII. +- `random_int()` for integers. + +## Encryption and decryption + +Yii provides convenient helper functions to encrypt/decrypt data using a +secret key. The data is passed through the encryption function so that only +the person who has the secret key will be able to decrypt it. For example, +you need to store some information in your database, but you need to make +sure only the user who has the secret key can view it (even if one +compromises the application database): + +```php +$encryptedData = (new \Yiisoft\Security\Crypt())->encryptByPassword($data, $password); + +// save data to a database or another storage +saveData($encryptedData); +``` + +Decrypting it: + +```php +// collect encrypted data from a database or another storage +$encryptedData = getEncryptedData(); + +$data = (new \Yiisoft\Security\Crypt())->decryptByPassword($encryptedData, $password); +``` + +You could use a key instead of a password: + +```php +$encryptedData = (new \Yiisoft\Security\Crypt())->encryptByKey($data, $key); + +// save data to a database or another storage +saveData($encryptedData); +``` + +Decrypting it: + +```php +// collect encrypted data from a database or another storage +$encryptedData = getEncryptedData(); + +$data = (new \Yiisoft\Security\Crypt())->decryptByKey($encryptedData, $key); +``` + +## Confirming data integrity + +There are situations in which you need to verify that your data hasn't been +tampered with by a third party or even corrupted in some way. Yii provides a +way to confirm data integrity by MAC signing. + +The `$key` should be present at both sending and receiving sides. On the +sending side: + +```php +$signedMessage = (new \Yiisoft\Security\Mac())->sign($message, $key); + +sendMessage($signedMessage); +``` + +On the receiving side: + +```php +$signedMessage = receiveMessage($signedMessage); + +try { + $message = (new \Yiisoft\Security\Mac())->getMessage($signedMessage, $key); +} catch (\Yiisoft\Security\DataIsTamperedException $e) { + // data is tampered +} +``` + +## Masking token length + +Masking a token helps to mitigate a BREACH attack by randomizing how the +token outputted on each request. A random mask is applied to the token, +making the string always unique. + +To mask a token: + +```php +$maskedToken = \Yiisoft\Security\TokenMask::apply($token); +``` + +To get the original value from the masked one: + +```php +$token = \Yiisoft\Security\TokenMask::remove($maskedToken); +``` diff --git a/src/pt-BR/guide/security/overview.md b/src/pt-BR/guide/security/overview.md new file mode 100644 index 00000000..807b6468 --- /dev/null +++ b/src/pt-BR/guide/security/overview.md @@ -0,0 +1,19 @@ +# Segurança + +Good security is vital to the health and success of any +application. Unfortunately, many developers cut corners when it comes to +security, either due to a lack of understanding or because implementation is +too much of a hurdle. To make your Yii-powered application as secure as +possible, Yii has included several excellent and easy-to-use security +features. + +* [Authentication](authentication.md) +* [Authorization](authorization.md) +* [Working with Passwords](passwords.md) +* [Cryptography](cryptography.md) +* [Best Practices](best-practices.md) +* [Trusted request](trusted-request.md) + +See also: + +* [Views security](../views/view.md#security) diff --git a/src/pt-BR/guide/security/passwords.md b/src/pt-BR/guide/security/passwords.md new file mode 100644 index 00000000..2e112d77 --- /dev/null +++ b/src/pt-BR/guide/security/passwords.md @@ -0,0 +1,45 @@ +# Working with passwords + +Most developers know that passwords can't be stored in plain text, but many +developers believe it's still safe to hash passwords using `md5`, `sha1` or +`sha256` etc. There was a time when using the aforementioned hashing +algorithms was enough, but modern hardware makes it possible to reverse such +hashes and even stronger ones using brute force attacks. + +To offer increased security for user passwords, even in the worst case +scenario (when one breaches your application), you need to use a hashing +algorithm that's resilient against brute force attacks. The best current +choice is `argon2`. Yii `yiisoft/security` package make securely generate +and verify hashes easier and ensure the best possible hashing solution used. + +To use it, you need to require the package first: + +``` +composer require yiisoft/security +``` + +When a user provides a password for the first time (e.g., upon +registration), the password needs to be hashed and stored: + + +```php +$hash = (new PasswordHasher())->hash($password); + +// save hash to a database or another storage +saveHash($hash); +``` + +When a user attempts to log in, the submitted password must be verified +against the previously hashed and stored password: + + +```php +// get hash from a database or another storage +$hash = getHash(); + +if ((new PasswordHasher())->validate($password, $hash)) { + // all good, logging in user +} else { + // wrong password +} +``` diff --git a/src/pt-BR/guide/security/trusted-request.md b/src/pt-BR/guide/security/trusted-request.md new file mode 100644 index 00000000..29ff339a --- /dev/null +++ b/src/pt-BR/guide/security/trusted-request.md @@ -0,0 +1,43 @@ +# Trusted request + +Getting user information, like a host and IP address, will work out of the +box in a normal setup where a single webserver is used to serve the +website. If your Yii application, however, runs behind a reverse proxy, you +need to add configuration to retrieve this information as the direct client +is now the proxy, and the user IP address is passed to the Yii application +by a header set by the proxy. + +You shouldn't blindly trust headers provided by proxies unless you +explicitly trust the proxy. Yii supports configuring trusted proxies via +the `Yiisoft\Yii\Web\Middleware\TrustedHostsNetworkResolver`. You should +add it to [middleware stack](../structure/middleware.md). + +The following is a request config for an application that runs behind an +array of reverse proxies, which are located in the `10.0.2.0/24` IP network: + +```php +/** @var \Yiisoft\Yii\Web\Middleware\TrustedHostsNetworkResolver $trustedHostsNetworkResolver */ +$trustedHostsNetworkResolver = $trustedHostsNetworkResolver->withAddedTrustedHosts(['1.0.2.0/24']); +``` + +The proxy sends the IP in the `X-Forwarded-For` header by default, and the +protocol (`http` or `https`) is in `X-Forwarded-Proto`. + +In case your proxies are using different headers, you can use the request +configuration to adjust these, e.g.: + +```php +/** @var \Yiisoft\Yii\Web\Middleware\TrustedHostsNetworkResolver $trustedHostsNetworkResolver */ +$trustedHostsNetworkResolver = $trustedHostsNetworkResolver + ->withAddedTrustedHosts( + ['1.0.2.0/24'], + ['X-ProxyUser-Ip'], + ['Front-End-Https'], + [], + [], + ['X-Proxy-User-Ip'] + ); +``` + +With the above configuration, `X-ProxyUser-Ip` and `Front-End-Https` headers +are used to get user IP and protocol. diff --git a/src/pt-BR/guide/start/creating-project.md b/src/pt-BR/guide/start/creating-project.md new file mode 100644 index 00000000..21d3bf86 --- /dev/null +++ b/src/pt-BR/guide/start/creating-project.md @@ -0,0 +1,67 @@ +# Criando um projeto + +Neste guia mostramos os comandos tanto para o +[Docker](https://docs.docker.com/get-started/get-docker/) quanto para o +servidor de desenvolvimento embutido, com tudo instalado localmente. + +> [!NOTE] +> Se você quiser usar outro servidor web, +> veja ["Configurando servidores web"](../../cookbook/configuring-webservers/general.md). + +Recomendamos começar com um template de projeto, que é um projeto Yii mínimo +e funcional com alguns recursos básicos. Ele serve como um bom ponto de +partida para os seus projetos. + +Você pode criar um novo projeto a partir de um template usando o gerenciador +de pacotes [Composer](https://getcomposer.org): + +```sh +composer create-project yiisoft/app your_project +``` + +Quem usa Docker pode rodar os seguintes comandos: + +```sh +docker run --rm -it -v "$(pwd):/app" --user $(id -u):$(id -g) composer/composer create-project yiisoft/app your_project +sudo chown -R $(id -u):$(id -g) your_project +cd your_project +make composer update +``` + +Se você quiser a versão de desenvolvimento em vez da versão de release: + +```sh +git clone https://github.com/yiisoft/app.git --depth 1 your_project && \ +cd your_project && \ +rm -rf .git && \ +make composer update +``` + +Isso instala a versão estável mais recente do template de projeto do Yii em +um diretório chamado `your_project`. Você pode escolher outro nome de +diretório se quiser. + +> [!TIP] +> Se você quiser instalar a versão de desenvolvimento mais recente do Yii, pode adicionar `--stability=dev` ao comando. +> Não use a versão de desenvolvimento do Yii em produção, porque ela pode quebrar o seu código em execução. + +Entre no diretório recém-criado, copie `.env.example` para `.env` e rode: + +```sh +./yii serve --port=80 +``` + +Se você usa Docker, rode: + +```sh +make up +``` + +Abra no navegador a URL `http://localhost/`. + +> [!NOTE] +> Para mudar a porta do servidor embutido, passe `--port` para `./yii serve`. No Docker, defina `DEV_PORT` +> em `docker/.env`. + +![Instalação do Yii concluída com +sucesso](/images/guide/start/app-installed.png) diff --git a/src/pt-BR/guide/start/databases.md b/src/pt-BR/guide/start/databases.md new file mode 100644 index 00000000..667e11e4 --- /dev/null +++ b/src/pt-BR/guide/start/databases.md @@ -0,0 +1,905 @@ +# Trabalhando com bancos de dados + +Yii doesn't dictate using a particular database or storage for your +application. There are many ways you can work with relational databases: + +- [Yii DB](https://github.com/yiisoft/db) +- [Yii Active Record](https://github.com/yiisoft/active-record) +- [Cycle](https://github.com/cycle) via [Yii Cycle + package](https://github.com/yiisoft/yii-cycle) +- [Doctrine](https://www.doctrine-project.org/) via [Yii Doctrine + package](https://github.com/stargazer-team/yii-doctrine) +- [PDO](https://www.php.net/manual/en/book.pdo.php) + +For non-relational ones, there are usually official libraries available: + +- [ElasticSearch](https://github.com/elastic/elasticsearch-php) +- [Redis](https://redis.io/docs/latest/develop/clients/php/) +- ... + +## Choosing a data access approach + +Yii3 keeps database access in optional packages. A new application doesn't get a global `Yii::$app->db` component +or a built-in Active Record layer automatically, so choose the package and boundary that fit your application. + +If you used Yii 2.0 database access layer, `yiisoft/db` is the closest Yii3 equivalent. It provides database +connections, commands, schema support, and a query builder. Instead of calling `Yii::$app->db`, configure a +connection as a service and inject `ConnectionInterface` where the database is needed. + +If you used Yii 2.0 Active Record, you can install +`yiisoft/active-record`. It is useful when your model classes mostly +describe tables and relations. For applications where Yii 2.0 Active Record +classes also contain form validation, request scenarios, authorization +checks, or business workflows, move those responsibilities to form models, +services, and domain objects instead of putting them back into the record +class. + +For most application code, put a repository or query service between the +action/service layer and storage: + +- actions and application services depend on repository methods such as + `findOneBySlug()`, `findAll()`, `save()`, and `deleteBySlug()`; +- the repository hides whether persistence is implemented with `yiisoft/db`, + Active Record, Cycle, Doctrine, or another storage; +- the repository is the place to map raw database rows or records to typed + objects used by the rest of the code. + +Small CRUD applications can start with a concrete repository class. Larger +applications usually benefit from a repository interface in the domain or +module and an implementation in the infrastructure layer. + +In this guide, we will focus on working with relational databases using Yii +DB. We'll use PostgreSQL to implement a simple CRUD (create read update +delete). + +## Installing PostgreSQL + +You need to install PostgreSQL. If you prefer not to use Docker, [get the +installer from official website](https://www.postgresql.org/download/), +install it and create a database. + +If you use Docker, it is a bit simpler. Modify `docker/dev/compose.yml`: + +```yaml +services: + app: + build: + dockerfile: docker/Dockerfile + context: .. + target: dev + args: + USER_ID: ${UID} + GROUP_ID: ${GID} + env_file: + - path: ./dev/.env + - path: ./dev/override.env + required: false + ports: + - "${DEV_PORT:-80}:80" + volumes: + - ../:/app + - ../runtime:/app/runtime + - caddy_data:/data + - caddy_config:/config + tty: true + depends_on: + db: + condition: service_healthy + + db: + image: postgres:${POSTGRES_VERSION:-18}-alpine + environment: + POSTGRES_DB: app + POSTGRES_PASSWORD: password + POSTGRES_USER: user + POSTGRES_INITDB_ARGS: "--locale-provider=icu --icu-locale=und --encoding=UTF8" + volumes: + - ../runtime/db:/var/lib/postgresql:rw + ports: + - "${DEV_DB_PORT:-5432}:5432" + healthcheck: + test: [ "CMD-SHELL", "pg_isready -U user -d app" ] + interval: 5s + timeout: 5s + retries: 5 +``` + +Note that we add `depends_on` so application waits for database to be up. + +> [!IMPORTANT] +> Also, we'll need a `pdo_pgsql` extension to communicate with PostgreSQL. You can enable it locally in `php.ini`. + +If you use Docker, check `docker/Dockerfile` and add `pdo_pgsql` in +`install-php-extensions` list: + +```dockerfile +RUN install-php-extensions \ + opcache \ + mbstring \ + intl \ + dom \ + ctype \ + curl \ + phar \ + openssl \ + xml \ + xmlwriter \ + simplexml \ + pdo \ + pdo_pgsql +``` + +Then rebuild PHP image with + +```sh +make build && make down && make up +``` + +## Configuring connection + +Now that we have the database, it's time to define the connection. + +First we need a package to be installed: + +```sh +make composer require yiisoft/db-pgsql:2.* +``` + +Now create `config/common/di/db-pgsql.php`: + +```php + [ + 'class' => Connection::class, + '__construct()' => [ + 'driver' => new Driver( + $params['yiisoft/db-pgsql']['dsn'], + $params['yiisoft/db-pgsql']['username'], + $params['yiisoft/db-pgsql']['password'], + ), + ], + ], +]; +``` + +And define parameters in `config/common/params.php`. For Docker that would +be: + +```php +use Yiisoft\Db\Pgsql\Dsn; + +return [ + // ... + 'yiisoft/db-pgsql' => [ + 'dsn' => new Dsn('pgsql', 'db', 'app', '5432'), + 'username' => 'user', + 'password' => 'password', + ], +]; +``` + +`db` host is resolved automatically within the Docker network. + +For local installation without Docker the host in Dsn would be +`localhost`. You'll have to adjust the rest to match how you configured the +database. + +### Multiple database connections + +When the application works with several databases, keep +`ConnectionInterface` for the primary connection and add a class alias for +each named connection: + +```php + MainDatabase::class, + + MainDatabase::class => [ + 'class' => Connection::class, + '__construct()' => [ + 'driver' => new Driver( + $params['app/db']['main']['dsn'], + $params['app/db']['main']['username'], + $params['app/db']['main']['password'], + ), + ], + ], + + AnalyticsDatabase::class => [ + 'class' => Connection::class, + '__construct()' => [ + 'driver' => new Driver( + $params['app/db']['analytics']['dsn'], + $params['app/db']['analytics']['username'], + $params['app/db']['analytics']['password'], + ), + ], + ], +]; +``` + +The alias class names are used as service IDs and type hints. They don't +need PHP files of their own. + +Define matching parameters: + +```php +use Yiisoft\Db\Pgsql\Dsn; + +return [ + // ... + 'app/db' => [ + 'main' => [ + 'dsn' => new Dsn('pgsql', 'db', 'app', '5432'), + 'username' => 'user', + 'password' => 'password', + ], + 'analytics' => [ + 'dsn' => new Dsn('pgsql', 'analytics-db', 'analytics', '5432'), + 'username' => 'analytics_user', + 'password' => 'analytics_password', + ], + ], +]; +``` + +Services that need the primary database can still depend on +`ConnectionInterface`. Services that need another database should type-hint +the corresponding alias: + +```php + [ + 'newMigrationNamespace' => 'App\\Migration', + 'sourceNamespaces' => ['App\\Migration'], +], +``` + +Now you can use `make yii migrate:create page` to create a new +migration. For our example we need a `page` table with some columns: + +```php +columnBuilder(); + + $b->createTable('page', [ + 'id' => $column::uuidPrimaryKey(), + 'title' => $column::string()->notNull(), + 'slug' => $column::string()->notNull()->unique(), + 'text' => $column::text()->notNull(), + 'created_at' => $column::dateTime(), + 'updated_at' => $column::dateTime(), + ]); + } + + public function down(MigrationBuilder $b): void + { + $b->dropTable('page'); + } +} +``` + +The `M251102141707Page` name of the migration class is generated so replace +the `Page` suffix with the actual migration name. The `M251102141707` prefix +is needed to find and sort migrations in the order they were added. + +Note that we use UUID as the primary key. We are going to generate these IDs +ourselves instead of relying on database so we'll need an extra compose +package for that. + +```shell +make composer require ramsey/uuid +``` + +While the storage space is a bit bigger than using int, the workflow with +such IDs is beneficial. Since you generate the ID yourself so you can define +a set of related data and save it in a single transaction. The entities +that define this set of data in the code are often called an "aggregate". + +Apply the migration with `make yii migrate:up`. + +## An entity + +Now that you have a table it is time to define an entity in the code. Create +`src/Web/Page/Page.php`: + +```php +toSlug($title), + text: $text, + createdAt: $createdAt, + updatedAt: $updatedAt, + ); + } +} +``` + +## Repository + +Now that we have an entity, we need a place for methods to save it, delete +it, and select either a single page or multiple pages. This is the +repository boundary described earlier: the rest of the application works +with `Page` objects and doesn't need to know how they are stored. + +Create `src/Web/Page/PageRepository.php`: + +```php + $page->id, + 'title' => $page->title, + 'slug' => $page->slug, + 'text' => $page->text, + 'created_at' => $page->createdAt, + 'updated_at' => $page->updatedAt, + ]; + + if ($this->exists($page->id)) { + $this->connection->createCommand()->update('{{%page}}', $row, ['id' => $page->id])->execute(); + } else { + $this->connection->createCommand()->insert('{{%page}}', $row)->execute(); + } + } + + public function findOneBySlug(string $slug): ?Page + { + $query = $this->connection + ->select() + ->from('{{%page}}') + ->where('slug = :slug', ['slug' => $slug]); + + return $this->createPage($query->one()); + } + + /** + * @return iterable + */ + public function findAll(): iterable + { + $rows = $this->connection + ->select() + ->from('{{%page}}') + ->all(); + + foreach ($rows as $row) { + yield $this->createPage($row); + } + } + + private function createPage(?array $row): ?Page + { + if ($row === null) { + return null; + } + + return Page::create( + id: $row['id'], + title: $row['title'], + text: $row['text'], + slug: $row['slug'], + createdAt: new DateTimeImmutable($row['created_at']), + updatedAt: new DateTimeImmutable($row['updated_at']), + ); + } + + public function deleteBySlug(string $slug): void + { + $this->connection->createCommand()->delete( + '{{%page}}', + ['slug' => $slug], + )->execute(); + } + + public function exists(string $id): bool + { + return $this->connection->createQuery() + ->from('{{%page}}') + ->where(['id' => $id]) + ->exists(); + } +} +``` + +In this repository there are both methods to get data and `save()` to do +insert or update. DB returns raw data as arrays but our repository +automatically creates entities from this raw data so later we operate typed +data. + +## Actions and routes + +We need some actions to: + +1. List all pages. +2. View a page. +3. Delete a page. +4. Create a page. +5. Update a page. + +Then we need routing for all these. + +Let's tackle these one by one. + +### List all pages + +Create `src/Web/Page/ListAction.php`: + +```php +viewRenderer->render(__DIR__ . '/list', [ + 'pages' => $this->pageRepository->findAll(), + ]); + } +} +``` + +Define list view in `src/Web/Page/list.php`: + +```php + $pages */ +/** @var UrlGeneratorInterface $urlGenerator */ +?> + +
    + +
  • + title, $urlGenerator->generate('page/view', ['slug' => $page->slug])) ?> +
  • + +
+ +generate('page/edit', ['slug' => 'new'])) ?> +``` + +### View a page + +Create `src/Web/Page/ViewAction.php`: + +```php +pageRepository->findOneBySlug($slug); + if ($page === null) { + return $this->responseFactory->createResponse(Status::NOT_FOUND); + } + + return $this->viewRenderer->render(__DIR__ . '/view', [ + 'page' => $page, + ]); + } +} +``` + +Now, a template in `src/Web/Page/view.php`: + +```php + + +

generate('page/list')) ?> → title) ?>

+ +

+ text) ?> +

+ +generate('page/edit', ['slug' => $page->slug])) ?> | + + +post($urlGenerator->generate('page/delete', ['slug' => $page->slug])) + ->csrf($csrf); +?> +open() ?> + +close() ?> +``` + +In this view we have a form that submits a request for page +deletion. Handing it with `GET` is common as well, but it is very +wrong. Since deletion changes data, it needs to be handled by one of the +non-idempotent HTTP methods. We use POST and a form in our example, but it +could be `DELETE` and async request made with JavaScript. The button could +be later styled properly to look similar to the "Edit". + +### Delete a page + +Create `src/Web/Page/DeleteAction.php`: + +```php +pageRepository->deleteBySlug($slug); + + return $this->responseFactory + ->createResponse(Status::SEE_OTHER) + ->withHeader('Location', $this->urlGenerator->generate('page/list')); + } +} +``` + +### Create or update a page + +First of all, we need a form at `src/Web/Page/Form.php`: + +```php +findOneBySlug($slug); + if ($page === null) { + return $this->responseFactory->createResponse(Status::NOT_FOUND); + } + + $form->title = $page->title; + $form->text = $page->text; + } + + $this->formHydrator->populateFromPostAndValidate($form, $request); + + if ($form->isValid()) { + $id = $isNew ? Uuid::uuid7()->toString() : $page->id; + + $page = Page::create( + id: $id, + title: $form->title, + text: $form->text, + ); + + $pageRepository->save($page); + + return $this->responseFactory + ->createResponse(Status::SEE_OTHER) + ->withHeader( + 'Location', + $this->urlGenerator->generate('page/view', ['slug' => $page->slug]), + ); + } + + return $this->viewRenderer->render(__DIR__ . '/edit', [ + 'form' => $form, + 'isNew' => $isNew, + 'slug' => $slug, + ]); + } +} +``` + +Note that `Uuid::uuid7()->toString()` won't work for MySQL and you'll need bytes instead, `Uuid::uuid7()->getBytes()`. + +In the above we use a special slug in the URL for new pages so the URL looks +like `http://localhost/pages/new`. If the page isn't new, we pre-fill the +form with the data from the database. Similar to how we did in [Working with +forms](forms.md), we handle the form submission. After successful save we +redirect to the page view. + +Now, a template in `src/Web/Page/edit.php`: + +```php +post($urlGenerator->generate('page/edit', ['slug' => $slug])) + ->csrf($csrf); +?> + +open() ?> + required() ?> + required() ?> + +close() ?> +``` + +### Routing + +Adjust `config/common/routes.php`: + +```php +routes( + Route::get('/') + ->action(Web\HomePage\Action::class) + ->name('home'), + Route::methods([Method::GET, Method::POST], '/say') + ->action(Web\Echo\Action::class) + ->name('echo/say'), + + Group::create('/pages')->routes( + Route::get('') + ->action(Web\Page\ListAction::class) + ->name('page/list'), + Route::get('/{slug}') + ->action(Web\Page\ViewAction::class) + ->name('page/view'), + Route::methods([Method::GET, Method::POST], '/{slug}/edit') + ->action(Web\Page\EditAction::class) + ->name('page/edit'), + Route::post('/{slug}/delete') + ->action(Web\Page\DeleteAction::class) + ->name('page/delete'), + ), + ), +]; +``` + +Note that we've grouped all page-related routes with a group under `/pages` +prefix. That is a convenient way to both not to repeat yourself and add some +extra middleware, such as authentication, to the whole group. + +## Testando + +Now try it out by opening `http://localhost/pages` in your browser. diff --git a/src/pt-BR/guide/start/demo-apps.md b/src/pt-BR/guide/start/demo-apps.md new file mode 100644 index 00000000..9fcb85a7 --- /dev/null +++ b/src/pt-BR/guide/start/demo-apps.md @@ -0,0 +1,24 @@ +# Aplicações de demonstração + +Existem várias aplicações de demonstração que mostram diferentes abordagens +de arquitetura e recursos do framework. + +**[Demo Blog](https://github.com/yiisoft/demo-blog) — Arquitetura DDD em camadas** + +Uma aplicação de blog que demonstra uma arquitetura em camadas seguindo os +princípios do Domain-Driven Design (DDD). Esta demo é um bom ponto de +partida se você quer aprender a estruturar uma aplicação Yii3 com uma +separação clara de responsabilidades entre as camadas de domínio, aplicação +e infraestrutura. + +**[Demo Diary](https://github.com/yiisoft/demo-diary) — Arquitetura de vertical slices** + +Uma aplicação de diário construída com o padrão de arquitetura de vertical +slices. Nessa abordagem, cada funcionalidade é implementada de ponta a +ponta em vez de ser dividida em camadas horizontais, o que facilita +adicionar ou modificar funcionalidades de forma independente. + +**[Demo Summarizer](https://github.com/yiisoft/demo-summarizer) — Resumidor de documentos com modelo de linguagem (LLM)** + +Uma demo executável do Yii3 para enviar documentos, extrair Markdown +legível, resumir o conteúdo e acompanhar o progresso do processamento. diff --git a/src/pt-BR/guide/start/forms.md b/src/pt-BR/guide/start/forms.md new file mode 100644 index 00000000..caf61cb7 --- /dev/null +++ b/src/pt-BR/guide/start/forms.md @@ -0,0 +1,429 @@ +# Trabalhando com formulários + +Esta seção continua a melhorar o "Dizendo olá". Em vez de usar a URL, agora +você vai pedir a mensagem ao usuário por meio de um formulário. + +Neste tutorial, você vai aprender a: + +* Criar um form model para representar os dados que o usuário informa em um + formulário. +* Declarar regras para validar os dados informados. +* Montar um formulário HTML em uma view. + +## Instalando o pacote de formulários + +Para instalar o pacote de formulários, rode o seguinte comando no diretório +da sua aplicação: + +``` +composer require yiisoft/form-model +``` + +No Docker, fica assim: + +``` +make composer require yiisoft/form-model +``` + +## Criando um formulário + +Os dados que serão pedidos ao usuário ficam representados por uma classe +`Form`, como mostrado abaixo, salva no arquivo `/src/Web/Echo/Form.php`: + +```php + Nota: os atributos de validação são regras do Yii Validator. Para verificações comuns, procure primeiro uma regra existente. Se um campo +> também precisar de validação específica da aplicação, use `Callback` para essa lógica de domínio. Com atributos PHP, use a opção `method`, +> porque atributos PHP não podem conter closures. Por exemplo, valide a sintaxe do UUID com `Uuid` e só então adicione +> `#[Callback(method: 'validateUuidV7', skipOnError: true)]` quando o seu domínio exigir especificamente UUID versão 7. + +```php +use Yiisoft\Validator\Result; +use Yiisoft\Validator\Rule\Callback; +use Yiisoft\Validator\Rule\Uuid; + +#[Uuid(skipOnError: true)] +#[Callback(method: 'validateUuidV7', skipOnError: true)] +public string $id = ''; + +private function validateUuidV7(mixed $value): Result +{ + return \App\Support\Uuid::isVersion7($value) + ? new Result() + : (new Result())->addError('ID must be a UUID version 7.'); +} +``` + +O método de callback retorna um `Result`: retorne um resultado vazio quando +o valor for válido ou adicione um erro quando não for. O corpo do método +pode chamar qualquer código de validação que a sua aplicação já usa, como +`App\Support\Uuid::isValid($value, 'v7')`. Veja os [detalhes da regra +Callback](https://github.com/yiisoft/validator/blob/master/docs/guide/en/built-in-rules-callback.md) +para exemplos completos e as assinaturas de método disponíveis. + +Para uma lógica de validação reaproveitada em vários formulários, crie uma +regra e um handler personalizados do Yii Validator em vez de copiar métodos +de callback. Veja o [guia de regras +personalizadas](https://github.com/yiisoft/validator/blob/master/docs/guide/en/creating-custom-rules.md) +para a estrutura de regra/handler. + +## Validação personalizada + +Os atributos de validação são regras do Yii Validator. Para verificações +comuns, procure primeiro uma regra existente. Por exemplo, para validar uma +string UUID, use `Uuid`: + +```php +use Yiisoft\FormModel\FormModel; +use Yiisoft\Validator\Rule\Uuid; + +final class Form extends FormModel +{ + #[Uuid] + public string $id = ''; +} +``` + +Quando um campo precisa de uma validação específica da aplicação que nenhuma +regra embutida cobre, use `Callback`. Isso é útil para verificações pontuais +ou para delegar a um método do domínio ou de uma biblioteca. Com atributos +PHP, use a opção `method`, porque atributos PHP não podem conter +closures. Por exemplo, o formulário a seguir valida o dígito verificador de +um número de cartão: + +```php +addError('Card number must be a string.'); + } + + $digits = str_replace([' ', '-'], '', $value); + + if ($digits === '' || !ctype_digit($digits)) { + return (new Result())->addError('Card number must contain digits only.'); + } + + $sum = 0; + $double = false; + + foreach (array_reverse(str_split($digits)) as $digit) { + $number = (int) $digit; + + if ($double) { + $number *= 2; + if ($number > 9) { + $number -= 9; + } + } + + $sum += $number; + $double = !$double; + } + + if ($sum % 10 !== 0) { + return (new Result())->addError('Card number checksum is invalid.'); + } + + return new Result(); + } +} +``` + +O método de callback retorna um `Result`: retorne um resultado vazio quando +o valor for válido ou adicione um erro quando não for. O corpo do método +pode chamar qualquer código de validação que a sua aplicação já usa, como +`App\Payment\CardNumber::hasValidChecksum($value)`. + +Para uma lógica de validação reaproveitada em vários formulários, crie uma +regra e um handler personalizados do Yii Validator em vez de copiar métodos +de callback. Veja o [guia de regras +personalizadas](https://github.com/yiisoft/validator/blob/master/docs/guide/en/creating-custom-rules.md) +para a estrutura de regra/handler. + +## Validando vários campos juntos + +Atributos nas propriedades bastam quando cada campo pode ser validado de +forma independente. Quando uma regra depende de vários campos, coloque uma +regra `Callback` na classe do form model e associe o erro ao campo que deve +exibi-lo. + +Por exemplo, um filtro de relatório pode exigir que a data inicial seja +anterior ou igual à data final: + +```php +dateFrom === '' || $this->dateTo === '') { + return $result; + } + + $dateFrom = $this->parseDate($this->dateFrom); + $dateTo = $this->parseDate($this->dateTo); + + if ($dateFrom === null || $dateTo === null) { + return $result; + } + + if ($dateFrom > $dateTo) { + $result->addError('The start date must be earlier than or equal to the end date.', [], ['dateFrom']); + } + + return $result; + } + + private function parseDate(string $value): ?DateTimeImmutable + { + $date = DateTimeImmutable::createFromFormat('!Y-m-d', $value); + $errors = DateTimeImmutable::getLastErrors(); + + if ($date === false || ($errors !== false && ($errors['warning_count'] > 0 || $errors['error_count'] > 0))) { + return null; + } + + return $date; + } +} +``` + +O `Callback` no nível da classe recebe o objeto inteiro como `$value`, mas +usar `$this` costuma ser mais claro em um método do form model. Retornar um +`Result` vazio significa que a regra entre campos passou. O terceiro +argumento de `addError()` é o caminho do valor; `['dateFrom']` faz o erro +aparecer no campo `dateFrom` quando o formulário é renderizado. + +## Usando o formulário + +Agora que você tem um formulário, use-o na sua action do "[Dizendo +olá](hello.md)". + +Este é o resultado final em `/src/Web/Echo/Action.php`: + +```php +formHydrator->populateFromPostAndValidate($form, $request); + + return $this->viewRenderer->render(__DIR__ . '/template', [ + 'form' => $form, + ]); + } +} +``` + +Em vez de ler da rota, você preenche o formulário com os dados POST da +requisição e o valida com a ajuda do `FormHydrator`. Depois, passa o +formulário para a view. + +Para o formulário funcionar, precisamos permitir tanto GET, para renderizar +o formulário, quanto POST, para enviar os dados. Ajuste a sua rota em +`config/common/routes.php`: + +```php +routes( + Route::get('/') + ->action(Web\HomePage\Action::class) + ->name('home'), + Route::methods([Method::GET, Method::POST], '/say') + ->action(Web\Echo\Action::class) + ->name('echo/say'), + ), +]; +``` + +## Ajustando a view + +Para renderizar um formulário, você precisa alterar a sua view, +`src/Web/Echo/template.php`: + +```php +post($urlGenerator->generate('echo/say')) + ->csrf($csrf); +?> + +open() ?> + required() ?> + +close() ?> + +isValid()): ?> + Echo said: message) ?> + +``` + +Se o formulário for válido, você exibe uma mensagem. O restante inicializa e +renderiza o formulário. + +Primeiro, você inicializa `$htmlForm` com o tipo POST e a URL da action +gerada com a ajuda do gerador de URLs. Você pode acessá-lo como +`$urlGenerator` em todas as views. Também precisa passar o token CSRF para o +formulário, que também está disponível em toda view como `$csrf` graças às +view injections listadas em `config/common/params.php`: + +```php +'yiisoft/yii-view-renderer' => [ + 'injections' => [ + Reference::to(CsrfViewInjection::class), + ], +], +``` + +O template renderiza o valor do token CSRF como um input oculto para +garantir que a requisição vem da página do formulário e não de outro +site. Ele é enviado junto com os dados POST do formulário. Sem ele, o +resultado seria o [código de resposta HTTP +422](https://tools.ietf.org/html/rfc4918#section-11.2). + +Você usa `Field::text()` para exibir o campo "message", então ele cuida de +preencher o valor, escapá-lo e renderizar o label do campo e os erros de +validação. + +Agora, se você enviar uma mensagem vazia, vai receber um erro de validação: +"The message to be echoed must contain at least 2 characters." + +## Testando + +Para ver como funciona, acesse a seguinte URL no navegador: + +``` +http://localhost:8080/say +``` + +Você vai ver uma página com um campo de formulário e um label indicando qual +dado informar. O formulário também tem um botão "submit" com o texto +"Say". Se você clicar no botão "submit" sem digitar nada, vai ver que o +campo é obrigatório. Se digitar um único caractere, o formulário mostra uma +mensagem de erro ao lado do campo com problema. + +![Formulário com erro de validação](/images/guide/start/form-error.png) + +Depois de digitar uma mensagem válida e clicar no botão "submit", a página +mostra de volta os dados que você digitou. + +![Formulário com mensagem de sucesso](/images/guide/start/form-success.png) + +## Resumo + +Nesta seção do guia, você aprendeu a criar uma classe de form model para +representar os dados do usuário e validar esses dados. + +Você também aprendeu a receber dados dos usuários e a exibi-los de volta no +navegador. Essa é uma tarefa que pode tomar muito tempo no desenvolvimento +de uma aplicação, mas o Yii oferece widgets poderosos que a tornam fácil. + +Na próxima seção, você vai aprender a trabalhar com bancos de dados, que são +necessários em quase toda aplicação. diff --git a/src/pt-BR/guide/start/gii.md b/src/pt-BR/guide/start/gii.md new file mode 100644 index 00000000..f07d8fbd --- /dev/null +++ b/src/pt-BR/guide/start/gii.md @@ -0,0 +1,4 @@ +# Gerando código com o Gii + +> [!NOTE] +> O Gii está em desenvolvimento e vai ficar disponível mais tarde. diff --git a/src/pt-BR/guide/start/hello.md b/src/pt-BR/guide/start/hello.md new file mode 100644 index 00000000..741fcfc7 --- /dev/null +++ b/src/pt-BR/guide/start/hello.md @@ -0,0 +1,192 @@ +# Dizendo olá + +Esta seção descreve como criar uma nova página "Hello" na sua aplicação. É +uma página simples que devolve o que você passar para ela ou, se nada for +passado, apenas diz "Hello!". + +Para isso, você vai definir uma rota e criar [um +handler](../structure/handler.md) que faz o trabalho e monta a resposta. +Depois, vai melhorá-lo para usar uma [view](../views/view.md) na construção +da resposta. + +Neste tutorial, você vai aprender três coisas: + +1. Como criar um handler para responder a uma requisição. +2. Como mapear uma URL para o handler. +3. Como usar uma [view](../views/view.md) para compor o conteúdo da + resposta. + +## Criando um handler + +Para a tarefa "Hello", você vai criar uma classe handler que lê o parâmetro +`message` da requisição e mostra essa mensagem de volta para o usuário. Se a +requisição não trouxer o parâmetro `message`, a action mostra a mensagem +padrão "Hello". + +Crie `src/Web/Echo/Action.php`: + +```php +responseFactory->createResponse(); + $response->getBody()->write('The message is: ' . Html::encode($message)); + return $response; + } +} +``` + +No exemplo, o método `__invoke` recebe o parâmetro `$message`, que, com a +ajuda do atributo `RouteArgument`, pega a mensagem da URL. O valor padrão é +`"Hello!"`. Se a requisição for feita para `/say/Goodbye`, a action atribui +o valor "Goodbye" à variável `$message`. + +A aplicação passa a resposta pela [pilha de +middlewares](../structure/middleware.md) até o emitter, que envia a resposta +ao usuário final. + +## Configurando o router + +Agora, para mapear o handler para uma URL, você precisa adicionar uma rota +em `config/common/routes.php`: + +```php +routes( + Route::get('/') + ->action(Web\HomePage\Action::class) + ->name('home'), + Route::get('/say[/{message}]') + ->action(Web\Echo\Action::class) + ->name('echo/say'), + ), +]; +``` + +Acima, você mapeia o padrão `/say[/{message}]` para `\App\Web\Echo\Action`. +A cada requisição, o router cria uma instância e chama o método +`__invoke()`. A parte `{message}` do padrão grava o que for informado nessa +posição no argumento de rota `message`. `[]` marca essa parte do padrão +como opcional. + +Você também dá o nome `echo/say` a essa rota para poder gerar URLs que +apontem para ela. + +## Testando + +Depois de criar a action e a view, abra `http://localhost/say/Hello+World` +no navegador. + +Essa URL mostra uma página com "The message is: Hello World". + +Se você omitir o parâmetro `message` na URL, a página mostra "The message +is: Hello!". + +## Criando um template de view + +Normalmente, a tarefa é mais complicada do que imprimir "hello world" e +envolve renderizar algum HTML complexo. Para isso, é prático usar templates +de view. Eles são scripts que você escreve para gerar o corpo de uma +resposta. + +Para a tarefa "Hello", crie um template `src/Web/Echo/template.php` que +imprime o parâmetro `message` recebido do método da action: + +```php + + +

The message is:

+``` + +No código acima, o parâmetro `message` passa por codificação HTML antes de +ser impresso. Isso é necessário porque o parâmetro vem do usuário final e +está sujeito a [ataques de cross-site scripting +(XSS)](https://pt.wikipedia.org/wiki/Cross-site_scripting) com JavaScript +malicioso embutido no parâmetro. + +Naturalmente, você pode colocar mais conteúdo na view `say`. O conteúdo pode +ter tags HTML, texto puro e até instruções PHP. Na verdade, o serviço de +view executa a view `say` como um script PHP. + +Para usar a view, você precisa alterar `src/Web/Echo/Action.php`: + +```php +viewRenderer->render(__DIR__ . '/template', [ + 'message' => $message, + ]); + } +} +``` + +Agora abra o navegador e confira de novo. Você deve ver um texto parecido, +mas com um layout aplicado. + +Além disso, você separou a parte de como funciona da parte de como é +apresentado. Em aplicações maiores, isso ajuda muito a lidar com a +complexidade. + +## Resumo + +Nesta seção, você passou pelas partes de handler e de template de uma +aplicação web típica. Você criou um handler como parte de uma classe para +tratar uma requisição específica. Também criou uma view para compor o +conteúdo da resposta. Neste exemplo simples, nenhuma fonte de dados foi +usada, já que o único dado era o parâmetro `message`. + +Você também aprendeu sobre o roteamento no Yii, que funciona como a ponte +entre as requisições do usuário e os handlers. + +Na próxima seção, você vai aprender a buscar dados e adicionar uma nova +página com um formulário HTML. diff --git a/src/pt-BR/guide/start/looking-ahead.md b/src/pt-BR/guide/start/looking-ahead.md new file mode 100644 index 00000000..277bd115 --- /dev/null +++ b/src/pt-BR/guide/start/looking-ahead.md @@ -0,0 +1,9 @@ +# Seguindo em frente + +Se você leu todo o capítulo "Primeiros passos", já criou uma aplicação Yii +completa. No caminho, aprendeu a implementar alguns recursos comuns, como +receber dados dos usuários por um formulário HTML, buscar dados em um banco +de dados e exibir dados de forma paginada. Também aprendeu a usar o +[Gii](gii.md) para gerar código automaticamente. Usar o Gii para gerar +código transforma boa parte do desenvolvimento web em algo tão simples +quanto preencher alguns formulários. diff --git a/src/pt-BR/guide/start/prerequisites.md b/src/pt-BR/guide/start/prerequisites.md new file mode 100644 index 00000000..58d2d408 --- /dev/null +++ b/src/pt-BR/guide/start/prerequisites.md @@ -0,0 +1,45 @@ +# O que você precisa saber? + +A curva de aprendizado do Yii não é tão íngreme quanto a de outros +frameworks PHP, mas ainda assim há algumas coisas que você deve aprender +antes de começar com o Yii. + +## PHP + +O Yii é um framework PHP, então [leia e entenda a referência da +linguagem](https://www.php.net/manual/pt_BR/langref.php). + +## Programação orientada a objetos + +Você precisa de uma noção básica de programação orientada a objetos. Se +ainda não conhece, veja um dos muitos tutoriais disponíveis, como [o do +tuts+](https://code.tutsplus.com/tutorials/object-oriented-php-for-beginners--net-12762). + +Ao desenvolver com o Yii, você escreve código orientado a objetos, então +conheça bem o [suporte do PHP a +POO](https://www.php.net/manual/pt_BR/language.oop5.php). + +Quanto mais complexa for a sua aplicação, mais conceitos avançados de POO +você vai precisar aprender para lidar bem com essa complexidade. + +## Linha de comando e Composer + +O Yii usa amplamente o gerenciador de pacotes que é o padrão de fato no PHP, +o [Composer](https://getcomposer.org), então leia e entenda o [guia +dele](https://getcomposer.org/doc/01-basic-usage.md). Se você não tem +costume de usar a linha de comando, é hora de começar. Depois de aprender o +básico, você não vai querer trabalhar sem ela. + +## HTTP + +Como o Yii é um framework web e a web usa principalmente HTTP, é uma boa +ideia [aprender mais sobre +ele](https://developer.mozilla.org/pt-BR/docs/Web/HTTP). + +## Docker + +O template de aplicação padrão usa Docker, então recomendamos que você [leia +e entenda os conceitos](https://docs.docker.com/get-started/). + +Também vale a pena conhecer os princípios do [twelve-factor +app](https://12factor.net/pt_br/). diff --git a/src/pt-BR/guide/start/workflow.md b/src/pt-BR/guide/start/workflow.md new file mode 100644 index 00000000..e9c42b98 --- /dev/null +++ b/src/pt-BR/guide/start/workflow.md @@ -0,0 +1,149 @@ +# Fluxo da aplicação + +Depois de instalar o Yii, você tem uma aplicação Yii funcionando. Esta +seção apresenta as funcionalidades que vêm com a aplicação, como o código +está organizado e como a aplicação trata as requisições de forma geral. + +Diferente do próprio framework, depois que você instala um template de +projeto, ele é todo seu. Você pode adicionar ou remover código e mudar o +que precisar. + +## Funcionalidades + +A aplicação instalada tem apenas uma página, acessível em +`http://localhost/`. Ela usa um layout comum que você pode reaproveitar nas +próximas páginas. + + + +Além da aplicação web, você pode acessar um script de console via `./yii` +ou, no caso do Docker, `make yii`. Use esse script para rodar tarefas em +segundo plano e de manutenção da aplicação, descritas na [seção de +aplicações de console](../tutorial/console-applications.md). + +## Debugger experimental + +O Yii tem um debugger que coleta dados de debug das requisições web e os +expõe pelo [Yii Dev Panel](https://yiisoft.github.io/yii-dev-panel/). O +debugger ainda está em desenvolvimento. Ele não foi lançado como pacote +estável, e a API, as rotas e a configuração podem mudar ou ser +descontinuadas. + +Para testar a versão de desenvolvimento atual, instale o pacote da API de +debug: + +```shell +composer require yiisoft/yii-debug-api:^3.0@dev +``` + +Ative o modo debug no `.env`: + +```dotenv +APP_DEBUG=true +``` + +O pacote registra as rotas automaticamente. Inicie a aplicação e abra +`/debug` para conferir se a API de debug está disponível. Depois abra o [Yii +Dev Panel](https://yiisoft.github.io/yii-dev-panel/) e informe a URL da sua +aplicação. + +> [!CAUTION] +> Use o modo debug no desenvolvimento local. Em produção, mantenha `APP_DEBUG=false` e não exponha as rotas de debug publicamente. + +## Estrutura da aplicação + +Os diretórios e arquivos mais importantes da sua aplicação são (considerando +que o diretório raiz da aplicação é `app`): + +``` +assets/ Arquivos-fonte dos asset bundles. +config/ Arquivos de configuração. + common/ Configuração comum e definições de DI. + console/ Configuração específica do console. + environments/ Configuração por ambiente (dev/test/prod). + web/ Configuração específica da web. +docker/ Arquivos específicos do Docker. +public/ Arquivos acessíveis publicamente pela internet. + assets/ Assets publicados/compilados. + index.php Script de entrada. +runtime/ Arquivos gerados em tempo de execução. +src/ Código-fonte da aplicação. + Console/ Comandos de console. + Shared/ Código compartilhado entre as aplicações web e console. + Web/ Código específico da web (actions, handlers, layout). + Shared/ Componentes web compartilhados. + Layout/ Componentes e templates de layout. + Environment.php Classe de configuração do ambiente. +tests/ Conjunto de testes Codeception da aplicação. + Console/ Testes dos comandos de console. + Functional/ Testes funcionais. + Unit/ Testes unitários. + Web/ Testes das actions web. +vendor/ Pacotes do Composer instalados. +Makefile Configuração do comando make. +yii Ponto de entrada da aplicação de console. +``` + +De forma geral, os arquivos da aplicação se dividem em dois grupos: os que +ficam em `app/public` e os que ficam nos outros diretórios. Os primeiros +podem ser acessados diretamente via HTTP (ou seja, no navegador), enquanto +os demais não devem ser expostos. + +Toda aplicação tem um script de entrada `public/index.php`, o único script +PHP acessível pela web na aplicação. O script de entrada usa um +[application runner](https://github.com/yiisoft/yii-runner) para criar uma +instância da requisição recebida com a ajuda de um dos pacotes PSR-7 e a +passa para uma instância da [aplicação](../structure/application.md). A +aplicação executa um conjunto de middlewares em sequência para processar a +requisição. Depois, passa o resultado para o emitter, que envia a resposta +ao navegador. + +Dependendo dos middlewares que você usa, a aplicação pode se comportar de +forma diferente. Por padrão, um router usa a URL requisitada e a +configuração para escolher um handler e executá-lo para produzir a resposta. + +Você pode saber mais sobre o template de aplicação na [documentação do +pacote yiisoft/app](https://github.com/yiisoft/app/blob/master/README.md). + +## Ciclo de vida da requisição + +O diagrama a seguir mostra como uma aplicação trata uma requisição. + +```mermaid +flowchart LR + user[User's client] --> index + index[index.php] --> DI[Initialize Dependency Container] + config[configs] -.-> DI + DI --> RequestFactory[RequestFactory] + RequestFactory -->|Request| app[Application] + app -->|Request| middleware[Middleware] + middleware -->|Request| router[Router] + router -->|Request| action[Action Handler] + action -->|Response| emitter[SapiEmitter] + router -->|Response| emitter + middleware -->|Response| emitter + app -->|Response| emitter + emitter --> user +``` + +1. Um usuário faz uma requisição para o [script de + entrada](../structure/entry-script.md) `public/index.php`. +2. O script de entrada, com a ajuda do application runner, carrega a + [configuração](../concept/configuration.md) do container e cria uma + instância da [aplicação](../structure/application.md) e os serviços + necessários para tratar a requisição. +3. A request factory cria um objeto de requisição a partir da requisição + bruta que veio do usuário. +4. A aplicação passa o objeto de requisição pelo array de middlewares + configurado. Um deles normalmente é o router. +5. O router descobre qual handler executar com base na requisição e na + configuração. +6. O handler pode carregar alguns dados, possivelmente de um banco de dados. +7. O handler monta uma resposta usando esses dados, diretamente ou com a + ajuda do pacote de view. +8. O emitter recebe a resposta e cuida de enviá-la para o navegador do + usuário. diff --git a/src/pt-BR/guide/structure/action.md b/src/pt-BR/guide/structure/action.md new file mode 100644 index 00000000..a377ae66 --- /dev/null +++ b/src/pt-BR/guide/structure/action.md @@ -0,0 +1,128 @@ +# Actions + +In a web application, the request URL determines what's executed. Matching +is made by a router configured with multiple routes. Each route can be +attached to a middleware that, given request, produces a response. Since +middleware overall could be chained and can pass actual handling to the next +middleware, we call the middleware actually doing the job an action. + +There are multiple ways to describe an action. The simplest one is using a +closure: + +```php +use \Psr\Http\Message\ServerRequestInterface; +use \Psr\Http\Message\ResponseInterface; +use Yiisoft\Router\Route; + +Route::get('/')->action(function (ServerRequestInterface $request) use ($responseFactory): ResponseInterface { + $response = $responseFactory->createResponse(); + $response->getBody()->write('You are at homepage.'); + return $response; +}); +``` + +It's fine for simple handling since any more complicated one would require +getting dependencies, so a good idea would be moving the handling to a class +method. Callback middleware could be used for the purpose: + +```php +use Yiisoft\Router\Route; + +Route::get('/')->action(FrontPageAction::class), +``` + +The class itself would be like: + +```php +use \Psr\Http\Message\ServerRequestInterface; +use \Psr\Http\Message\ResponseInterface; + +final readonly class FrontPageAction +{ + public function __invoke(ServerRequestInterface $request): ResponseInterface + { + // build response for a front page + } +} +``` + +For many cases, it makes sense to group handling for many routes into a +single class: + + +```php +use Yiisoft\Router\Route; + +Route::get('/post/index')->action([PostController::class, 'actionIndex']), +Route::get('/post/view/{id:\d+}')->action([PostController::class, 'actionView']), +``` + +The class itself would look like the following: + +```php +use \Psr\Http\Message\ServerRequestInterface; +use \Psr\Http\Message\ResponseInterface; +use Yiisoft\Router\HydratorAttribute\RouteArgument; + +final readonly class PostController +{ + public function actionIndex(ServerRequestInterface $request): ResponseInterface + { + // render posts list + } + + + public function actionView( + ServerRequestInterface $request, + #[RouteArgument('id')] + int $id, + ): ResponseInterface + { + // render a single post by $id + } +} +``` + +We usually call such a class "controller." + +The `{id}` part of the `/post/view/{id:\d+}` route is a named route +parameter. Route parameters are available from +`Yiisoft\Router\CurrentRoute`. To receive one as an action argument, add the +`RouteArgument` attribute to the corresponding parameter. The attribute name +should match the route parameter name. + +## Autowiring + +Both constructors of action-classes and action-methods are automatically getting services from + the dependency injection container: + +```php +use \Psr\Http\Message\ServerRequestInterface; +use \Psr\Http\Message\ResponseInterface; +use Psr\Log\LoggerInterface; + +final readonly class PostController +{ + public function __construct( + private PostRepository $postRepository + ) + { + } + + public function actionIndex(ServerRequestInterface $request, LoggerInterface $logger): ResponseInterface + { + $logger->debug('Rendering posts list'); + // render posts list + } + + + public function actionView(ServerRequestInterface $request): ResponseInterface + { + // render a single post + } +} +``` + +In the above example `PostRepository` is injected automatically via +constructor. That means it is available in every action. Logger is injected +into `index` action only. diff --git a/src/pt-BR/guide/structure/application.md b/src/pt-BR/guide/structure/application.md new file mode 100644 index 00000000..3fff6311 --- /dev/null +++ b/src/pt-BR/guide/structure/application.md @@ -0,0 +1,18 @@ +# Application + +The primary purpose of the web application and its runner in Yii3 is to +process requests to get responses. + +Typically, the runtime consists of: + +1. Startup. Get config, create an instance of container and do additional + environment initialization such as registering error handler, so it can + handle errors occurring. Fire `ApplicationStartup` event. +2. Handle requests via passing request objects to middleware dispatcher to + execute [middleware stack](middleware.md) and get a response object. In + usual PHP applications, it's done once. In [environments such as + RoadRunner](../tutorial/using-with-event-loop.md), it could be done + multiple times with the same application instance. Response object is + converted into an actual HTTP response by using emitter. Fire + `AfterEmit` event. +3. Shutdown. Fire `ApplicationShutdown` event. diff --git a/src/pt-BR/guide/structure/designing-packages.md b/src/pt-BR/guide/structure/designing-packages.md new file mode 100644 index 00000000..513245d9 --- /dev/null +++ b/src/pt-BR/guide/structure/designing-packages.md @@ -0,0 +1,536 @@ +# Designing packages for Yii applications + +This page describes how to design a Composer package that adds behavior to a +Yii application through configuration. Use it when your package needs to +register services, routes, events, commands, assets, migrations, +translations, or a theme. + +For installing and updating packages in an application, see [Using +packages](package.md). + +## Composer metadata + +Each package must have a `composer.json` file in its root directory. At +minimum, define a package name, dependencies, autoloading, and Yii config +metadata when the package integrates with a Yii application. + +Use a package name in the `vendor-name/project-name` format: + +```json +{ + "name": "vendor/blog", + "type": "library", + "description": "Blog integration for Yii applications", + "require": { + "php": ">=8.2", + "yiisoft/router": "^4.0" + }, + "autoload": { + "psr-4": { + "Vendor\\Blog\\": "src/" + } + } +} +``` + +Use stable dependency constraints for stable releases. Avoid using `yiisoft` +as your vendor name because it is reserved for Yii packages. + +If your package requires a Yii application, prefixing the project name with +`yii-` can make that clear on Packagist. + +## Package layout + +A Yii-aware package is a regular Composer package with PHP classes, optional +resource files, and optional config files. Keep the configuration in a +predictable directory and make the public API explicit: + +``` +composer.json +config/ + params.php + di.php + di-providers.php + routes.php + events.php + params-web.php + params-console.php + di-console.php +src/ + ... +assets/ + ... +migrations/ + ... +messages/ + ... +views/ + ... +``` + +Use only the files your package needs. For example, a package with console +commands but no web routes does not need `routes.php`. + +## Config plugin metadata + +Yii applications use [yiisoft/config](https://github.com/yiisoft/config) to +discover package configuration. Declare package config files in the +`extra.config-plugin` section of `composer.json`: + +```json +{ + "name": "vendor/blog", + "type": "library", + "autoload": { + "psr-4": { + "Vendor\\Blog\\": "src/" + } + }, + "extra": { + "config-plugin": { + "params": "config/params.php", + "di": "config/di.php", + "di-providers": "config/di-providers.php", + "routes": "config/routes.php", + "events": "config/events.php", + "params-web": "config/params-web.php", + "params-console": "config/params-console.php", + "di-console": "config/di-console.php" + } + } +} +``` + +Each `config-plugin` key is a config group name and each value is a path +relative to the package root. + +Use the common, web, and console groups consistently: + +- `params`, `di`, `di-providers`, `di-delegates`, `events`, and `bootstrap` + apply to both web and console entry points. +- `params-web`, `di-web`, `di-providers-web`, `events-web`, `bootstrap-web`, + and `routes` apply to web entry points. +- `params-console`, `di-console`, `di-providers-console`, `events-console`, + and `bootstrap-console` apply to console entry points. + +If your package defines a new config group, document how an application +should load that group. Prefer the standard groups when you integrate with +Yii services because application templates and Yii packages already use +these names. + +After users install, update, remove, or dump Composer autoload files, the +config plugin rebuilds the merge plan that Yii reads at runtime. If users +edit their root package configuration manually, ask them to run: + +```sh +composer yii-config-rebuild +``` + +## Parameters + +Put default options in `config/params.php`. Group package parameters under +the Composer package name to avoid collisions: + +```php + [ + 'postsPerPage' => 20, + 'cacheTtl' => 3600, + ], +]; +``` + +Application developers can override these values in their own +`config/common/params.php`, `config/web/params.php`, +`config/console/params.php`, or environment-specific parameter files. + +Do not read environment variables or global state from package code when a +parameter can express the choice. Use parameters to configure services +through DI definitions or service providers. + +## DI definitions + +Use `config/di.php`, `config/di-web.php`, or `config/di-console.php` for +direct container definitions: + +```php + [ + 'class' => PostRepository::class, + '__construct()' => [ + 'cacheTtl' => $params['vendor/blog']['cacheTtl'], + ], + ], +]; +``` + +Prefer direct DI definitions when the configuration describes one service +clearly. + +## DI service providers + +Use a DI provider when registration belongs together as a reusable unit: +several related services, aliases, factory definitions, or extensions. + +Register providers in `config/di-providers.php`: + +```php + BlogProvider::class, +]; +``` + +Declare the group in `composer.json`: + +```json +"extra": { + "config-plugin": { + "di-providers": "config/di-providers.php" + } +} +``` + +A provider can return several service definitions and extensions. Place the +provider class in `src/Provider/BlogProvider.php`: + +```php + PostRepository::class, + PostRepositoryInterface::class => static fn ( + ContainerInterface $container + ): CachedPostRepository => new CachedPostRepository( + $container->get(PostRepository::class), + $container->get(LoggerInterface::class), + ), + ]; + } + + public function getExtensions(): array + { + return []; + } +} +``` + +## Routes + +Web packages can add routes through `config/routes.php`, declared as the +`routes` group: + +```php +routes( + Route::get('') + ->action(IndexAction::class) + ->name('vendor/blog/index'), + ), +]; +``` + +Route names should be package-prefixed. This avoids collisions with +application routes and with routes from other packages. + +Keep package routes small and overridable. If an application needs full +control over URLs, document the actions and let the application define its +own routes. + +## Events + +Use `config/events.php`, `config/events-web.php`, or +`config/events-console.php` to attach package handlers to events: + +```php + [ + ClearPostListCache::class, + ], +]; +``` + +Handlers can be closures, callables, invokable objects, invokable class +names, or DI aliases supported by the event dispatcher configuration. Prefer +class names for package handlers because applications can override their +dependencies through the container. + +## Assets + +If your package ships CSS, JavaScript, images, or fonts, define asset +bundles as PHP classes. For example, place this class in +`src/Asset/BlogAsset.php`: + +```php +register(BlogAsset::class); +``` + +Use `$sourcePath` for files shipped inside the package. Use `$basePath` and +`$baseUrl` as the public target where the asset manager publishes them. + +## Migrations + +Packages that need database schema changes should ship migrations and add +their namespace or path to `yiisoft/db-migration` parameters. + +For namespaced migrations: + +```php + [ + 'sourceNamespaces' => [ + 'Vendor\\Blog\\Migration', + ], + ], +]; +``` + +For path-based migrations: + +```php + [ + 'sourcePaths' => [ + __DIR__ . '/../migrations', + ], + ], +]; +``` + +Put this in `config/params-console.php` and declare it as `params-console` +in `composer.json`. + +This only contributes package migration locations. The application still +needs `yiisoft/db-migration` installed and a database connection configured +before migration commands can run. + +Package migrations must be stable after release. Do not edit a migration +that users may already have applied. Add a new migration instead. + +## Translations + +If the package has user-facing messages, give it a dedicated translation +category and register a category source in `config/di.php`: + +```php + [ + 'definition' => static function (): CategorySource { + $messageSource = new MessageSource(__DIR__ . '/../messages'); + + return new CategorySource( + 'vendor-blog', + $messageSource, + new IntlMessageFormatter(), + $messageSource, + ); + }, + 'tags' => ['translation.categorySource'], + ], +]; +``` + +Store messages by locale and category: + +``` +messages/ + en-US/ + vendor-blog.php + de/ + vendor-blog.php +``` + +Use the explicit category when translating: + +```php +$translator->translate('post.created', category: 'vendor-blog'); +``` + +## Themes + +A package can ship view files and assets for a theme. Do not activate it +from vendor package configuration. Instead, document the root application +configuration needed to enable it. For the application template, this +belongs in `config/web/params.php`: + +```php + [ + 'theme' => [ + 'pathMap' => [ + '@views' => '@vendor/vendor/blog/views', + ], + 'basePath' => '@vendor/vendor/blog/assets', + 'baseUrl' => '@assetsUrl/vendor-blog', + ], + ], +]; +``` + +Themes replace view paths according to a path map. Document which +application view paths your theme replaces and which asset URL must be +published or exposed by the application. + +Do not set `yiisoft/view.theme` directly in vendor package +configuration. `yiisoft/view` already defines that key, and duplicate keys +in the same configuration layer are not allowed. + +If your package only provides optional theme files, do not make the theme +active by default. Provide the view files, asset bundle, and a documented +parameter snippet so the application can opt in. + +## Console commands + +Console packages can add Symfony Console commands through +`config/params-console.php`: + +```php + [ + 'commands' => [ + 'blog/reindex' => ReindexCommand::class, + ], + ], +]; +``` + +Command names should be package-prefixed. Keep command dependencies +constructor-injected and registered through DI. + +## Application overrides + +Package configuration is the default layer. The application can override it +in its root package configuration. Design for that: + +- Use package-prefixed parameter keys, route names, event handler IDs, and + DI aliases. +- Keep default configuration small and documented. +- Avoid doing irreversible work during service registration. +- Put optional integrations in separate config files or providers when they + require optional Composer packages. +- Test the package inside a minimal Yii application so the config plugin, DI + container, routes, console commands, migrations, translations, and assets + are exercised together. + +When a user needs to customize package configuration, they usually do not +need to copy the package config file. They can partially redefine the needed +keys in the application configuration. + +After changing config group mappings, they should rebuild the merge plan +with: + +```sh +composer yii-config-rebuild +``` + +## Releasing packages + +Before tagging a release, test the package by itself and inside a minimal +Yii application. Include a `README.md`, `CHANGELOG.md`, and `UPGRADE.md` +when behavior or configuration changes require explanation. + +Use [semantic versioning](https://semver.org) for public releases. After the +first release, do not edit migrations that users may already have applied; +add new migrations instead. diff --git a/src/pt-BR/guide/structure/entry-script.md b/src/pt-BR/guide/structure/entry-script.md new file mode 100644 index 00000000..1d148a0f --- /dev/null +++ b/src/pt-BR/guide/structure/entry-script.md @@ -0,0 +1,116 @@ +# Entry scripts + +Entry scripts are the first step in the application bootstrapping +process. An application (either Web application or console application) has +a single entry script. End users make requests to entry scripts which +instantiate application instances and forward the requests to them. + +Entry scripts for Web applications must be stored under Web-accessible +directories so that they can be accessed by end users. They're often named +as `index.php`, but can also use any other names, provided Web servers can +locate them. + +Entry script for console application is `./yii`. + +Entry scripts mainly perform the following work with the help of +`ApplicationRunner`: + +* Register [Composer + autoloader](https://getcomposer.org/doc/01-basic-usage.md#autoloading); +* Obtain configuration; +* Use configuration to initialize a dependency injection container; +* Get an instance of the request. +* Pass it to `Application` to handle and get a response from it. +* With the help of an emitter that transforms a response object into an + actual HTTP response that's sent to the client browser. + +## Web Applications + +The following is the code in the entry script for the application template: + +```php +debug(); +// Run application: +$runner->run(); +``` + + +## Console Applications + +Similarly, the following is the code for the entry script of a console +application: + +```php +#!/usr/bin/env php +withDefinitions($config->get('console')) + ->withProviders($config->get('providers-console')); +$container = new Container($containerConfig); + +/** @var ContainerInterface $container */ +$container = $container->get(ContainerInterface::class); + +$application = $container->get(Application::class); +$exitCode = 1; + +try { + $application->start(); + $exitCode = $application->run(null, new ConsoleBufferedOutput()); +} catch (\Error $error) { + $application->renderThrowable($error, new ConsoleBufferedOutput()); +} finally { + $application->shutdown($exitCode); + exit($exitCode); +} +``` + +## Alternative runtimes + +For alternative runtimes such as FrankenPHP, Rapira, RoadRunner, or Swoole, +special entry scripts should be used. See: + +- [Using Yii with FrankenPHP](../tutorial/using-yii-with-frankenphp.md) +- [Using Yii with Rapira](../tutorial/using-yii-with-rapira.md) +- [Using Yii with RoadRunner](../tutorial/using-yii-with-roadrunner.md) +- [Using Yii with Swoole](../tutorial/using-yii-with-swoole.md) diff --git a/src/pt-BR/guide/structure/middleware.md b/src/pt-BR/guide/structure/middleware.md new file mode 100644 index 00000000..46fbc188 --- /dev/null +++ b/src/pt-BR/guide/structure/middleware.md @@ -0,0 +1,195 @@ +# Middleware + +Yii works with HTTP using the abstraction layer built around [PSR-7 HTTP +message interfaces](https://www.php-fig.org/psr/psr-7/) and [PSR-15 request +handler/middleware interfaces](https://www.php-fig.org/psr/psr-15/). + +The application is composed of one or several middleware. Middleware runs +between request and response. When the URL is requested, the request object +is passed to the middleware dispatcher that starts executing middleware one +after another. Each middleware, given the request, can: + +- Pass the request to the next middleware performing some work before / + after it. +- Form the response and return it. + +Depending on middleware used, application behavior may vary significantly. + +![Middleware](/images/guide/middleware.svg) + +In the above each next middleware wraps the previous +middleware. Alternatively, it could be presented as follows: + +![Middleware](/images/guide/middleware_alternative.svg) + +## Using middleware + +Any [PSR-15](https://www.php-fig.org/psr/psr-15/) compatible middleware +could be used with Yii, and there are many. Say, you need to add basic +authentication to one of the application URLs. URL-dependent middleware is +configured using router, so you need to change the router factory. + +Authentication middleware is implemented by +`middlewares/http-authentication` package so execute `composer require +middlewares/http-authentication` in the application root directory. + +Now register the middleware in DI container configuration `config/web.php`: + +```php + [ + 'class' => \Middlewares\BasicAuthentication::class, + '__construct()' => [ + 'users' => [ + 'foo' => 'bar', + ], + ], + 'realm()' => ['Access to the staging site via basic auth'], + 'attribute()' => ['username'], +], +``` + +In the `config/routes.php`, add new route: + +```php +action([SiteController::class, 'auth']) + ->name('site/auth') + ->prependMiddleware(BasicAuthentication::class) +]; +``` + +When configuring routing, you're binding `/basic-auth` URL to a chain of +middleware consisting of basic authentication, and the action itself. A +chain is a special middleware that executes all the middleware it's +configured with. + +The action itself could be the following: + +```php +public function auth(ServerRequestInterface $request): ResponseInterface +{ + $response = $this->responseFactory->createResponse(); + $response->getBody()->write('Hi ' . $request->getAttribute('username')); + return $response; +} +``` + +Basic authentication middleware wrote to request `username` attribute, so +you can access the data if needed. + +To apply middleware to application overall regardless of URL, adjust +`config/application.php`: + +```php +return [ + Yiisoft\Yii\Http\Application::class => [ + '__construct()' => [ + 'dispatcher' => DynamicReference::to(static function (Injector $injector) { + return ($injector->make(MiddlewareDispatcher::class)) + ->withMiddlewares( + [ + ErrorCatcher::class, + BasicAuthentication::class, + SessionMiddleware::class, + CsrfTokenMiddleware::class, + Router::class, + ] + ); + }), + 'fallbackHandler' => Reference::to(NotFoundHandler::class), + ], + ], +]; +``` + +## Creating your own middleware + +To create middleware, you need to implement a single `process` method of +`Psr\Http\Server\MiddlewareInterface`: + +```php +public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface; +``` + +There are multiple ways to handle a request, and choosing one depends on +what the middleware should achieve. + +### Forming a response directly + +To respond directly, one needs a response factory passed via constructor: + +```php +responseFactory->createResponse(); + $response->getBody()->write('Hello!'); + return $response; + } +} +``` + +### Delegating handling to the next middleware + +If middleware either isn't intended to form a response or change the request or can't do anything this time, +handling could be left to the next middleware in the stack: + +```php +public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface +{ + return $handler->handle($request); +} +``` + +In case you need to pass data to the next middleware, you can use request +attributes: + +```php +$request = $request->withAttribute('answer', 42); +return $handler->handle($request); +``` + +To get it in the next middleware: + +```php +$answer = $request->getAttribute('answer'); +``` + +### Capturing response to manipulate it + +You may want to capture the response to manipulate it. It could be useful +for adding CORS headers, gzipping content, etc. + +```php +$response = $handler->handle($request); +// extra handing +return $response; +``` diff --git a/src/pt-BR/guide/structure/module.md b/src/pt-BR/guide/structure/module.md new file mode 100644 index 00000000..6cb01de4 --- /dev/null +++ b/src/pt-BR/guide/structure/module.md @@ -0,0 +1,280 @@ +# Modules + +A module is an application part grouped around a business context or a +reusable feature. In Yii, this is a design boundary, not a required base +class. A module can be: + +- application code under the `App\` namespace; +- a [Composer package](package.md) installed into `vendor/`; +- code that starts in the application and is later extracted into a package. + +Use a module when a group of actions, domain services, repositories, event +handlers, views, assets, commands, and related configuration changes +together and has a name that makes sense to the business. + +For example, a blog module can live in an application as: + +``` +src/ + Blog/ + Post/ + Post.php + PostRepositoryInterface.php + InMemoryPostRepository.php + Web/ + IndexAction.php + index.php +``` + +The same structure can later become a Composer package by changing the +namespace and adding package metadata and configuration files. See +[Designing packages](designing-packages.md) for package-specific details. + +## Module boundaries + +Keep module code together by context first and by technical type +second. This is close to the [vertical +slices](../../cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md) +approach, but at a larger application-structure boundary. Prefer +`App\Blog\Post\PostRepositoryInterface` over a global +`App\Repository\PostRepositoryInterface` when the repository belongs to blog +posts only. + +Treat module classes as a public API only when another module is expected to +use them. Good public API classes are usually: + +- commands or queries that express a use case; +- DTOs or value objects passed between modules; +- interfaces for services another module may call; +- events emitted by the module. + +Keep implementation classes private to the module namespace. Other modules +should not depend on `App\Blog\Post\InMemoryPostRepository` or a controller +action directly. They should depend on an interface, a use case class, or an +event. + +## Interfaces between modules + +Put an interface where the contract belongs: + +- If the interface describes a capability provided by a module, place it in + that module. For example, `App\Blog\Post\PostRepositoryInterface` belongs + to the blog module because it describes how blog posts are read. +- If the interface describes what a module needs from the outside world, + place it in the consuming module. For example, + `App\Order\Customer\CustomerVerifierInterface` belongs to the order module + if orders only need a yes-or-no customer check. The customer module, an + application adapter, or a package can provide the implementation. + +This keeps dependencies explicit. A module can depend on another module's +public contract, but it should not reach into another module's internal +implementation classes. + +First, define the interface in the module: + +```php + + */ + public function findLatest(): array; +} +``` + +Put the implementation in the same module and bind the interface to it: + +```php + InMemoryPostRepository::class, +]; +``` + +In the default application template, put this file under +`config/common/di/`, for example `config/common/di/blog.php`. The template +loads `config/common/di/*.php` into the shared `di` configuration group, so +the binding is available to web and console entry points. + +## Web actions + +Actions belong to the module when they are the web entry point for module +behavior: + +```php +viewRenderer->render(__DIR__ . '/index', [ + 'posts' => $this->posts->findLatest(), + ]); + } +} +``` + +Keep request parsing and response creation in the action. Keep business +decisions in the module's domain classes or use case services. + +## Routes + +For a small application, add module routes directly to +`config/common/routes.php`: + +```php +routes( + Route::get('/') + ->action(Web\HomePage\Action::class) + ->name('home'), + ), + + Group::create('/blog') + ->routes( + Route::get('') + ->action(IndexAction::class) + ->name('blog/index'), + ), +]; +``` + +Use module-prefixed route names, such as `blog/index`, to avoid collisions. + +If the application has many modules, you can give each module its own route +config file. Change the `routes` group in `config/configuration.php`: + +```php +'routes' => [ + 'common/routes.php', + 'common/routes/*.php', +], +``` + +Then create `config/common/routes/blog.php`: + +```php +routes( + Route::get('') + ->action(IndexAction::class) + ->name('blog/index'), + ), +]; +``` + +After changing `config/configuration.php` or adding files matched by a +config wildcard, rebuild the merge plan: + +```sh +composer yii-config-rebuild +``` + +## Module configuration + +Application modules use the same configuration groups as packages. The +difference is where the configuration lives: + +- application module configuration lives in the root application under + `config/`; +- package module configuration lives in the package and is declared in + `extra.config-plugin`. + +Common locations for application module configuration are: + +``` +config/ + common/ + di/ + blog.php + routes/ + blog.php + params.php + console/ + params.php + web/ + params.php +``` + +Put shared service definitions in `common/di/`. Put web-only definitions in +`web/di/`. Put console-only parameters or command registrations in +`console/params.php`. + +When a module grows enough to become reusable, move its PHP classes to a +Composer package, move its configuration files to the package `config/` +directory, and declare them in the package `composer.json`: + +```json +{ + "extra": { + "config-plugin": { + "di": "config/di.php", + "routes": "config/routes.php" + } + } +} +``` + +The application can then override package defaults in its own config files. + +## Cross-module communication + +Choose the smallest coupling that supports the behavior: + +- Use constructor injection with an interface for a direct synchronous call. +- Use an event when the producer should not know who reacts to something + that happened. +- Use an application service or use case class when orchestration belongs + outside both modules. +- Use a package when the module must be reused by more than one application. + +Avoid service locator calls and global state inside module classes. Let +actions, commands, and services receive their dependencies through +constructors so module boundaries stay visible in code and testable in +isolation. diff --git a/src/pt-BR/guide/structure/overview.md b/src/pt-BR/guide/structure/overview.md new file mode 100644 index 00000000..3d8f5d9d --- /dev/null +++ b/src/pt-BR/guide/structure/overview.md @@ -0,0 +1,65 @@ +# Overview + +Yii applications code is typically grouped into modules by context. In each +module there could be grouping by type. + +For example, if the application is an online store, the context could be: + +- Customer + - Profile + - Products list + - Checkout +- Logistics +- Delivery + - Addresses +- Helpdesk + - Support + - Claims + - Returns +- Accounting + - Returns + - Transactions + - Taxes + +For a "Customer" context, residing under `App\Customer` namespace, structure +would be: + +``` +App/ + Customer/ <-- module namespace + Entity/ + Customer.php <-- entity shared by "Profile" and "Checkout" + Profile/ + Widget/ + Gravatar.php + ProfileRepository.php <-- repository is usually specific to context + ProfileController.php <-- "Customer\Profile" entry point + ProductList/ <-- module namespace + Entity/ <-- entities specific to "Customer\ProductList" + Category.php + Product.php + ProductsListController.php <-- "Customer\ProductList" entry point + Checkout/ <-- module namespace + CheckoutController.php +``` + +A context may include sub-contexts. If a class is shared by multiple +contexts, it's moved to the ancestor of both contexts. + +A context may have [an entry point known as "action" or +"controller"](action.md). Its job is to take [a request +instance](../runtime/request.md), pass it to [domain layer](domain.md) in a +suitable format, and create [a response](../runtime/response.md) based on +domain layer return. + +Besides, Yii applications also have the following: + +* [entry scripts](entry-script.md): they're PHP scripts that are directly + accessible by end users. They're responsible for starting a request + handling cycle. Typically, a single entry script is handling the whole + application. +* [services](service.md): they're typically stateless objects registered + within dependency container and provide various action methods. +* [middleware](middleware.md): they represent a code that needs to be + invoked before and after the actual handling of each request by action + handlers. diff --git a/src/pt-BR/guide/structure/package.md b/src/pt-BR/guide/structure/package.md new file mode 100644 index 00000000..18d14ee7 --- /dev/null +++ b/src/pt-BR/guide/structure/package.md @@ -0,0 +1,118 @@ +# Using packages + +Reusable code is distributed as [Composer +packages](https://getcomposer.org/doc/05-repositories.md#package). A +package can be an infrastructure library, a Yii integration, a reusable +feature, or a module representing an application context. + +This page explains how to use packages in an application. To create a +Yii-aware package, see [Designing packages for Yii +applications](designing-packages.md). + +## Installing packages + +By default, Composer installs packages registered on +[Packagist](https://packagist.org/), the main repository for open source PHP +packages. + +Install a package with: + +```sh +composer require vendor-name/package-name +``` + +Composer updates two files: + +- `composer.json` stores the package name and version constraint. +- `composer.lock` stores the exact versions installed. + +Commit both files so other environments install the same dependency +versions. + +Installed packages are stored in the application `vendor/` directory. + +> [!WARNING] +> Never edit files in `vendor/` directly. Change application configuration, extend classes, decorate services, or +> contribute fixes to the package instead. + +Package classes are available through Composer autoloading after +installation. See [Autoloading](../concept/autoloading.md) for details. + +## Updating packages + +Update a package within the version constraint recorded in `composer.json`: + +```sh +composer update vendor-name/package-name +``` + +Change the accepted version constraint with `composer require`: + +```sh +composer require vendor-name/package-name:^2.0 +``` + +After updating a Yii-aware package, Composer rebuilds Yii's configuration +merge plan. If you changed configuration group mappings manually, rebuild it +explicitly: + +```sh +composer yii-config-rebuild +``` + +## Removing packages + +Remove a package with: + +```sh +composer remove vendor-name/package-name +``` + +Then remove application code and configuration that referenced classes, +services, routes, commands, assets, migrations, or translations from that +package. + +## Private packages + +For private code, configure Composer repositories in the application +`composer.json`. Common options are: + +- `vcs` for a Git repository. +- `path` for a local package during development. +- `composer` for a private Composer repository. + +For example, to work with a package located next to the application: + +```json +{ + "repositories": [ + { + "type": "path", + "url": "../packages/blog" + } + ] +} +``` + +Then install it normally: + +```sh +composer require vendor/blog +``` + +Read more in the [Composer repository +documentation](https://getcomposer.org/doc/05-repositories.md). + +## Package configuration + +Some Yii packages provide default configuration through +[yiisoft/config](https://github.com/yiisoft/config). After installation, +the package configuration becomes part of the vendor layer and the +application can override it in the root package configuration. + +Prefer partial overrides in application config files over copying whole +package config files. For example, override only the parameter or service +definition you need. + +For more details, see [Configuration](../concept/configuration.md) and +[Designing packages for Yii applications](designing-packages.md). diff --git a/src/pt-BR/guide/testing/end-to-end.md b/src/pt-BR/guide/testing/end-to-end.md new file mode 100644 index 00000000..27b33973 --- /dev/null +++ b/src/pt-BR/guide/testing/end-to-end.md @@ -0,0 +1,131 @@ +# End-to-end tests + +The Yii application template uses the `Web` Codeception suite for tests that +go through an HTTP server. These tests live in `tests/Web` and use +`App\Tests\Support\WebTester`. + +Use web tests for user-visible HTTP behavior: pages, links, forms, +redirects, cookies, and error pages. + +## Web suite + +The template configures `tests/Web.suite.yml` like this: + +```yaml +actor: WebTester +extensions: + enabled: + - Codeception\Extension\RunProcess: + 0: composer serve + sleep: 3 +modules: + enabled: + - PhpBrowser: + url: http://127.0.0.1:8080 +``` + +`RunProcess` starts the application with the Composer `serve` +script. `PhpBrowser` sends HTTP requests to the server. + +## Test a page + +The template includes `tests/Web/HomePageCest.php`: + +```php +wantTo('home page works.'); + $I->amOnPage('/'); + $I->expectTo('see page home.'); + $I->see('Hello!'); + } +} +``` + +Run the web suite locally: + +```shell +APP_ENV=test vendor/bin/codecept run Web +``` + +Run only this test: + +```shell +APP_ENV=test vendor/bin/codecept run Web HomePageCest +``` + +With Docker: + +```shell +make test Web +``` + +## Test links and error pages + +Use the same actor methods for navigation and response assertions: + +```php +wantTo('see 404 page.'); + $I->amOnPage('/non-existent-page'); + $I->canSeeResponseCodeIs(404); + $I->see('404'); + $I->see('The page /non-existent-page not found.'); + } +} +``` + +## Smoke test with curl + +For a deployment smoke test, start the application and check one URL: + +```shell +APP_ENV=test ./yii serve --port=8080 +``` + +In another terminal: + +```shell +curl -fsS http://127.0.0.1:8080/ > /tmp/home.html +grep -q "Hello!" /tmp/home.html +``` + +## Reset state + +Web tests use real infrastructure, so reset state before each scenario: + +- Load only the records required by the scenario. +- Clear session and cookie storage. +- Clear generated files and outgoing messages. +- Stop background workers, or make their effects deterministic. + +If the scenario changes a database, reset it in the Cest `_before()` hook or +in a project-specific helper: + +```php +public function _before(WebTester $I): void +{ + // Reset database tables, files, queues, and outgoing messages. +} +``` diff --git a/src/pt-BR/guide/testing/environment-setup.md b/src/pt-BR/guide/testing/environment-setup.md new file mode 100644 index 00000000..d96e4e1e --- /dev/null +++ b/src/pt-BR/guide/testing/environment-setup.md @@ -0,0 +1,195 @@ +# Testing environment setup + +The Yii application template has the test environment configured. Use this +page when creating a new project from the template, restoring removed test +files, or adding a new suite. + +## Composer configuration + +The template requires Codeception, PHPUnit, and the modules used by the +suites: + +```json +{ + "require-dev": { + "codeception/codeception": "^5.3", + "codeception/module-asserts": "^3.2", + "codeception/module-cli": "^2.0", + "codeception/module-phpbrowser": "^3.0", + "phpunit/phpunit": "^11.5" + }, + "autoload-dev": { + "psr-4": { + "App\\Tests\\": "tests" + } + }, + "scripts": { + "test": "codecept run" + } +} +``` + +If these entries are already in your project, keep the installed versions +from `composer.lock`. + +## Main Codeception file + +The root `codeception.yml` defines the test namespace, paths, bootstrap +file, and coverage source: + +```yaml +namespace: App\Tests +support_namespace: Support +bootstrap: bootstrap.php + +settings: + shuffle: true + colors: true + +paths: + tests: tests + output: tests/_output + data: tests/Support/Data + support: tests/Support + +coverage: + enabled: true + show_uncovered: true + show_only_summary: true + include: + - src/* + - public/index.php + - yii + +extensions: + enabled: + - Codeception\Extension\RunFailed +``` + +`tests/bootstrap.php` prepares the application environment for every suite: + +```php +runAndGetResponse($request); + $body = $response->getBody(); + if ($body->isSeekable()) { + $body->rewind(); + } + + return $response; + } +} +``` + +## Test a page + +The template includes `tests/Functional/HomePageCest.php`: + +```php +sendRequest( + new ServerRequest(uri: '/'), + ); + + assertSame(200, $response->getStatusCode()); + assertStringContainsString( + 'Don\'t forget to check the guide', + $response->getBody()->getContents(), + ); + } +} +``` + +Run it: + +```shell +APP_ENV=test vendor/bin/codecept run Functional +APP_ENV=test vendor/bin/codecept run Functional HomePageCest +``` + +## Send request data + +Use PSR-7 methods to model the request: + +```php +$request = (new ServerRequest(uri: '/contact', method: 'POST')) + ->withHeader('Content-Type', 'application/x-www-form-urlencoded') + ->withParsedBody([ + 'ContactForm' => [ + 'name' => 'Sam', + 'email' => 'sam@example.test', + 'body' => 'Hello.', + ], + ]); + +$response = $tester->sendRequest($request); + +assertSame(302, $response->getStatusCode()); +assertSame('/contact/sent', $response->getHeaderLine('Location')); +``` + +For JSON APIs, write the JSON body into a PSR-7 stream and set +`Content-Type: application/json`. + +## Reset state + +Functional tests often touch runtime files, sessions, cache, and a +database. Reset changed state in the Cest `_before()` hook or in a project +helper: + +```php +public function _before(FunctionalTester $tester): void +{ + // Reset database tables, cache pools, queues, and outgoing messages. +} +``` + +Keep pure domain rules in unit tests. Put request and response behavior in +functional tests. diff --git a/src/pt-BR/guide/testing/overview.md b/src/pt-BR/guide/testing/overview.md new file mode 100644 index 00000000..88990cff --- /dev/null +++ b/src/pt-BR/guide/testing/overview.md @@ -0,0 +1,99 @@ +# Testes + +The Yii application template includes a ready test setup. It uses +Codeception with PHPUnit assertions and has four suites: + +- `Unit` for isolated PHP classes. +- `Functional` for application code called in the same PHP process. +- `Web` for requests sent through an HTTP server. +- `Console` for console commands. + +The main files are: + +- `codeception.yml`. +- `tests/bootstrap.php`. +- `tests/Unit.suite.yml`. +- `tests/Functional.suite.yml`. +- `tests/Web.suite.yml`. +- `tests/Console.suite.yml`. +- `tests/Support/*Tester.php`. + +## Run tests locally + +Build actor classes after installing dependencies or changing a suite: + +```shell +vendor/bin/codecept build +``` + +Run all tests: + +```shell +APP_ENV=test vendor/bin/codecept run +``` + +The template also defines a Composer script: + +```shell +APP_ENV=test composer test +``` + +Run one suite: + +```shell +APP_ENV=test vendor/bin/codecept run Unit +APP_ENV=test vendor/bin/codecept run Functional +APP_ENV=test vendor/bin/codecept run Web +APP_ENV=test vendor/bin/codecept run Console +``` + +Run one test class or method: + +```shell +APP_ENV=test vendor/bin/codecept run Functional HomePageCest +APP_ENV=test vendor/bin/codecept run Functional HomePageCest:base +``` + +`APP_ENV=test` is required for local commands because `tests/bootstrap.php` +prepares the application environment before tests run. + +## Run tests in Docker + +Build actor classes: + +```shell +make codecept build +``` + +Run all tests: + +```shell +make test +``` + +Run one suite: + +```shell +make test Unit +make test Functional +make test Web +make test Console +``` + +The Docker test environment reads `docker/test/.env`, where `APP_ENV=test` +is already set. + +## Choose a suite + +Start with unit tests for code that has no framework boundary: value +objects, validators, domain services, and transformers. + +Use functional tests when code needs Yii configuration, dependency +injection, routing, middleware, request handling, or template rendering. + +Use web tests for behavior that must go through an HTTP server: status +codes, links, redirects, cookies, and rendered pages as seen by a client. + +Use console tests for commands in `src/Console`. + +Run static analysis in CI and before changing shared contracts. diff --git a/src/pt-BR/guide/testing/quality-tools.md b/src/pt-BR/guide/testing/quality-tools.md new file mode 100644 index 00000000..b6882172 --- /dev/null +++ b/src/pt-BR/guide/testing/quality-tools.md @@ -0,0 +1,110 @@ +# Static analysis and code quality + +The Yii application template includes static analysis and code quality tools +alongside the test suite. + +## Psalm + +Run Psalm locally: + +```shell +vendor/bin/psalm +``` + +Run Psalm in Docker: + +```shell +make psalm +``` + +The template stores Psalm configuration in `psalm.xml`. The GitHub Actions +workflow runs Psalm for supported PHP versions. + +When Psalm reports an issue, fix the code or add a precise type +annotation. Keep suppressions narrow and local to the line or method that +needs them. + +## Composer Dependency Analyser + +Composer Dependency Analyser checks that `composer.json` matches the classes +used by the application. + +Run it locally: + +```shell +vendor/bin/composer-dependency-analyser --config=composer-dependency-analyser.php +``` + +Run it in Docker: + +```shell +make composer-dependency-analyser +``` + +Use this check after adding or removing package usage in `src`, `config`, or +`tests`. + +## PHP CS Fixer + +PHP CS Fixer applies the project coding style from `.php-cs-fixer.php`. + +Run it locally: + +```shell +vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.php --diff +``` + +Run it in Docker: + +```shell +make cs-fix +``` + +Commit formatting changes together with the code that needs them. + +## Rector + +Rector applies configured code upgrades and refactorings from `rector.php`. + +Preview changes locally: + +```shell +vendor/bin/rector --dry-run +``` + +Apply changes locally: + +```shell +vendor/bin/rector +``` + +Run it in Docker: + +```shell +make rector +``` + +Review Rector changes before committing them. Automated refactoring can +change behavior when custom rules or broad paths are configured. + +## Pull request checks + +A practical local check before opening a pull request is: + +```shell +APP_ENV=test vendor/bin/codecept build +APP_ENV=test vendor/bin/codecept run +vendor/bin/psalm +vendor/bin/composer-dependency-analyser --config=composer-dependency-analyser.php +vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.php --diff +``` + +With Docker: + +```shell +make codecept build +make test +make psalm +make composer-dependency-analyser +make cs-fix +``` diff --git a/src/pt-BR/guide/testing/unit.md b/src/pt-BR/guide/testing/unit.md new file mode 100644 index 00000000..7c0b2bcb --- /dev/null +++ b/src/pt-BR/guide/testing/unit.md @@ -0,0 +1,213 @@ +# Unit tests + +Unit tests check a small piece of PHP code directly. In the Yii application +template they live in `tests/Unit` and run through the `Unit` Codeception +suite. + +The template includes `tests/Unit/EnvironmentTest.php`: + +```php +generate('Hello, Yii3!'); + + assertSame('hello-yii3', $slug); + } +} +``` + +Run it: + +```shell +APP_ENV=test vendor/bin/codecept run Unit SlugGeneratorTest +``` + +## Test services with dependencies + +Pass dependencies through the constructor and use test doubles for I/O. + +Create `src/Clock/ClockInterface.php`: + +```php +clock->now()); + } +} +``` + +Create `tests/Unit/PublishPostTest.php`: + +```php +publish('Testing Yii'); + + assertSame('Testing Yii', $post->title); + assertSame('2026-05-07 10:00:00', $post->publishedAt->format('Y-m-d H:i:s')); + } +} +``` + +Run it: + +```shell +APP_ENV=test vendor/bin/codecept run Unit PublishPostTest +``` + +Keep unit tests focused on one class or one small collaboration. Use +functional tests when the behavior depends on Yii configuration, dependency +injection, routing, or middleware. diff --git a/src/pt-BR/guide/tutorial/console-applications.md b/src/pt-BR/guide/tutorial/console-applications.md new file mode 100644 index 00000000..3787eaef --- /dev/null +++ b/src/pt-BR/guide/tutorial/console-applications.md @@ -0,0 +1,93 @@ +# Console applications + +Console applications are mainly used to create utility, background +processing and maintenance tasks. + +## Primeiros passos + +If you're using [yiisoft/app](https://github.com/yiisoft/app) or +[yiisoft/app-api](https://github.com/yiisoft/app-api), console support is +already included. You can access the entry point as: + +``` +./yii +``` + +If you want a standalone console-only application, use the +[yiisoft/app-console](https://github.com/yiisoft/app-console) project +template: + +```sh +composer create-project yiisoft/app-console your-project +``` + +To add console support to an existing project from scratch, refer to the +[yiisoft/yii-console package +documentation](https://github.com/yiisoft/yii-console). + +Out of the box only `serve` command is available. It's starting PHP built-in +web server to serve the application locally. + +Commands are executed with `symfony/console`. To create your own console +command, you need to define a command: + +```php +setHelp('This command serves for demo purpose') + ->addArgument('name', InputArgument::OPTIONAL, 'Name to greet', 'anonymous'); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $io = new SymfonyStyle($input, $output); + + $name = $input->getArgument('name'); + $io->success("Hello, $name!"); + return ExitCode::OK; + } +} +``` + +Now register the command in `config/params.php`: + +```php +return [ + 'yiisoft/yii-console' => [ + 'commands' => [ + 'demo:hello' => App\Demo\HelloCommand::class, + ], + ], +]; +``` + +After it's done, the command could be executed as + +``` +./yii demo:hello Alice +``` + + +## References + +- [Symfony Console component + guide](https://symfony.com/doc/current/components/console.html) diff --git a/src/pt-BR/guide/tutorial/docker.md b/src/pt-BR/guide/tutorial/docker.md new file mode 100644 index 00000000..006afc75 --- /dev/null +++ b/src/pt-BR/guide/tutorial/docker.md @@ -0,0 +1,456 @@ +# Docker in Application Templates + +Both [yiisoft/app](https://github.com/yiisoft/app) and +[yiisoft/app-api](https://github.com/yiisoft/app-api) come with a +ready-to-use Docker setup based on [FrankenPHP](https://frankenphp.dev/) +with Caddy as the built-in web server. The setup covers local development, +testing, and production deployment through a set of environment files, +Docker Compose configurations, a multi-stage Dockerfile, and a `Makefile` +that wraps common operations. + +## Docker directory overview + +All Docker-related files live under the `docker/` directory: + +``` +docker/ +├── .env # Compose-level variables (stack name, ports, image names) +├── Dockerfile # Multi-stage image definition +├── compose.yml # Base Compose file (shared anchor for all environments) +├── dev/ +│ ├── .env # Application environment variables for development +│ ├── .gitignore # Excludes override.env from version control +│ ├── compose.yml # Development-specific Compose overrides +│ └── override.env.example # Optional developer-local overrides template +├── test/ +│ ├── .env # Application environment variables for testing +│ ├── .gitignore # Excludes override.env from version control +│ └── compose.yml # Test-specific Compose overrides +└── prod/ + ├── .env # Application environment variables for production + ├── .gitignore # Excludes override.env from version control + └── compose.yml # Production-specific Compose overrides (Docker Swarm) +``` + +Each subdirectory (`dev/`, `test/`, `prod/`) corresponds to an environment +stage and contains its own `.env` file with application-level configuration +and a `compose.yml` that extends the base `docker/compose.yml`. + +## Environment files + +The templates use two separate environment systems that serve different +purposes and different runtimes. + +### .env.example (project root) + +The project root contains a `.env.example` file that serves as a template +for local development **without Docker**: + +```ini +# Local environment configuration. +# Copy this file to .env and adjust as needed. +# In production, set environment variables via server or container configuration instead. +APP_ENV=dev +APP_DEBUG=true +``` + +Copy it to create your local configuration file: + +```sh +cp .env.example .env +``` + +The `.env` file is loaded automatically by `src/bootstrap.php` using +[phpdotenv](https://github.com/vlucas/phpdotenv) only when `APP_ENV` is not +already present in the process environment. This means **Docker-provided +environment variables always take precedence** over the root `.env` file — +both workflows can coexist safely in the same project directory. + +> [!NOTE] +> `phpdotenv` is a development dependency and is not installed in production +> (`composer install --no-dev`), so the root `.env` file has no effect on production containers. + +### docker/.env + +This file contains variables used by the Compose files themselves — they are +**not** passed into the running application container: + +```ini +# Variables for compose.yml files. Not available in the app. + +STACK_NAME=app + +# Development + +DEV_PORT=80 + +# Production + +PROD_HOST=app.example.com +PROD_SSH="ssh://docker-web" + +IMAGE=app +IMAGE_TAG=latest +``` + +| Variable | Purpose | +|--------------|-------------------------------------------------------------------------| +| `STACK_NAME` | Docker Compose project name and Docker Swarm stack name. | +| `DEV_PORT` | Host port to expose the application on in development (`make up`). | +| `PROD_HOST` | Hostname used by Caddy labels for automatic HTTPS in production. | +| `PROD_SSH` | Remote Docker host for deploying to a Swarm node via SSH. | +| `IMAGE` | Docker image name used during build and push. | +| `IMAGE_TAG` | Docker image tag (`latest` by default; use a version string in CI/CD). | + +### docker/dev/.env + +Contains application environment variables injected into the development +container at runtime: + +```ini +# App dev environment. +# Note that variables are available in the app only, not in compose.yml. + +APP_ENV=dev +APP_DEBUG=true +SERVER_NAME=:80 +XDEBUG_MODE=develop +COMPOSER_CACHE_DIR=/app/runtime/cache/composer +``` + +| Variable | Purpose | +|-----------------------|--------------------------------------------------------------------------------------| +| `APP_ENV` | Application environment. `dev` enables developer-friendly behavior. | +| `APP_DEBUG` | Enables detailed error output and debug panels. | +| `SERVER_NAME` | Caddy server address — `:80` means listen on all interfaces on port 80. | +| `XDEBUG_MODE` | Xdebug mode. Use `develop` for helpers and `debug` to enable step debugging. | +| `COMPOSER_CACHE_DIR` | Moves Composer's cache into the mounted volume so it persists between runs. | + +### docker/test/.env + +Contains application environment variables for the test container: + +```ini +# App test environment. +# Note that variables are available in the app only, not in compose.yml. + +APP_ENV=test +APP_DEBUG=false +APP_C3=true +SERVER_NAME=:80 +XDEBUG_MODE=coverage +COMPOSER_CACHE_DIR=/app/runtime/cache/composer +``` + +| Variable | Purpose | +|----------------------|-----------------------------------------------------------------------------------------------| +| `APP_ENV` | Sets the environment to `test` so the application loads test-specific configuration. | +| `APP_DEBUG` | Disabled in tests to match a realistic execution context. | +| `APP_C3` | Enables [c3](https://github.com/Codeception/c3) remote code coverage collection. | +| `SERVER_NAME` | Caddy server address. | +| `XDEBUG_MODE` | `coverage` activates Xdebug's code coverage driver required for coverage reports. | +| `COMPOSER_CACHE_DIR` | Persistent Composer cache inside the volume. | + +### docker/prod/.env + +Contains application environment variables for the production container: + +```ini +# App prod environment. +# Note that variables are available in the app only, not in compose.yml. + +APP_ENV=prod +APP_DEBUG=false +SERVER_NAME=:80 +``` + +The production environment intentionally uses a minimal +configuration. Secrets and host-specific overrides should be managed through +deployment tooling and never committed to version control. + +### Override env files + +Each environment directory contains a `.gitignore` that excludes an +`override.env` file. This file is optional and, when present, is merged on +top of the main `.env` for that environment: + +``` +# docker/dev/override.env.example +APP_HOST_PATH=/projects/yiisoft/app +``` + +Copy the example file to create your local overrides: + +```sh +cp docker/dev/override.env.example docker/dev/override.env +``` + +Use override files for developer-specific settings such as Xdebug IDE keys +or local bind paths that should not be shared with the team. + +## Compose files + +The Compose configuration is split across multiple files that Docker Compose +merges at runtime. This approach avoids duplicating shared settings and +keeps each environment's file focused and small. + +### docker/compose.yml (base) + +The base file defines shared settings inherited by all environments: + +```yaml +services: + app: &appconfig + extra_hosts: + - "host.docker.internal:host-gateway" + +volumes: + caddy_data: + caddy_config: +``` + +The `&appconfig` YAML anchor lets environment files reference and extend +this service definition. The `host.docker.internal` entry maps to the +Docker host so containers can reach services running on the host machine +(for example, a local database). + +The two named volumes (`caddy_data` and `caddy_config`) persist Caddy's +certificate storage and configuration across container restarts. + +### docker/dev/compose.yml + +Extends the base file for local development: + +```yaml +services: + app: + build: + dockerfile: docker/Dockerfile + context: .. + target: dev + args: + USER_ID: ${UID} + GROUP_ID: ${GID} + env_file: + - path: ./dev/.env + - path: ./dev/override.env + required: false + ports: + - "${DEV_PORT:-80}:80" + volumes: + - ../:/app + - ../runtime:/app/runtime + - caddy_data:/data + - caddy_config:/config + tty: true +``` + +Key points: + +- **`target: dev`** — Selects the `dev` stage from the multi-stage + Dockerfile. +- **`USER_ID` / `GROUP_ID`** — Passed as build arguments so the container + user matches the host user, preventing file permission issues on Linux. +- **`env_file`** — Loads `docker/dev/.env` and, optionally, the developer's + local `override.env`. +- **`ports`** — Exposes port 80 (or `DEV_PORT` from `docker/.env`) on the + host. +- **`volumes`** — Mounts the entire project into `/app` so code changes are + reflected immediately without rebuilding the image. + +### docker/test/compose.yml + +Identical in structure to the dev file but loads `docker/test/.env` and does +not expose ports to the host, since tests run entirely inside the container +network. + +### docker/prod/compose.yml + +Targets production deployments using Docker Swarm: + +```yaml +services: + app: + image: ${IMAGE}:${IMAGE_TAG} + networks: + - caddy_public + volumes: + - runtime:/app/runtime + - caddy_data:/data + - caddy_config:/config + env_file: + - path: ./prod/.env + - path: ./prod/override.env + required: false + deploy: + replicas: 2 + update_config: + delay: 10s + parallelism: 1 + order: start-first + failure_action: rollback + monitor: 10s + rollback_config: + parallelism: 0 + order: stop-first + restart_policy: + condition: on-failure + delay: 5s + max_attempts: 3 + window: 120s + labels: + caddy: ${PROD_HOST:-app.example.com} + caddy.reverse_proxy: "{{upstreams 80}}" + +volumes: + runtime: + +networks: + caddy_public: + external: true +``` + +Instead of building an image, the production file references a pre-built +image (`${IMAGE}:${IMAGE_TAG}`). The `deploy` block configures Docker Swarm +behaviour: two replicas with a rolling `start-first` update strategy and +automatic rollback on failure. The `caddy` labels are picked up by a [Caddy +Docker Proxy](https://github.com/lucaslorentz/caddy-docker-proxy) running in +the same Swarm to configure automatic HTTPS routing. + +> [!NOTE] +> The `caddy_public` network must already exist on the Swarm before deploying. +> See the [Docker Swarm deployment guide](../../cookbook/deployment/docker-swarm.md) for full setup instructions. + +## Multi-stage Dockerfile + +The `docker/Dockerfile` uses [multi-stage +builds](https://docs.docker.com/build/building/multi-stage/) to produce lean +images for each purpose from a single file, avoiding duplication of the base +setup: + +```dockerfile +FROM composer/composer:2-bin AS composer + +FROM dunglas/frankenphp:1-php8.2-bookworm AS base + +RUN apt update && apt -y install \ + unzip + +RUN install-php-extensions \ + opcache mbstring intl dom ctype curl phar openssl xml xmlwriter simplexml pdo + +ENV LC_ALL=C.UTF-8 + +# +# Development +# + +FROM base AS dev +ARG USER_ID=10001 +ARG GROUP_ID=10001 +ARG USER_NAME=appuser +ARG GROUP_NAME=appuser + +RUN install-php-extensions xdebug + +COPY --from=composer /composer /usr/bin/composer + +RUN \ + groupadd --gid ${GROUP_ID} ${GROUP_NAME}; \ + useradd --gid ${GROUP_ID} --uid ${USER_ID} ${GROUP_NAME}; \ + setcap CAP_NET_BIND_SERVICE=+eip /usr/local/bin/frankenphp; \ + chown -R ${USER_NAME}:${GROUP_NAME} /data/caddy && \ + chown -R ${USER_NAME}:${GROUP_NAME} /config/caddy +USER ${USER_NAME} + +# +# Production +# + +FROM base AS prod-builder +COPY --from=composer /composer /usr/bin/composer +COPY .. /app +RUN --mount=type=cache,target=/tmp/cache \ + composer install --no-dev --no-progress --no-interaction --classmap-authoritative && \ + rm composer.lock composer.json + +FROM base AS prod +ENV APP_ENV=prod +COPY --from=prod-builder --chown=www-data:www-data /app /app +USER www-data +``` + +The Dockerfile defines four stages: + +| Stage | Purpose | +|----------------|--------------------------------------------------------------------------------------------------| +| `composer` | Copies the Composer binary from the official image to avoid installing it in other stages. | +| `base` | Installs FrankenPHP, common PHP extensions, and system packages shared by all environments. | +| `dev` | Extends `base` with Xdebug and Composer. Creates a non-root user matching the host user's UID/GID to prevent permission issues with mounted volumes. | +| `prod-builder` | Extends `base`, copies the application source, and runs `composer install --no-dev` using a build cache. Removes `composer.lock` and `composer.json` afterwards to keep the final image clean. | +| `prod` | Copies only the built application from `prod-builder` into a clean `base` image. This produces a small final image because the Composer binary and intermediate files are not included. | + +> [!TIP] +> When building the production image you select a specific stage with `--target prod`. The `prod-builder` +> stage is an intermediate step and is never pushed to a registry. + +The `dev` target is selected when running `make up` or `make build`, while +`make prod-build` targets `prod`. + +## make commands + +The `Makefile` provides a convenient interface for all common Docker +operations. Run `make` or `make help` to list available targets with their +descriptions. + +### Development + +| Command | Description | +|---------------|----------------------------------------------------------------| +| `make build` | Build (or rebuild) the development Docker image. | +| `make up` | Start the development environment in detached mode. | +| `make down` | Stop and remove containers, networks, and orphaned services. | +| `make stop` | Stop running containers without removing them. | +| `make clear` | Remove all development containers, networks, and volumes. | +| `make shell` | Open an interactive Bash shell inside the running `app` container. | + +### Running tools + +Commands in this group run inside the development container using `docker +compose run --rm`, so they work even when the container is not currently +running: + +| Command | Description | +|--------------------------------------|-------------------------------------------------| +| `make yii ` | Run a `./yii` console command. | +| `make composer ` | Run Composer. | +| `make rector` | Run [Rector](https://getrector.com/) for automated PHP refactoring and code quality improvements. | +| `make cs-fix` | Run [PHP CS Fixer](https://cs.symfony.com/). | +| `make psalm` | Run [Psalm](https://psalm.dev/) static analysis. | +| `make composer-dependency-analyser` | Run [Composer Dependency Analyser](https://github.com/shipmonk-rnd/composer-dependency-analyser). | + +### Testes + +| Command | Description | +|------------------------|-----------------------------------------------------------| +| `make test` | Run the full test suite with Codeception. | +| `make test-coverage` | Run tests and generate an HTML coverage report. | +| `make codecept ` | Run any Codeception command with custom arguments. | + +### Production + +| Command | Description | +|----------------------|-------------------------------------------------------------------------------------| +| `make prod-build` | Build the production Docker image locally (`--target prod`). | +| `make prod-push` | Push the built image to the registry defined by `IMAGE` and `IMAGE_TAG`. | +| `make prod-deploy` | Deploy the stack to a remote Docker Swarm node defined by `PROD_SSH`. | + +> [!TIP] +> Most commands accept additional arguments. For example, to install a specific package: +> ```sh +> make composer require yiisoft/yii-db-mysql +> ``` +> To run a single test suite: +> ```sh +> make test -- Unit +> ``` diff --git a/src/pt-BR/guide/tutorial/i18n.md b/src/pt-BR/guide/tutorial/i18n.md new file mode 100644 index 00000000..9d7b4cff --- /dev/null +++ b/src/pt-BR/guide/tutorial/i18n.md @@ -0,0 +1,449 @@ +# Internationalization + +Internationalization prepares an application for more than one +locale. Localization is the locale-specific part: translated text, plural +forms, date and number formats, and view templates for a locale such as +`en-US` or `de`. + +In a Yii application, the usual parts are: + +- locale selection for the current request; +- translated application messages; +- plural and parameter formatting; +- localized view templates for pages that need different markup. + +This tutorial assumes a new [yiisoft/app](https://github.com/yiisoft/app) +project. + +## Install packages + +`yiisoft/app` already includes `yiisoft/i18n` and `yiisoft/translator`. +Install PHP-file message storage: + +```sh +composer require yiisoft/translator-message-php +``` + +Install the extractor as a development dependency: + +```sh +composer require --dev yiisoft/translator-extractor +``` + +The examples use ICU message formatting for plural forms. Make sure the PHP +`intl` extension is enabled. For simple placeholders only, use +`Yiisoft\Translator\SimpleMessageFormatter` in the configuration below. + +## Configure application locale + +The application template keeps basic application settings in +`config/common/application.php`. Set the source locale there: + +```php + 'UTF-8', + 'locale' => 'en-US', + 'name' => 'My Project', +]; +``` + +The default layout uses this value in the `` attribute through `ApplicationParams`. +When your application chooses locale per request, set the selected locale on the view as shown in +[Choosing locale per request](#choosing-locale-per-request). + +Configure translator defaults in `config/common/params.php`: + +```php +'yiisoft/translator' => [ + 'locale' => 'en-US', + 'fallbackLocale' => 'en-US', + 'defaultCategory' => 'app', +], +``` + +`locale` is the default translation locale. `fallbackLocale` is used when a +translation is missing for the current locale. `defaultCategory` is the +category used when a call to `translate()` does not specify one. + +## Configure message storage + +Create `config/common/di/translator.php`: + +```php + [ + 'definition' => static function (Aliases $aliases) use ($params): CategorySource { + $messageSource = new MessageSource($aliases->get('@root/messages')); + + return new CategorySource( + $params['yiisoft/translator']['defaultCategory'], + $messageSource, + new IntlMessageFormatter(), + $messageSource, + ); + }, + 'tags' => ['translation.categorySource'], + ], +]; +``` + +This registers the `app` category. The `MessageSource` reads PHP arrays from +the `messages/` directory and writes extracted messages back to the same +directory. + +Create the source and target message files: + +``` +messages/ +├── de/ +│ └── app.php +└── en-US/ + └── app.php +``` + +`messages/en-US/app.php`: + +```php + 'Home', + 'home.welcome' => 'Welcome to Yii3', + 'cart.items' => '{count, plural, =0{No items} one{# item} other{# items}}', +]; +``` + +`messages/de/app.php`: + +```php + 'Home', + 'home.welcome' => 'Willkommen bei Yii3', + 'cart.items' => '{count, plural, =0{Keine Artikel} one{# Artikel} other{# Artikel}}', +]; +``` + +## Translate messages + +Inject `Yiisoft\Translator\TranslatorInterface` where you prepare data for a +response. For the default home page action, update +`src/Web/HomePage/Action.php`: + +```php +viewRenderer->render(__DIR__ . '/template', [ + 'itemCount' => 3, + 'translator' => $this->translator, + ]); + } +} +``` + +Use the translator in `src/Web/HomePage/template.php`: + +```php +setTitle($translator->translate('home.title')); +?> + +
+

translate('home.welcome')) ?>

+ +

translate('cart.items', ['count' => $itemCount])) ?>

+
+``` + +Escape translated text before output. Store trusted HTML separately or +render it from a view template. + +## Choosing locale per request + +For a web application, choose locale early in the middleware stack and apply +it to both the translator and the view. The example below uses the `lang` +query parameter and a fixed allow list: + +```php +getLocale($request); + + $this->translator->setLocale($locale); + $this->view->setLocale($locale); + + return $handler->handle($request); + } + + private function getLocale(ServerRequestInterface $request): string + { + $locale = $request->getQueryParams()['lang'] ?? null; + + return is_string($locale) && in_array($locale, self::SUPPORTED_LOCALES, true) + ? $locale + : self::DEFAULT_LOCALE; + } +} +``` + +Register the middleware in `config/common/routes.php` or in the route group +that needs localized output. Add middleware before the route action: + +```php +use App\Web\Middleware\LocaleMiddleware; +use Yiisoft\Router\Route; + +return [ + Route::get('/') + ->middleware(LocaleMiddleware::class) + ->action(App\Web\HomePage\Action::class) + ->name('home'), +]; +``` + +Update `src/Web/Shared/Layout/Main/layout.php` to read the locale from the +current view state: + +```php + +``` + +Use the same approach when locale is stored in a session, a cookie, a user +profile, or a route parameter. + +`yiisoft/i18n` provides `Yiisoft\I18n\Locale` for working with BCP 47 locale +codes: + +```php +use Yiisoft\I18n\Locale; + +$locale = new Locale('de-DE'); + +echo $locale->language(); // de +echo $locale->region(); // DE +echo $locale->fallbackLocale()->asString(); // de +``` + +This is useful when you need to derive a language fallback or inspect locale +parts before choosing a supported locale. + +## Localized view files + +Use message translation for labels, headings, buttons, validation messages, +and short paragraphs. Use localized view files when a page needs different +markup or a different amount of text for each locale. + +`yiisoft/view` looks for localized files in a locale subdirectory next to +the original view file. For example, when `src/Web/HomePage/template.php` is +rendered with locale `de-DE`, Yii checks: + +1. `src/Web/HomePage/de-DE/template.php` +2. `src/Web/HomePage/de/template.php` +3. `src/Web/HomePage/template.php` + +The fallback to the two-letter language code is automatic. + +You can set the locale for a single render call: + +```php +return $this->viewRenderer + ->withLocale('de-DE') + ->render(__DIR__ . '/template'); +``` + +When the locale is set on `WebView` in middleware, the same locale is +applied to views rendered by `WebViewRenderer`. + +## Extract messages + +Configure the extractor so it can read existing messages and write new IDs +to the same message storage. + +Create `config/common/di/translator-extractor.php`: + +```php + [ + '__construct()' => [ + [ + DynamicReference::to([ + 'class' => ExtractorCategorySource::class, + '__construct()' => [ + $params['yiisoft/translator']['defaultCategory'], + DynamicReference::to( + static fn (Aliases $aliases): MessageSource => new MessageSource($aliases->get('@root/messages')), + ), + DynamicReference::to( + static fn (Aliases $aliases): MessageSource => new MessageSource($aliases->get('@root/messages')), + ), + ], + ]), + ], + ], + ], +]; +``` + +Rebuild config after adding the extractor configuration file: + +```sh +composer yii-config-rebuild +``` + +Extract messages from application source files: + +```sh +./yii translator/extract src --languages=en-US,de +``` + +The command scans calls such as: + +```php +$translator->translate('home.welcome'); +$translator->translate('cart.items', ['count' => $itemCount]); +``` + +It writes missing IDs to: + +``` +messages/en-US/app.php +messages/de/app.php +``` + +After extraction, edit target language files and replace source IDs with +translated text. + +Use `--category` when a call belongs to another category: + +```sh +./yii translator/extract src --languages=en-US,de --category=shop +``` + +The extractor excludes `vendor/` by default. Use `--only` or `--except` when +you need a narrower scan: + +```sh +./yii translator/extract src --languages=en-US,de --only=**/*.php --except=**/runtime/** +``` + +## Working with categories + +The default `app` category is enough for most application messages. Add +categories when a package or a large feature owns its own message files. + +For a `shop` category, create another tagged category source: + +```php +'translation.shop' => [ + 'definition' => static function (Aliases $aliases): CategorySource { + $messageSource = new MessageSource($aliases->get('@root/messages')); + + return new CategorySource( + 'shop', + $messageSource, + new IntlMessageFormatter(), + $messageSource, + ); + }, + 'tags' => ['translation.categorySource'], +], +``` + +Translate with the category name: + +```php +$translator->translate('checkout.submit', category: 'shop'); +``` + +The message files are stored as: + +``` +messages/de/shop.php +messages/en-US/shop.php +``` + +Keep message IDs stable. Changing an ID creates a new translation task for +every locale. diff --git a/src/pt-BR/guide/tutorial/mailing.md b/src/pt-BR/guide/tutorial/mailing.md new file mode 100644 index 00000000..e5833e5d --- /dev/null +++ b/src/pt-BR/guide/tutorial/mailing.md @@ -0,0 +1,329 @@ +# Mailing + +Yii simplifies the composition and sending of email messages using the +[yiisoft/mailer](https://github.com/yiisoft/mailer) package. This package +provides content composition functionality and a basic interface for sending +emails. By default, the package includes a file mailer that writes email +contents into a file instead of sending them. This is particularly useful +during the initial stages of application development. + +To send actual emails, you can use the [Symfony +Mailer](https://github.com/yiisoft/mailer-symfony) implementation, which is +used in the examples below. + +## Configuring the Mailer + +The mailer service allows you to create a message instance, populate it with +data, and send it. Typically, you get an instance from the DI container as +`Yiisoft\Mailer\MailerInterface`. + +You can also create an instance manually as follows: + +```php + +use Yiisoft\Mailer\Symfony\Mailer; + +/** + * @var \Symfony\Component\Mailer\Transport\TransportInterface $transport + */ + +$mailer = new \Yiisoft\Mailer\Symfony\Mailer( + $transport, +); +``` + +The `Yiisoft\Mailer\MailerInterface` provides two main methods: + +- `send()` - Sends the given email message. +- `sendMultiple()` - Sends many messages at once. + +## Creating a Message + +### Simple Text Message + +To create a simple message with a text body, use `Yiisoft\Mailer\Message`: + +```php +$message = new \Yiisoft\Mailer\Message( + from: 'from@domain.com', + to: 'to@domain.com', + subject: 'Message subject', + textBody: 'Plain text content' +); +``` + +### Simple HTML Message + +```php +$message = new \Yiisoft\Mailer\Message( + from: 'from@domain.com', + to: 'to@domain.com', + subject: 'Message subject', + htmlBody: 'HTML content' +); +``` + +### HTML Message from template + +For this example, we will use package rendering package +[view](https://github.com/yiisoft/view). + +```php +/** + * @var \Yiisoft\View\View $view + */ + +$content = $view->render('path/to/view.php', [ + 'name' => 'name', + 'code' => 'code', +]); + +$message = new \Yiisoft\Mailer\Message( + from: 'from@domain.com', + to: 'to@domain.com', + subject: 'Subject', + htmlBody: $content +); +``` + +### Using Layouts + +You can also pass parameters to layouts from your template message: + +```php +/** + * @var \Yiisoft\View\View $view + * @var array $layoutParameters + */ + +$messageBody = $view->render('path/to/view.php', [ + 'name' => 'name', + 'code' => 'code', +]); + +$layoutParameters['content'] = $messageBody; + +$content = $view->render('path/to/layout.php', $layoutParameters); + +$message = new \Yiisoft\Mailer\Message( + from: 'from@domain.com', + to: 'to@domain.com', + subject: 'Subject', + htmlBody: $content +); +``` + +### Layout Example + +You can wrap the view rendering result in a layout, similar to how layouts +work in web applications. This is useful for setting up shared content like +CSS styles: + +```php + + + + + + + + + + +
+--
+Mailed by Yii +
+ + + +``` + +## Adding More Data + +The `Yiisoft\Mailer\MessageInterface` provides several methods to customize +your message: + +- `withCharset()` - Returns a new instance with the specified charset. +- `withFrom()` - Returns a new instance with the specified sender email + address. +- `withTo()` - Returns a new instance with the specified recipient(s) email + address. +- `withReplyTo()` - Returns a new instance with the specified reply-to + address. +- `withCc()` - Returns a new instance with the specified Cc (extra copy + receiver) addresses. +- `withBcc()` - Returns a new instance with the specified Bcc (hidden copy + receiver) addresses. +- `withSubject()` - Returns a new instance with the specified message + subject. +- `withDate()` - Returns a new instance with the specified date when the + message was sent. +- `withPriority()` - Returns a new instance with the specified priority of + this message. +- `withReturnPath()` - Returns a new instance with the specified return-path + (the bounce address) of this message. +- `withSender()` - Returns a new instance with the specified actual sender + email address. +- `withHtmlBody()` - Returns a new instance with the specified message HTML + content. +- `withTextBody()` - Returns a new instance with the specified message plain + text content. +- `withAddedHeader()` - Returns a new instance with the specified added + custom header value. +- `withHeader()` - Returns a new instance with the specified custom header + value. +- `withHeaders()` - Returns a new instance with the specified custom header + values. + +These methods are immutable, meaning they return a new instance of the +message with the updated data. + +Note `with` prefix. It indicates that the method is immutable and returns a +new instance of the class with the changed data. + +### Getters + +The following getters are available to retrieve message data: + +- `getCharset()` - Returns the charset of this message. +- `getFrom()` - Returns the message sender email address. +- `getTo()` - Returns the message recipient(s) email address. +- `getReplyTo()` - Returns the reply-to address of this message. +- `getCc()` - Returns the Cc (extra copy receiver) addresses of this + message. +- `getBcc()` - Returns the Bcc (hidden copy receiver) addresses of this + message. +- `getSubject()` - Returns the message subject. +- `getDate()` - Returns the date when the message was sent, or null if it + wasn't set. +- `getPriority()` - Returns the priority of this message. +- `getReturnPath()` - Returns the return-path (the bounce address) of this + message. +- `getSender()` - Returns the message actual sender email address. +- `getHtmlBody()` - Returns the message HTML body. +- `getTextBody()` - Returns the message text body. +- `getHeader()` - Returns all values for the specified header. +- `__toString()` - Returns string representation of this message. + +## Attaching Files + +You can attach files to your message using the `withAttached()` method: + +```php +use Yiisoft\Mailer\File; + +// Attach a file from the local file system +$message = $message->withAttached( + File::fromPath('/path/to/source/file.pdf'), +); + +// Create an attachment on-the-fly +$message = $message->withAttached( + File::fromContent('Attachment content', 'attach.txt', 'text/plain'), +); +``` + +## Embedding Images + +You can embed images into the message content using the `withEmbedded()` +method. This is particularly useful when composing messages with views: + +```php +$logo = 'path/to/logo'; +$htmlBody = $this->view->render( + __DIR__ . 'template.php', + [ + 'content' => $content, + 'logoCid' => $logo->cid(), + ], +); +return new \Yiisoft\Mailer\Message( + from: 'from@domain.com', + to: 'to@domain.com', + subject: 'Message subject', + htmlBody: $htmlBody, + embeddings: $logo + ); +``` + +In your view or layout template, you can reference the embedded image using +its CID: + +```php + +``` + +## Sending a Message + +To send an email message: + +```php +/** + * @var \Yiisoft\View\View $view + */ + +$content = $view->render('path/to/view.php', [ + 'name' => 'name', + 'code' => 'code', +]); + +$message = new \Yiisoft\Mailer\Message( + from: 'from@domain.com', + to: 'to@domain.com', + subject: 'Subject', + htmlBody: $content +); + +$mailer->send($message); +``` + +## Sending Multiple Messages + +You can send multiple messages at once: + +```php +$messages = []; + +foreach ($users as $user) { + $messages[] = (new \Yiisoft\Mailer\Message()) + // ... + ->withTo($user->email); +} + +$result = $mailer->sendMultiple($messages); +``` + +The `sendMultiple()` method returns a `Yiisoft\Mailer\SendResults` object +containing arrays of successfully sent and failed messages. + +## Implementing your own mail driver + +To create a custom mail solution, implement the +`Yiisoft\Mailer\MailerInterface` and `Yiisoft\Mailer\MessageInterface` +interfaces. + +## For Development + +For local or test development, you can use simplified implementations of the +mailer that does not send emails. The package provides these +implementations: + +- `Yiisoft\Mailer\StubMailer` - A simple mailer that stores messages in a + local array. +- `Yiisoft\Mailer\FileMailer` - A mock mailer that saves email messages as + files instead of sending them. +- `Yiisoft\Mailer\NullMailer` - A mailer that discards messages without + sending or storing them. + +To use one of these mailers, configure it in your development environment +file Example: `environments/local/di.php` + +```php +return [ + Yiisoft\Mailer\MailerInterface::class => Yiisoft\Mailer\StubMailer::class, //or any other +]; + +``` diff --git a/src/pt-BR/guide/tutorial/performance-tuning.md b/src/pt-BR/guide/tutorial/performance-tuning.md new file mode 100644 index 00000000..2bb48c75 --- /dev/null +++ b/src/pt-BR/guide/tutorial/performance-tuning.md @@ -0,0 +1,219 @@ +# Performance tuning + +There are many factors affecting the performance of your application. Some +are environmental, some are related to your code, while some others are +related to Yii itself. In this section, we will count most of these factors +and explain how you can improve your application performance by adjusting +these factors. + + +## Optimizing your PHP Environment + +A well-configured PHP environment is important. To get maximum performance: + +- Use the latest stable PHP version. Major releases of PHP may bring + significant performance improvements. +- Enable bytecode caching with [Opcache](https://secure.php.net/opcache). + Bytecode caching avoids the time spent on parsing and including PHP + scripts for every incoming request. +- [Tune `realpath()` + cache](https://github.com/samdark/realpath_cache_tuner). +- Make sure [XDebug](https://xdebug.org/) isn't installed in the production + environment. +- Try [PHP 7 preloading](https://wiki.php.net/rfc/preload). + +## Optimizing your code + +Beyond environment configuration, there are code-level optimizations that +can improve your application's performance: + +- Look out for [algorithm + complexity](https://en.wikipedia.org/wiki/Time_complexity). Especially + give attention to `foreach` within `foreach` loops but look out for using + [heavy PHP + functions](https://stackoverflow.com/questions/2473989/list-of-big-o-for-php-functions) + in loops as well. +- [Speeding up + array_merge()](https://www.exakat.io/speeding-up-array_merge/) +- [Move that foreach() inside the + method](https://www.exakat.io/move-that-foreach-inside-the-method/) +- [Array, classes and anonymous classes memory + usage](https://www.exakat.io/array-classes-and-anonymous-memory-usage/) +- Use fully qualified function names with leading backslashes to optimize + opcache performance. When calling [certain global + functions](https://github.com/php/php-src/blob/944b6b6bbd6f05ad905f5f4ad07445792bee4027/Zend/zend_compile.c#L4291-L4353) + from within a namespace, PHP first searches in the current namespace + before falling back to the global namespace. Adding a leading backslash + (e.g., `\count()` instead of `count()`) tells PHP to directly use the + global function, avoiding the namespace lookup and improving opcache + efficiency. This optimization is best implemented automatically using + tools like [PHP-CS-Fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer) + with the `native_function_invocation` rule. + +The above optimizations would give you a significant performance boost only +if the code in question is executed frequently. That is usually the case for +big loops or batch processing. + +## Using caching techniques + +You can use various caching techniques to significantly improve the +performance of your application. For example, if your application allows +users to enter text in Markdown format, you may consider caching the parsed +Markdown content to avoid parsing the same Markdown text repeatedly in every +request. Please refer to the [Caching](../caching/overview.md) section to +learn about the caching support provided by Yii. + + +## Optimizing session storage + +By default, session data is stored in files. The implementation is locking a file from opening a session to the point it's +closed either by `$session->close()` or at the end of request. +While the session file is locked, all other requests that are trying to use the same session are blocked. That's waiting for the +initial request to release a session file. This is fine for development and probably small projects. But when it comes +to handling massive concurrent requests, it's better to use more sophisticated storage, such as Redis. + +It could be done either by [configuring PHP via +php.ini](https://www.digitalocean.com/community/tutorials/how-to-set-up-a-redis-server-as-a-session-handler-for-php-on-ubuntu-14-04) +or [implementing +SessionHandlerInterface](https://www.sitepoint.com/saving-php-sessions-in-redis/) +and configuring session service as follows: + +```php +\Yiisoft\Session\SessionInterface::class => [ + 'class' => \Yiisoft\Session\Session::class, + '__construct()' => [[], $myCustomSessionHandler], +], +``` + +## Optimizing databases + +Executing DB queries and fetching data from databases are often the main +performance bottleneck in a Web application. Although using [data +caching](../caching/data.md) techniques may ease the performance hit, it +doesn't fully solve the problem. When the database has enormous amounts of +data and the cached data are invalid, fetching the latest data could be +prohibitively expensive without a proper database and query design. + +A general technique to improve the performance of DB queries is to create +indices for table columns that need to be filtered by. For example, if you +need to look for a user record by `username`, you should create an index on +`username`. Note that while indexing can make SELECT queries much faster, it +will slow down INSERT, UPDATE and DELETE queries. + +For complex DB queries, it's recommended that you create database views to +save the query parsing and preparation time. + +Last but not least, use `LIMIT` in your `SELECT` queries. This avoids +fetching an overwhelming amount of data from the database and exhausting the +memory allocated to PHP. + + +## Optimizing composer autoloader + +Because Composer autoloader is used to include most third-party class files, +you should consider optimizing it by executing the following command: + +``` +composer dumpautoload -o +``` + +Additionally, you may consider using [authoritative class +maps](https://getcomposer.org/doc/articles/autoloader-optimization.md#optimization-level-2-a-authoritative-class-maps) +and [APCu +cache](https://getcomposer.org/doc/articles/autoloader-optimization.md#optimization-level-2-b-apcu-cache). +Note that both optimizations may or may not be suitable for your particular +case. + + +## Processing data offline + +When a request involves some resource-intensive operations, you should think +of ways to perform those operations in offline mode without having users +wait for them to finish. + +There are two methods to process data offline: pull and push. + +In the pull method, whenever a request involves some complex operation, you +create a task and save it in a persistent storage, such as a database. You +then use a separate process (such as a cron job) to pull the tasks and +process them. This method is straightforward to implement, but it has some +drawbacks. For example, the task process needs to periodically pull from the +task storage. If the pull frequency is too low, the tasks may be processed +with great delay, but if the frequency is too high, it will introduce high +overhead. + +In the push method, you would use a message queue (e.g., RabbitMQ, ActiveMQ, +Amazon SQS, etc.) to manage the tasks. Whenever a new task is put in the +queue, it will initiate or notify the task handling process to trigger the +task processing. + +## Using preloading + +As of PHP 7.4.0, PHP can be configured to preload scripts into the opcache +when the engine starts. You can read more in the +[documentation](https://www.php.net/manual/en/opcache.preloading.php) and +the corresponding [RFC](https://wiki.php.net/rfc/preload). + +Note that the optimal tradeoff between performance and memory may vary with +the application. "Preload everything" may be the easiest strategy, but not +necessarily the best strategy. + +For example, we conducted a simple +[yiisoft/app](https://github.com/yiisoft/app) application template +benchmark. Without preloading and with preloading of the entire composer +class map. + +### Preloading benchmarks + +The application template benchmark includes configuring classes to injected +dependencies in the bootstrap script. + +For both variants, +[ApacheBench](https://httpd.apache.org/docs/2.4/programs/ab.html) was used +with the following run parameters: + +```shell +ab -n 1000 -c 10 -t 10 +``` + +Also, the debug mode was disabled. And an optimized autoloader of the +[Composer](https://getcomposer.org) was used, and development dependencies +weren't used: + +```shell +composer install --optimize-autoloader --no-dev +``` + +With preloading enabled, the entire composer class map (825 files) was used: + +```php +$files = require 'vendor/composer/autoload_classmap.php'; + +foreach (array_unique($files) as $file) { + opcache_compile_file($file); +} +``` + +#### Test results + +| Benchmark | Preloaded files | Opcache memory used | Per request memory used | Time per request | Requests per second | +|--------------------|-----------------|---------------------|-------------------------|------------------|---------------------| +| Without preloading | 0 | 12.32 mb | 1.71 mb | 27.63 ms | 36.55 rq/s | +| With preloading | 825 | 17.86 mb | 1.82 mb | 26.21 ms | 38.42 rq/s | + +As you can see, the test results aren't much different, since this is just a +clean application template that contains a few classes. More discussion of +preloading, including benchmarks, can be found in the [composer's +issue](https://github.com/composer/composer/issues/7777). + +## Performance profiling + +You should profile your code to find out the performance bottlenecks and +take appropriate measures accordingly. The following profiling tools may be +useful: + + + +- [Blackfire](https://blackfire.io/) +- [XHProf](https://secure.php.net/manual/en/book.xhprof.php) +- [XDebug profiler](https://xdebug.org/docs/profiler) diff --git a/src/pt-BR/guide/tutorial/using-with-event-loop.md b/src/pt-BR/guide/tutorial/using-with-event-loop.md new file mode 100644 index 00000000..e23d13e9 --- /dev/null +++ b/src/pt-BR/guide/tutorial/using-with-event-loop.md @@ -0,0 +1,67 @@ +# Using Yii with event loop + +A normal PHP web request execution cycle consists of setting up an environment, getting a request, processing it to form a response +and sending the result. After the response is sent, execution is terminated and its context is lost. So, for the further + request, the whole sequence is repeated. Such an approach has a big advantage in ease of development since a developer doesn't +have to take much care about memory leaks or properly clean up context. On the other side, initializing everything for +every request takes time and overall consumes up to 50% of processing resources. + +There is an alternative way of running an application. Event loop. The idea +is to initialize everything possible at once and then process a number of +requests using it. Such an approach is usually called event loop. + +There are multiple tools that could be used to achieve it. Notably, +[FrankenPHP](https://frankenphp.dev/), [Rapira](https://rapira.rs/), +[RoadRunner](https://roadrunner.dev/) and [Swoole](https://www.swoole.com/). + +## Event loop implications + +Event loop worker basically looks like the following: + +```php +initializeContext(); +while ($request = getRequest()) { + $response = process($request); + emit($response); +} +``` + +Usually, there are multiple workers processing requests at the same time as +with traditional php-fpm. + +That means that there's more to consider when developing applications. + +### Processing is blocking + +Worker process requests one by one that's current processing is blocking +processing next request. That means that long-running processes, same as in +general PHP applications, should be put into a background via using a queue. + +### Services and state + +Since the context in the event loop is shared between all request-responses +processed by a single worker, all changes in the state of a service made by +the previous request may affect the current request. Moreover, it can be a +security problem if data from one user is available to another user. + +There are two ways of dealing with it. First, you can avoid having state by +making services stateless. PHP's `readonly` keyword may be handy for +it. Second, you can reset the services' state at the end of the request +processing. In this case, a state resetter will help you: + +```php +initializeContext(); +$resetter = $container->get(\Yiisoft\Di\StateResetter::class); +while ($request = getRequest()) { + $response = process($request); + emit($response); + $resetter->reset(); // We should reset the state of such services on every request. +} +``` + +## Integrations + +- [FrankenPHP](using-yii-with-frankenphp.md) +- [Rapira](using-yii-with-rapira.md) +- [RoadRunner](using-yii-with-roadrunner.md) +- [Swoole](using-yii-with-swoole.md) diff --git a/src/pt-BR/guide/tutorial/using-yii-with-frankenphp.md b/src/pt-BR/guide/tutorial/using-yii-with-frankenphp.md new file mode 100644 index 00000000..9279338a --- /dev/null +++ b/src/pt-BR/guide/tutorial/using-yii-with-frankenphp.md @@ -0,0 +1,263 @@ +# Using Yii with FrankenPHP + +[FrankenPHP](https://frankenphp.dev/) is an application server for PHP with Caddy built in. It can run Yii in +[worker mode](using-with-event-loop.md), allowing the framework bootstrap to happen once per worker instead of +once per request. + +## Installation + +The [FrankenPHP runner](https://github.com/yiisoft/yii-runner-frankenphp) +requires PHP 8.1–8.5. Install FrankenPHP using its [installation +instructions](https://frankenphp.dev/docs/), or use the Docker setup in the +Yii application templates described below. + +Install the runner package with Composer: + +```shell +composer require yiisoft/yii-runner-frankenphp +``` + +FrankenPHP works especially well in containerized deployments and is the +runtime used by the Yii application templates Docker setup described in +[Docker in application templates](docker.md). + +> [!NOTE] +> This runner is for worker mode. To use FrankenPHP in classic mode, keep `public/index.php` and +> [yiisoft/yii-runner-http](https://github.com/yiisoft/yii-runner-http), the default HTTP runner in the templates. + +## Configuration + +First, configure the worker entry script. + +### Worker entry script + +Create `/worker.php` in the project root: + +```php +setLevels([ + LogLevel::EMERGENCY, + LogLevel::ERROR, + LogLevel::WARNING, + ]), + ], + ), + new PlainTextRenderer(), + ), +); +$runner->run(); +``` + +The runner bootstraps the application once and then keeps processing +requests in worker mode. Unlike classic `public/index.php`, this script is +not executed per request. + +### Server configuration + +FrankenPHP is configured through a `Caddyfile`. For production, it may look +like the following: + +```caddyfile +{ + skip_install_trust + + frankenphp { + + } +} + +{$SERVER_NAME::80} { + encode zstd br gzip + php_server { + root /app/public + worker { + match * + file /app/worker.php + } + } +} +``` + +This configuration tells FrankenPHP to serve the `public` directory and +handle all requests with `worker.php`. Static assets are still served from +`public`, while PHP requests are processed through the long-running worker. + +For development, add `watch` so FrankenPHP reloads workers when PHP files +change: + +```caddyfile +{ + skip_install_trust + + frankenphp { + + } +} + +{$SERVER_NAME::80} { + encode zstd br gzip + php_server { + root /app/public + worker { + match * + file /app/worker.php + watch /app/**/*.php + } + } +} +``` + +### Docker setup in Yii application templates + +Yii application templates already ship with a FrankenPHP-based Docker +setup. To switch the application to worker mode, update the files inside the +Docker layout instead of relying on `public/index.php`. + +Create `/worker.php` in the project root as shown above, then update the +Caddy configuration used by the container. For development, edit +`docker/dev/Caddyfile`: + +```caddyfile +{ + skip_install_trust + + frankenphp { + + } +} + +{$SERVER_NAME::80} { + encode zstd br gzip + php_server { + root /app/public + worker { + match * + file /app/worker.php + watch /app/**/*.php + } + } +} +``` + +For production, use the same configuration without `watch` in +`docker/Caddyfile`: + +```caddyfile +{ + skip_install_trust + + frankenphp { + + } +} + +{$SERVER_NAME::80} { + encode zstd br gzip + php_server { + root /app/public + worker { + match * + file /app/worker.php + } + } +} +``` + +The templates use `dunglas/frankenphp` as the base image in +`docker/Dockerfile`, mount the project into `/app` in development, and pass +runtime configuration through environment files such as `docker/dev/.env` +and `docker/prod/.env`. The default value of `SERVER_NAME` in these files is +`:80`, which matches the examples above. + +After changing `worker.php` and the relevant `Caddyfile`, rebuild the image +and restart the environment: + +```shell +make build +make up +``` + +In production, rebuild and deploy the production image using the project's +production Docker workflow. + +If you switch fully to worker mode, `public/index.php` and +`yiisoft/yii-runner-http` are no longer needed. + +## Starting a server + +The exact start command depends on how you run FrankenPHP: + +- In the Yii application templates, run `make build` and `make up` after + updating `worker.php` and the relevant `Caddyfile`. +- With the standalone binary, run the following command from the directory + containing your `Caddyfile`: + +```shell +frankenphp run --config Caddyfile +``` + +The example configuration uses `/app` as the application root. Adjust +`/app/public`, `/app/worker.php`, and the watch path to match your +installation. See the [FrankenPHP configuration +reference](https://frankenphp.dev/docs/config/) for other deployment +options. + +## On worker scope + +- Each worker's memory is isolated from other workers. +- A single worker handles multiple requests, so services created inside it + may keep state between requests. +- At each iteration of the event loop, every stateful service should be + reset. + +For the general implications of long-running workers, see [Using Yii with +event loop](using-with-event-loop.md). + +## Worker mode notes + +- Use the `MAX_REQUESTS` environment variable to limit how many requests a + worker handles before restart. +- The runner calls `Yiisoft\Di\StateResetter::reset()` after each + request. Register resetters for your stateful services as described in the + [Yii DI + documentation](https://github.com/yiisoft/di#resetting-services-state). + +## Additional configuration + +`FrankenPHPApplicationRunner` is configured by default for Yii application +templates and follows the [dependency container +configuration](../concept/configuration.md#container-configuration) concept. + +The constructor allows overriding the default bootstrap, events, DI, params, +and error-handler configuration. You can also provide a custom config +instance with `withConfig()` and a custom container with `withContainer()`. diff --git a/src/pt-BR/guide/tutorial/using-yii-with-rapira.md b/src/pt-BR/guide/tutorial/using-yii-with-rapira.md new file mode 100644 index 00000000..7093ae04 --- /dev/null +++ b/src/pt-BR/guide/tutorial/using-yii-with-rapira.md @@ -0,0 +1,143 @@ +# Using Yii with Rapira + +[Rapira](https://rapira.rs/) is a PHP application server written in Rust that embeds the PHP interpreter. +The [Yii Rapira runner](https://github.com/yiisoft/yii-runner-rapira) supports its classic, worker, and dispatcher modes. +Worker and dispatcher modes initialize the application once per worker and reuse it for subsequent requests. +See [Using Yii with event loop](using-with-event-loop.md) for the implications of keeping the application in memory. + +## Installation + +The runner requires PHP 8.4–8.5. Install the Rapira binary following the +[Rapira installation +instructions](https://rapira.rs/docs/intro/installation), using a PHP +version supported by the runner. The Composer packages provide the Yii +integration; the server binary must be installed separately. + +Install the runner and its contract package in your Yii application: + +```shell +composer require yiisoft/yii-runner-rapira:@dev rapira/contract:@dev +``` + +These stability flags allow the development versions used by the runner's +installation instructions. + +## Configuration + +The following example assumes an application based on `yiisoft/app` or +`yiisoft/app-api`, with `App\Environment` and `src/bootstrap.php` provided +by the template. + +### Worker entry script + +Create `worker.php` in the application root: + +```php +setLevels([ + LogLevel::EMERGENCY, + LogLevel::ERROR, + LogLevel::WARNING, + ]), + ], + ), + new PlainTextRenderer(), + ), +); +$runner->run(); +``` + +The runner creates the container, starts the application, converts incoming +requests to PSR-7 requests, and emits responses. It detects the Rapira +execution mode, so the same entry script can be used with all three modes. + +### Server configuration + +Create `rapira.toml` next to `worker.php`: + +```toml +[http] +listen = "127.0.0.1:8000" + +[http.pool] +entrypoint = "worker.php" +mode = "worker" +max_requests = 1000 +``` + +This configuration listens on the loopback interface and recycles each +worker after 1,000 requests. For serving files from `public`, follow +Rapira's [static file configuration](https://rapira.rs/docs/static-files). +See the [configuration reference](https://rapira.rs/docs/configuration) for +the other server and pool settings. + +## Starting a server + +Run the following command from the application root: + +```shell +rapira serve rapira.toml +``` + +Open `http://127.0.0.1:8000` to access the application. Restart the server +after changing application code or configuration. + +## Execution modes + +Set `mode` in the `[http.pool]` section of `rapira.toml` to choose how +requests are processed: + +- `classic` initializes the application for each request, similarly to + PHP-FPM. +- `worker` keeps the application in memory and receives requests through + PHP's SAPI superglobals. +- `dispatcher` keeps the application in memory and receives request objects + through Rapira's dispatcher API. The Yii runner processes these requests + sequentially within each worker. + +See [Rapira execution modes](https://rapira.rs/docs/execution-modes) for +details. + +## On worker scope + +In worker and dispatcher modes, services may retain state between +requests. The runner calls `Yiisoft\Di\StateResetter::reset()` after each +request, but you must configure resetters for your own stateful services. +See the [Yii DI +documentation](https://github.com/yiisoft/di#resetting-services-state). + +The `max_requests` setting limits how long a worker lives; it does not +replace resetting request-specific state. + +## Additional configuration + +`RapiraApplicationRunner` uses the application templates' web configuration +groups by default. Its constructor accepts alternative groups, configuration +directories, and a temporary error handler. Use `withConfig()` to supply a +custom configuration instance or `withContainer()` to supply a PSR-11 +container. See the [runner +documentation](https://github.com/yiisoft/yii-runner-rapira#configuration) +for examples. diff --git a/src/pt-BR/guide/tutorial/using-yii-with-roadrunner.md b/src/pt-BR/guide/tutorial/using-yii-with-roadrunner.md new file mode 100644 index 00000000..80b18078 --- /dev/null +++ b/src/pt-BR/guide/tutorial/using-yii-with-roadrunner.md @@ -0,0 +1,180 @@ +# Using Yii with RoadRunner + +[RoadRunner](https://roadrunner.dev/) is a Golang-powered application server that integrates well with PHP. It runs +it as workers and each worker may handle multiple requests. Such an operation mode is often called +[event loop](using-with-event-loop.md) and allows not re-initializing a framework for each request that improves +performance significantly. + +## Installation + +RoadRunner works on Linux, macOS and Windows. The best way to install it is +to use a Composer: + +``` +composer require yiisoft/yii-runner-roadrunner +``` + +After installation is done, run + +``` +./vendor/bin/rr get +``` + +That would download ready to use RoadRunner server `rr` binary. + +## Configuration + +First, we need to configure the server itself. Create `/.rr.yaml` and add +the following config: + +```yaml +version: '3' + +server: + command: "php worker.php" + +rpc: + listen: tcp://127.0.0.1:6001 + +http: + address: :8080 + pool: + debug: false # set to true for local development only + supervisor: + max_worker_memory: 192 + middleware: [static, gzip, headers, sendfile] + static: + dir: "public" + forbid: [".php", ".htaccess"] + headers: + response: + "Cache-Control": "no-cache" + +logs: + mode: production + level: warn +``` + +> [!INFO] +> Read more about TLS, HTTP/2, HTTP/3 configuration and other middleware [on the RoadRunner docs](https://docs.roadrunner.dev/docs/http/http). + +We're specifying that the entry script is `worker.php`, the server listens +on port 8080, `public` directory files are served statically except `.php` +and `.htaccess`. The `max_worker_memory` is a soft limit: if a worker +exceeds 192 MB, it will restart after finishing its current request. Also, +we're sending an additional header. + +## KV cache + +RoadRunner has a [KV +plugin](https://docs.roadrunner.dev/docs/key-value/overview-kv) that can be +used as a PSR-16 cache storage. It is useful when the application already +runs under RoadRunner and needs a cache shared by workers. + +Install the PHP bridge and Yii cache package: + +``` +composer require spiral/roadrunner-kv yiisoft/cache +``` + +Add a KV storage to `.rr.yaml`: + +```yaml +kv: + cache: + driver: memory + config: + interval: 60 +``` + +The `memory` driver stores values inside the RoadRunner process, so its data +is lost when RoadRunner stops. For persistent cache storage, use another KV +driver from the RoadRunner documentation. + +Create `config/common/di/roadrunner-kv.php`: + +```php + static function (): StorageInterface { + $factory = new Factory(RPC::create('tcp://127.0.0.1:6001')); + + return $factory->select('cache'); + }, + + SimpleCacheInterface::class => StorageInterface::class, + YiiCacheInterface::class => Cache::class, +]; +``` + +Now services can use `Yiisoft\Cache\CacheInterface` the same way as with +other cache backends: + +```php +use Yiisoft\Cache\CacheInterface; + +final readonly class FeedService +{ + public function __construct( + private CacheInterface $cache, + ) { + } + + public function latest(): array + { + return $this->cache->getOrSet('feed-latest', fn (): array => $this->loadLatest(), 60); + } + + private function loadLatest(): array + { + return []; + } +} +``` + +Create `/worker.php`: + +```php +run(); +``` + +## Starting a server + +To start a server, execute the following command: + +``` +./rr serve +``` + +## On worker scope + +- Each worker's scope is isolated from other workers. Memory isn't shared. +- A single worker serves multiple requests where the scope is shared. +- At each iteration of the event loop, every service that depends on state + should be reset. diff --git a/src/pt-BR/guide/tutorial/using-yii-with-swoole.md b/src/pt-BR/guide/tutorial/using-yii-with-swoole.md new file mode 100644 index 00000000..322f6a94 --- /dev/null +++ b/src/pt-BR/guide/tutorial/using-yii-with-swoole.md @@ -0,0 +1,172 @@ +# Using Yii with Swoole + +[Swoole](https://www.swoole.com/) is a PHP extension for event-driven, coroutine-based network applications. It +includes an HTTP server, coroutine APIs, and runtime hooks for common blocking I/O functions. + +Swoole allows Yii request handlers to run as workers. Each worker may handle +multiple requests. Such an operation mode is often called [event +loop](using-with-event-loop.md) and allows not re-initializing a framework +for each request that improves performance significantly. + +## Installation + +Swoole supports Linux, macOS, Cygwin, and WSL. Install the extension through +PECL: + +```bash +pecl install swoole +``` + +If PECL doesn't enable the extension automatically, add it to your +`php.ini`: + +```ini +extension=swoole.so +``` + +Check that PHP loads the extension: + +```bash +php --ri swoole +``` + +The Swoole project also provides a [Docker +image](https://github.com/swoole/docker-swoole) and documents source builds +with optional features such as OpenSSL, sockets, MySQL, PostgreSQL, and curl +hooks. + +## Putting up a server + +Swoole passes `Swoole\Http\Request` and `Swoole\Http\Response` objects to +request callbacks. Yii handles PSR-7 requests and responses, so add a +converter package: + +```shell +composer require ilexn/swoole-convert-psr7 +``` + +Create an entry script, `server.php`: + +```php +setLevels([ + LogLevel::EMERGENCY, + LogLevel::ERROR, + LogLevel::WARNING, + ]), + ], + ), + new HtmlRenderer(), + ), +); + +$container = $runner->getContainer(); +$application = $container->get(Application::class); +$errorCatcher = $container->get(ErrorCatcher::class); + +$serverRequestFactory = new SwooleServerRequestConverter( + $container->get(ServerRequestFactoryInterface::class), + $container->get(UriFactoryInterface::class), + $container->get(UploadedFileFactoryInterface::class), + $container->get(StreamFactoryInterface::class) +); + +$server = new Server('0.0.0.0', 9501); + +$server->on('start', static function (Server $server) use ($application) { + $application->start(); + echo "Swoole http server is started at http://127.0.0.1:9501\n"; +}); + +$server->on('request', static function ( + Request $request, + Response $response +) use ($serverRequestFactory, $application, $errorCatcher, $container) { + try { + $psr7Request = $serverRequestFactory->createFromSwoole($request); + $psr7Response = $application->handle($psr7Request); + (new SwooleResponseConverter($response))->send($psr7Response); + } catch (Throwable $throwable) { + $handler = new ThrowableHandler($throwable); + $psr7Response = $errorCatcher->process($request, $handler); + (new SwooleResponseConverter($response))->send($psr7Response); + } + $application->afterEmit($psr7Response); + $container->get(StateResetter::class)->reset(); +}); + +$server->on('shutdown', static function (Server $server) use ($application) { + $application->shutdown(); +}); + +$server->start(); +``` + +## Starting a server + +To start a server, execute the following command: + +``` +php server.php +``` + +## On scope + +A scope is shared, so at each iteration of the event loop every service that +depends on state should be reset. + +## Sessions + +Avoid native PHP sessions, including `Yiisoft\Session\Session`, when Swoole +coroutines handle overlapping requests within one worker: they share session +state and can expose one user's data to another request. + +For requests handled one at a time, close the session and reset services +between requests. `yiisoft/session` prevents stale session ID reuse, but +does not isolate overlapping coroutines. + +For authentication, consider tokens such as +[JWT](https://jwt.io/introduction) instead of native sessions, especially +for APIs. If you need session features, use an implementation that isolates +each coroutine's session data; changing the native storage handler to Redis +is not enough. + +See the [Swoole +guidance](https://github.com/swoole/swoole-src/issues/4478#issuecomment-962840796) +and [Yii session discussion](https://github.com/yiisoft/session/issues/25). diff --git a/src/pt-BR/guide/views/asset.md b/src/pt-BR/guide/views/asset.md new file mode 100644 index 00000000..ee79c6d1 --- /dev/null +++ b/src/pt-BR/guide/views/asset.md @@ -0,0 +1,666 @@ +# Assets + +Asset management is crucial for modern web applications. Assets include CSS +stylesheets, JavaScript files, images, fonts, and other static +resources. Yii3 provides a comprehensive asset management system through the +`yiisoft/assets` package that handles dependencies, optimization, and +deployment of these resources. + +## Installation + +The asset management functionality is provided by the `yiisoft/assets` +package: + +```bash +composer require yiisoft/assets +``` + +This package is included by default in the `yiisoft/app` application +template. + +## Basic Concepts + +### Asset Bundles + +An asset bundle is a collection of related asset files (CSS, JavaScript, +images) that are logically grouped together. Asset bundles can depend on +other bundles, allowing for proper dependency management. + +### Asset Manager + +The Asset Manager is responsible for: - Resolving asset bundle dependencies +- Publishing assets from protected directories to web-accessible locations - +Combining and minifying assets (when configured) - Generating proper URLs +for assets + +## Creating Asset Bundles + +### Basic Asset Bundle + +Here's a simple asset bundle definition: + +```php + 'print'], + ['css/admin/mobile.css', 'media' => 'screen and (max-width: 768px)'], + ]; + + // JavaScript files with attributes + public array $js = [ + 'js/admin/core.js', + ['js/admin/charts.js', 'defer' => true], + ['js/admin/analytics.js', 'async' => true], + ]; + + // Global options for all JS files in this bundle + public array $jsOptions = [ + 'data-admin' => 'true', + ]; + + // Global options for all CSS files in this bundle + public array $cssOptions = [ + 'data-bundle' => 'admin', + ]; + + public array $depends = [ + MainAsset::class, + ChartJsAsset::class, + ]; +} +``` + +## Using Asset Bundles + +### In Controllers + +Register asset bundles in your controllers or views: + +```php +assetManager->register(MainAsset::class); + + return $this->viewRenderer->render('index', [ + 'title' => 'Home Page', + ]); + } + + public function admin(): ResponseInterface + { + // Register multiple asset bundles + $this->assetManager->registerMany([ + MainAsset::class, + AdminAsset::class, + ]); + + return $this->viewRenderer->render('admin/dashboard'); + } +} +``` + +### In Views + +You can also register assets directly in views: + +```php +register(ProductAsset::class); +?> + +
+

+ +
+``` + +### With WebView Integration + +The recommended approach is to integrate with WebView for automatic asset +rendering: + +```php +register(MainAsset::class); + +// Add all registered assets to the view +$this->addCssFiles($assetManager->getCssFiles()); +$this->addCssStrings($assetManager->getCssStrings()); +$this->addJsFiles($assetManager->getJsFiles()); +$this->addJsStrings($assetManager->getJsStrings()); +$this->addJsVars($assetManager->getJsVars()); +?> + +
+ +
+``` + +## Asset Publishing + +### Source Path Publishing + +When assets are located in non-web-accessible directories (like vendor +packages), they need to be published: + +```php +publish('@vendor/company/package/assets'); + +// Get the published URL +$publishedUrl = $assetManager->getPublishedUrl('@vendor/company/package/assets'); +``` + +## Third-party Library Assets + +### jQuery Asset Bundle + +```php + 'sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3', + 'crossorigin' => 'anonymous', + ]; + + public array $js = [ + 'https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js', + ]; + + public array $jsOptions = [ + 'integrity' => 'sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p', + 'crossorigin' => 'anonymous', + ]; +} +``` + +## Asset Configuration + +### Application Configuration + +Configure asset management in your application configuration: + +**config/web/params.php** +```php +return [ + 'yiisoft/assets' => [ + // Base path for published assets + 'basePath' => '@webroot/assets', + + // Base URL for assets + 'baseUrl' => '@web/assets', + + // Asset converter configuration + 'converter' => [ + 'commands' => [ + 'scss' => ['sass', '{from}', '{to}', '--style=compressed'], + 'ts' => ['tsc', '{from}', '--outFile', '{to}'], + ], + ], + ], +]; +``` + +### Environment-specific Assets + +Configure different assets for different environments: + +```php +css = ['css/main.css', 'css/debug.css']; + $this->js = ['js/main.js', 'js/debug.js']; + } else { + // Production assets (minified) + $this->css = ['css/main.min.css']; + $this->js = ['js/main.min.js']; + } + } +} +``` + +## Asset Optimization + +### Asset Combination + +Combine multiple CSS or JavaScript files into single files: + +```php +/** + * @var \Yiisoft\Assets\AssetManager $assetManager + */ + +// Enable asset combination +$assetManager->setCombine(true); + +// Set combination options +$assetManager->setCombineOptions([ + 'css' => true, // Combine CSS files + 'js' => true, // Combine JavaScript files +]); +``` + +### Asset Compression + +Configure asset compression for production: + +```php +// In your asset manager configuration +'converter' => [ + 'commands' => [ + 'css' => ['cleancss', '{from}', '-o', '{to}'], + 'js' => ['uglifyjs', '{from}', '-o', '{to}', '--compress', '--mangle'], + ], +], +``` + +## Working with Asset Converter + +### SCSS/SASS Compilation + +```php + 'screen and (max-width: 768px)'], + ]; + + public array $depends = [ + AppAsset::class, + ]; +} +``` + +## Best Practices + +1. **Organize by functionality**: Group related assets into logical bundles +2. **Manage dependencies**: Properly declare dependencies between bundles +3. **Use meaningful names**: Name your asset bundles clearly +4. **Environment optimization**: Use minified assets in production +5. **CDN consideration**: Use CDN for popular libraries when appropriate +6. **Version your assets**: Include version numbers in filenames for cache + busting +7. **Minimize HTTP requests**: Combine related assets when possible +8. **Optimize file sizes**: Compress and minify assets for production + +## Troubleshooting + +### Common Issues + +**Asset not found:** +- Check that the asset file exists in the specified path +- Verify `$basePath` and `$baseUrl` are configured correctly +- Ensure assets are published if using `$sourcePath` + +**Dependencies not loading:** +- Verify the dependency bundles are properly registered +- Check for circular dependencies +- Ensure dependency bundles are correctly configured + +**Assets not appearing in HTML:** +- Make sure you're calling `$this->addCssFiles()` and `$this->addJsFiles()` in your layout +- Verify that `$this->head()`, `$this->beginBody()`, and `$this->endBody()` are called in the layout + +**Permission issues:** +- Check that the web server has write permissions to the assets directory +- Verify the published assets directory is web-accessible diff --git a/src/pt-BR/guide/views/script-style-meta.md b/src/pt-BR/guide/views/script-style-meta.md new file mode 100644 index 00000000..4a899f47 --- /dev/null +++ b/src/pt-BR/guide/views/script-style-meta.md @@ -0,0 +1,505 @@ +# Scripts, styles and meta tags + +Modern web applications require careful management of CSS styles, JavaScript +code, and HTML meta tags. Yii3 provides a comprehensive system for +registering and organizing these resources through the `WebView` class, +which is part of the `yiisoft/view` package. + +## Overview + +The `WebView` class extends the basic `View` class with web-specific +functionality, allowing you to: + +- Register CSS files and inline styles +- Register JavaScript files and inline scripts +- Manage HTML meta tags and link tags +- Control the position where resources are rendered +- Handle dependencies between resources + +## CSS management + +### Registering CSS Files + +You can register CSS files to be included in your HTML pages: + +```php +registerCssFile('/css/styles.css'); + +// Register CSS file with attributes +$this->registerCssFile('/css/print.css', WebView::POSITION_HEAD, [ + 'media' => 'print', +]); + +// Register CSS file with custom key to avoid duplicates +$this->registerCssFile('/css/theme.css', WebView::POSITION_HEAD, [], 'theme-css'); +``` + +### Registering Inline CSS + +For inline CSS styles, use the `registerCss()` method: + +```php +// Register inline CSS +$this->registerCss(' + .highlight { + background-color: yellow; + font-weight: bold; + } + .error { + color: red; + border: 1px solid red; + } +', WebView::POSITION_HEAD); + +// With custom attributes +$this->registerCss(' + @media print { + .no-print { display: none; } + } +', WebView::POSITION_HEAD, ['id' => 'print-styles']); +``` + +### CSS from Files + +You can also register CSS content from external files: + +```php +// Read CSS from a file and register as inline CSS +$this->registerCssFromFile('/path/to/dynamic-styles.css', WebView::POSITION_HEAD, [ + 'id' => 'dynamic-styles', +]); +``` + +### Using Style Tags + +For more control, you can use HTML style tags directly: + +```php +use Yiisoft\Html\Html; + +$styleTag = Html::style(' + .custom-button { + background: linear-gradient(45deg, #blue, #purple); + border: none; + color: white; + padding: 10px 20px; + } +', ['id' => 'custom-button-styles']); + +$this->registerStyleTag($styleTag, WebView::POSITION_HEAD); +``` + +## JavaScript management + +### Registering JavaScript Files + +Include external JavaScript files using `registerJsFile()`: + +```php +// Register a JavaScript file +$this->registerJsFile('/js/main.js'); + +// Register with attributes (async loading) +$this->registerJsFile('/js/analytics.js', WebView::POSITION_END, [ + 'async' => true, +]); + +// Register with defer attribute +$this->registerJsFile('/js/interactive.js', WebView::POSITION_END, [ + 'defer' => true, +]); + +// Register from CDN +$this->registerJsFile('https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js', + WebView::POSITION_END, [], 'jquery'); +``` + +### Registering Inline JavaScript + +Add inline JavaScript code with `registerJs()`: + +```php +// Register inline JavaScript +$this->registerJs(' + document.addEventListener("DOMContentLoaded", function() { + console.log("Page loaded!"); + initializeComponents(); + }); +', WebView::POSITION_END); + +// Register JavaScript that should run when DOM is ready +$this->registerJs(' + function showAlert(message) { + alert(message); + } +', WebView::POSITION_READY); +``` + +### JavaScript Variables + +Pass PHP data to JavaScript using `registerJsVar()`: + +```php +// Register JavaScript variables +$this->registerJsVar('apiUrl', 'https://api.example.com'); +$this->registerJsVar('currentUser', [ + 'id' => $user->getId(), + 'name' => $user->getName(), + 'isAdmin' => $user->isAdmin(), +]); +$this->registerJsVar('config', [ + 'debug' => $this->isDebugMode(), + 'locale' => $this->getLocale(), +]); +``` + +This generates JavaScript code like: + +```html + +``` + +### Using Script Tags + +For more control over script tags: + +```php +use Yiisoft\Html\Html; + +$scriptTag = Html::script(' + window.myApp = { + init: function() { + console.log("App initialized"); + } + }; +', ['type' => 'module']); + +$this->registerScriptTag($scriptTag, WebView::POSITION_END); +``` + +## Position Constants + +Resources can be positioned at different locations in the HTML document: + +```php +use Yiisoft\View\WebView; + +// In the section +WebView::POSITION_HEAD + +// At the beginning of +WebView::POSITION_BEGIN + +// At the end of (before ) +WebView::POSITION_END + +// When DOM is ready (jQuery document.ready equivalent) +WebView::POSITION_READY + +// When page is fully loaded (window.onload equivalent) +WebView::POSITION_LOAD +``` + +Example layout showing where each position is rendered: + +```php + +beginPage() ?> + + + + + head() ?> + + + + beginBody() ?> + +
+ +
+ + + endBody() ?> + + +endPage() ?> +``` + +## Meta tags + +### Basic Meta Tags + +Register meta tags for SEO and page information: + +```php +// Register meta tags using array syntax +$this->registerMeta(['name' => 'description', 'content' => 'Page description']); +$this->registerMeta(['name' => 'keywords', 'content' => 'yii, php, framework']); +$this->registerMeta(['name' => 'author', 'content' => 'John Doe']); +$this->registerMeta(['name' => 'robots', 'content' => 'index, follow']); + +// Viewport for responsive design +$this->registerMeta(['name' => 'viewport', 'content' => 'width=device-width, initial-scale=1']); + +// Open Graph tags for social media +$this->registerMeta(['property' => 'og:title', 'content' => 'Page Title']); +$this->registerMeta(['property' => 'og:description', 'content' => 'Page description']); +$this->registerMeta(['property' => 'og:image', 'content' => 'https://example.com/image.jpg']); +``` + +### Using Meta Tag Objects + +For more control, use the `Html::meta()` helper: + +```php +use Yiisoft\Html\Html; + +// Create meta tags with the Html helper +$this->registerMetaTag( + Html::meta() + ->name('description') + ->content('This is a comprehensive guide to Yii3 views') +); + +$this->registerMetaTag( + Html::meta() + ->httpEquiv('refresh') + ->content('300') // Refresh every 5 minutes +); +``` + +### Preventing Duplicate Meta Tags + +Use keys to prevent duplicate meta tags: + +```php +// First registration +$this->registerMeta([ + 'name' => 'description', + 'content' => 'Original description' +], 'description'); + +// This will override the previous one +$this->registerMeta([ + 'name' => 'description', + 'content' => 'Updated description' +], 'description'); +``` + +## Link tags + +### Basic Link Tags + +Register various types of link tags: + +```php +// Favicon +$this->registerLink([ + 'rel' => 'icon', + 'type' => 'image/png', + 'href' => '/favicon.png', +]); + +// RSS feed +$this->registerLink([ + 'rel' => 'alternate', + 'type' => 'application/rss+xml', + 'title' => 'RSS Feed', + 'href' => '/feed.rss', +]); + +// Canonical URL +$this->registerLink([ + 'rel' => 'canonical', + 'href' => 'https://example.com/canonical-url', +]); + +// Preload resources +$this->registerLink([ + 'rel' => 'preload', + 'href' => '/fonts/main.woff2', + 'as' => 'font', + 'type' => 'font/woff2', + 'crossorigin' => 'anonymous', +]); +``` + +### Using Link Tag Objects + +```php +use Yiisoft\Html\Html; + +// CSS stylesheet +$this->registerLinkTag( + Html::link('/css/main.css', [ + 'rel' => 'stylesheet', + ]) +); + +// DNS prefetch +$this->registerLinkTag( + Html::link('https://fonts.googleapis.com', [ + 'rel' => 'dns-prefetch', + ]) +); +``` + +## Practical Examples + +### Complete Page Setup + +Here's how you might set up a complete page with all types of resources: + +```php +setTitle($title); + +// Meta tags +$this->registerMeta(['name' => 'description', 'content' => $description]); +$this->registerMeta(['name' => 'keywords', 'content' => 'ecommerce, products, online shop']); + +// Open Graph tags +$this->registerMeta(['property' => 'og:title', 'content' => $title]); +$this->registerMeta(['property' => 'og:description', 'content' => $description]); +$this->registerMeta(['property' => 'og:image', 'content' => $product['image']]); + +// CSS files +$this->registerCssFile('/css/product.css'); +$this->registerCssFile('/css/responsive.css', WebView::POSITION_HEAD, [ + 'media' => 'screen and (max-width: 768px)', +]); + +// JavaScript files +$this->registerJsFile('/js/product-gallery.js', WebView::POSITION_END); +$this->registerJsFile('/js/shopping-cart.js', WebView::POSITION_END); + +// JavaScript variables +$this->registerJsVar('productData', $product); +$this->registerJsVar('cartApiUrl', '/api/cart'); + +// Inline JavaScript +$this->registerJs(' + document.addEventListener("DOMContentLoaded", function() { + initProductGallery(); + initShoppingCart(); + }); +', WebView::POSITION_END); + +// Page-specific styles +$this->registerCss(' + .product-special { + background: linear-gradient(45deg, #ff6b6b, #4ecdc4); + padding: 20px; + border-radius: 10px; + } +', WebView::POSITION_HEAD); +?> + +
+ +
+``` + +### Conditional Resource Loading + +Load resources based on conditions: + +```php +registerCssFile('/css/dark-theme.css'); +} else { + $this->registerCssFile('/css/light-theme.css'); +} + +// Admin-specific resources +if ($isAdmin) { + $this->registerCssFile('/css/admin-toolbar.css'); + $this->registerJsFile('/js/admin-functions.js'); +} + +// Role-based JavaScript configuration +$this->registerJsVar('userPermissions', [ + 'canEdit' => in_array($userRole, ['admin', 'editor']), + 'canDelete' => $userRole === 'admin', + 'canPublish' => in_array($userRole, ['admin', 'publisher']), +]); +?> +``` + +## Best Practices + +1. **Use appropriate positions**: Place CSS in `POSITION_HEAD`, JavaScript + at `POSITION_END` +2. **Minimize inline resources**: Prefer external files for better caching +3. **Use keys for duplicates**: Prevent duplicate resources with meaningful + keys +4. **Optimize loading**: Use `async` and `defer` attributes for non-critical + JavaScript +5. **Group related resources**: Keep related CSS and JS files together +6. **Use CDNs wisely**: Balance performance with reliability +7. **Validate meta tags**: Ensure proper SEO meta tags are set +8. **Consider security**: Be careful with inline scripts and CSP policies + +## Working with Asset Bundles + +For more complex asset management, consider using asset bundles: + +```php +// Register an asset bundle (covered in detail in the Assets guide) +$assetBundle = $this->assetManager->register(MainAsset::class); + +// Add all CSS files from the bundle +$this->addCssFiles($this->assetManager->getCssFiles()); + +// Add all JavaScript files from the bundle +$this->addJsFiles($this->assetManager->getJsFiles()); +``` diff --git a/src/pt-BR/guide/views/template-engines.md b/src/pt-BR/guide/views/template-engines.md new file mode 100644 index 00000000..9d15ee9f --- /dev/null +++ b/src/pt-BR/guide/views/template-engines.md @@ -0,0 +1,207 @@ +# Template engines + +Yii3 supports multiple template engines through a flexible renderer +system. By default, PHP is used as the template engine, but you can easily +add support for other engines like Twig and +[Blade](https://github.com/lee-to/yii-blade), or create your own custom +renderers. + +PHP templates were described in the "[View](view.md)" guide section. + +## Twig Template Engine + +Twig is a modern template engine that provides a more designer-friendly +syntax. To use Twig in your Yii3 application, you need to install the Twig +extension. + +```bash +composer require yiisoft/view-twig +``` + +Now you can use `.twig` templates. For example, `views/site/about.twig`: + +```twig +{# Variable type hints for IDE support #} +{# @var user \App\Entity\User #} +{# @var posts \App\Entity\Post[] #} + + +``` + +### Twig Features + +**Automatic Escaping**: Twig automatically escapes variables for HTML context: + +```twig +{# Automatically escaped #} +

{{ title }}

+ +{# Raw output (use carefully) #} +
{{ content|raw }}
+``` + +**Filters and Functions**: Twig provides many built-in filters and functions: + +```twig +{# Date formatting #} + + +{# String manipulation #} +

{{ description|truncate(100) }}

+ +{# URL generation #} +Profile +``` + +**Template Inheritance**: Twig supports template inheritance: + +**views/layout/main.twig** +```twig + + + + {% block title %}Default Title{% endblock %} + + +
+ {% block content %}{% endblock %} +
+ + +``` + +**views/site/about.twig** +```twig +{% extends "layout/main.twig" %} + +{% block title %}About Us{% endblock %} + +{% block content %} +

About Our Company

+

Welcome to our website!

+{% endblock %} +``` + +### Rendering Twig Templates + +Use Twig templates the same way as PHP templates: + +```php +// In your controller +public function about(): ResponseInterface +{ + return $this->viewRenderer->render('about.twig', [ + 'user' => $this->getCurrentUser(), + 'posts' => $this->getRecentPosts(), + ]); +} +``` + +## Custom Template Engines + +You can create custom template engines by implementing the +`TemplateRendererInterface`: + +```php + $value) { + $content = str_replace("{{$key}}", (string) $value, $content); + } + + return $this->parser->parse($content); + } +} +``` + +Register your custom renderer: + +```php +use Yiisoft\Container\Reference; + +// In configuration +'yiisoft/view' => [ + 'renderers' => [ + 'md' => Reference::to(App\View\MarkdownRenderer::class), + ], +], +``` + +Now you can use `.md` template files: + +**views/content/help.md** +```markdown +# Help: {{title}} + +Welcome, {{username}}! + +This is a Markdown template with **bold** and *italic* text. + +- Feature 1 +- Feature 2 +- Feature 3 +``` + +## Choosing the Right Template Engine + +**Use PHP templates when:** +- You need maximum flexibility and performance +- Your team is comfortable with PHP +- You want to leverage existing PHP knowledge +- You need complex logic in templates (though this should be minimized) + +**Use Twig templates when:** +- You want stricter separation between logic and presentation +- You work with designers who prefer cleaner syntax +- You need automatic escaping and security features +- You want template inheritance and advanced features + +**Use custom templates when:** +- You have specific requirements not met by PHP or Twig +- You're working with specialized content formats +- You need integration with external template systems + +## Best Practices + +1. **Keep templates simple**: Move complex logic to controllers or services +2. **Always escape output**: Prevent XSS attacks by properly escaping + variables +3. **Use meaningful names**: Name your templates and variables clearly +4. **Organize templates**: Group related templates in subdirectories +5. **Document variables**: Always add type hints for better IDE support +6. **Avoid business logic**: Keep business logic in models and services diff --git a/src/pt-BR/guide/views/view-injections.md b/src/pt-BR/guide/views/view-injections.md new file mode 100644 index 00000000..5a7e5f03 --- /dev/null +++ b/src/pt-BR/guide/views/view-injections.md @@ -0,0 +1,116 @@ +# View injections + +The view injections are designed to provide a standardized way to pass +parameters to the common layer of views in an application. It allows +developers to manage the data that will be available across various views, +ensuring flexibility and reusability of code. + +The view injections could be used if you require `yiisoft/yii-view-renderer` +package: + + +```sh +composer require yiisoft/yii-view-renderer +``` + +## Configuration + +In config `params.php`: + + +```php +... +'yiisoft/yii-view' => [ + 'injections' => [ + Reference::to(ContentViewInjection::class), + Reference::to(CsrfViewInjection::class), + Reference::to(LayoutViewInjection::class), + ], + ], +``` + +## New injections + +Start by defining a class that will implement the +`Yiisoft\Yii\View\Renderer\CommonParametersInjectionInterface`. This class +will be responsible for providing the parameters you want to inject into +your view templates and layouts. + +```php +class MyCustomParametersInjection implements Yiisoft\Yii\View\Renderer\CommonParametersInjectionInterface +{ + // Class properties and methods will go here + + public function __construct(UserService $userService) + { + $this->userService = $userService; + } + + public function getCommonParameters(): array + { + return [ + 'siteName' => 'My Awesome Site', + 'currentYear' => date('Y'), + 'user' => $this->userService->getCurrentUser(), + ]; + } +} +``` + +Add your new Injection to `params.php`: + +```php +'yiisoft/yii-view' => [ + 'injections' => [ + ..., + Reference::to(MyCustomParametersInjection::class), + ], + ], +``` + +## Using Separate Injections for Different Layouts + +If your application has multiple layouts, you can create separate parameter +injections for each layout. This approach allows you to tailor the +parameters injected into each layout according to its specific needs, +enhancing the flexibility and maintainability of your application. + +Create your custom ViewInjection for a specific layout: + +```php +readonly final class CartViewInjection implements CommonParametersInjectionInterface +{ + public function __construct(private Cart $cart) + { + } + + public function getCommonParameters(): array + { + return [ + 'cart' => $this->cart, + ]; + } +} +``` + +Add your new injection to `params.php` under specific layout name. In the +following example, it's `@layout/cart`: + +```php +'yiisoft/yii-view' => [ + 'injections' => [ + ..., + Reference::to(MyCustomParametersInjection::class), + DynamicReference::to(static function (ContainerInterface $container) { + $cart = $container + ->get(Cart::class); + + return new LayoutSpecificInjections( + '@layout/cart', // layout name for injection + + new CartViewInjection($cart) + ); + }), + ], + ], +``` diff --git a/src/pt-BR/guide/views/view.md b/src/pt-BR/guide/views/view.md new file mode 100644 index 00000000..a68cf1c9 --- /dev/null +++ b/src/pt-BR/guide/views/view.md @@ -0,0 +1,316 @@ +# Views + +View is responsible for presenting data to end users. You give it a template +with some placeholders and presentation logic and some data. The view is +passing data to the template executing template logic. The end result is +ready to be passed to end user, be it a browser, a file to download, an +email to send or something else. + +```mermaid +flowchart LR + A[Data] --> V[View] + B[Template] --> V + V --> C[HTML] + C --> D[Browser] +``` + +In Yii3 views are typically PHP files that contain presentation logic and +HTML markup. The view system provides a flexible way to organize your +presentation layer and supports features like layouts and partial +views. Instead of using plain PHP templates, you can leverage one of the +template engines such as [Twig](template-engines.md) or +[Blade](https://github.com/lee-to/yii-blade). + +## Installation + +For basic view functionality, you need the `yiisoft/view` package: + +```sh +composer require yiisoft/view +``` + +For web applications, you should also install the +`yiisoft/yii-view-renderer` package which provides +[PSR-7](https://www.php-fig.org/psr/psr-7/) compatibility and web-specific +features: + +```sh +composer require yiisoft/yii-view-renderer +``` + +These packages are included by default in the `yiisoft/app` application +template. + +## Basic Concepts + +A view template file contains presentation logic. In the `yiisoft/app` +template, view files are typically stored alongside their controllers (e.g., +`src/Web/Echo/Action.php`). Here's a simple view file example, +`src/Web/Echo/template.php`: + +```php + + +

The message is:

+``` + +Here `$message` is a view data that is passed when you render a template +with the help of `WebViewRenderer`. For example, `src/Web/Echo/Action.php`: + +```php +viewRenderer->render(__DIR__ . '/template', [ + 'message' => $message, + ]); + } +} +``` + +First argument of the `render()` method is a path to the template file. In +the `yiisoft/app`, template files are typically stored alongside their +actions. The result is ready to be rendered to the browser so we return it +immediately. + +## Working with layouts + +Most web applications use a common layout for all pages. In the +`yiisoft/app` template, layouts are stored in `src/Web/Shared/Layout/Main/` +directory. You can set a default layout in `config/common/params.php`: + +```php +return [ + 'yiisoft/yii-view-renderer' => [ + 'viewPath' => null, + 'layout' => '@src/Web/Shared/Layout/Main/layout.php', + ], +]; +``` + +A typical layout file such as `src/Web/Shared/Layout/Main/layout.php` looks +like this: + +```php +register(MainAsset::class); + +$this->addCssFiles($assetManager->getCssFiles()); +$this->addCssStrings($assetManager->getCssStrings()); +$this->addJsFiles($assetManager->getJsFiles()); +$this->addJsStrings($assetManager->getJsStrings()); +$this->addJsVars($assetManager->getJsVars()); + +$this->beginPage() +?> + + + + + + + <?= Html::encode($this->getTitle()) ?> + head() ?> + + +beginBody() ?> + + + +
+ +
+ + + +endBody() ?> + + +endPage() ?> +``` + +In the template above `$applicationParams` is an array of parameters from +`config/common/application.php`. + +`$aliases` refers to [aliases component](../concept/aliases.md) that is used +to get the base URL of the application at the server for URLs. + +`$this` is an instance of the view that we use to get page title and output +assets. Both standard and custom. + +With `$assetManager->register(MainAsset::class);` we register an asset that defines `css` to include to the page. It is +automatically copied to `public/assets` on first use. It is not very useful for a single CSS file but becomes handy as +the number of assets grows. + +> [!IMPORTANT] +> No output in plain PHP templates is encoded you should not forget to use `Html::encode()` to prevent +XSS security vulnerabilities. + +More about what's available in layout could be read in +[yiisoft/view](https://github.com/yiisoft/view) documentation. + +### Rendering without layout + +Sometimes you need to render a view without a layout (for example, for AJAX +responses): + +```php +public function ajaxContent(): ResponseInterface +{ + return $this->viewRenderer + ->withLayout(null) + ->render('ajax-content', ['data' => $data]); +} + +// Or use the renderPartial method +public function ajaxContent(): ResponseInterface +{ + return $this->viewRenderer->renderPartial('ajax-content', ['data' => $data]); +} +``` + +## Nested Views and Partials + +### Rendering Sub-views + +You can render other views from within a view using the `$this->render()` method: + +```php + +
+ + render('_post_item', ['post' => $post]) ?> + +
+``` + +**src/Web/Post/_item.php** +```php + +
+

getTitle()) ?>

+

getExcerpt()) ?>

+ +
+``` + +### Using Blocks + +Blocks allow you to define content in one view and display it in another, +typically in layouts: + +```php +// In a view file +setBlock('sidebar', $this->render('_sidebar', ['items' => $sidebarItems])) ?> + +// In the layout file +hasBlock('sidebar')): ?> + + +``` + +## Rendering as String + +If you need the rendered content as a string instead of a PSR-7 response: + +```php +public function getEmailContent(): string +{ + return $this->viewRenderer->renderAsString('email/welcome', [ + 'user' => $user, + ]); +} +``` + +## View Events + +The view system triggers events during the rendering process that you can +listen to: + +```php +use Yiisoft\View\Event\WebView\BeforeRender; +use Yiisoft\View\Event\WebView\AfterRender; + +// Example event listener +final class ViewEventListener +{ + public function onBeforeRender(BeforeRender $event): void + { + // Add global CSS class based on view name + if (str_contains($event->getFile(), 'admin/')) { + $event->getView()->registerCssClass('admin-view'); + } + } + + public function onAfterRender(AfterRender $event): void + { + // Log rendering time + $this->logger->info('View rendered', [ + 'view' => $event->getFile(), + 'time' => $event->getRenderTime(), + ]); + } +} +``` diff --git a/src/pt-BR/guide/views/widget.md b/src/pt-BR/guide/views/widget.md new file mode 100644 index 00000000..9242128a --- /dev/null +++ b/src/pt-BR/guide/views/widget.md @@ -0,0 +1,767 @@ +# Widgets + +Widgets are reusable, self-contained components that encapsulate complex +HTML generation logic. They provide a clean way to create configurable UI +elements that can be used across different views and applications. Yii3 +provides a flexible widget system through the `yiisoft/widget` package. + +## Installation + +The widget functionality is provided by the `yiisoft/widget` package: + +```bash +composer require yiisoft/widget +``` + +For ready-made widgets (like forms, navigation, etc.), you can also install: + +```bash +composer require yiisoft/yii-widgets +``` + +These packages are included by default in the `yiisoft/app` application +template. + +## Basic Concepts + +### Widget Class + +A widget is a PHP class that extends the abstract `Widget` class and +implements a `render()` method that returns HTML content as a string. + +### Widget Factory + +The `WidgetFactory` is responsible for creating widget instances and can +inject dependencies through the DI container. + +### Widget Configuration + +Widgets can be configured with properties and methods, making them highly +customizable and reusable across different contexts. + +## Creating Custom Widgets + +### Simple Widget + +Here's a basic widget that displays an alert message: + +```php +message = $message; + return $new; + } + + public function type(string $type): self + { + $new = clone $this; + $new->type = $type; + return $new; + } + + public function closeable(bool $closeable = true): self + { + $new = clone $this; + $new->closeable = $closeable; + return $new; + } + + protected function render(): string + { + if (empty($this->message)) { + return ''; + } + + $classes = ['alert', 'alert-' . $this->type]; + + if ($this->closeable) { + $classes[] = 'alert-dismissible'; + } + + $content = Html::encode($this->message); + + if ($this->closeable) { + $content .= Html::button('×', [ + 'type' => 'button', + 'class' => 'btn-close', + 'data-bs-dismiss' => 'alert', + ]); + } + + return Html::div($content, ['class' => implode(' ', $classes)]); + } +} +``` + +### Using the Widget + +```php + + +
+ message('Operation completed successfully!') + ->type('success') + ->closeable() ?> + + message('Please review the form errors below.') + ->type('danger') ?> +
+``` + +### Widget with Dependencies + +Widgets can use dependency injection for services: + +```php +userService->getCurrentUser(); + + if ($currentUser === null) { + return $this->renderLoginLink(); + } + + return $this->renderUserMenu($currentUser); + } + + private function renderLoginLink(): string + { + return Html::a('Login', $this->urlGenerator->generate('login'), [ + 'class' => 'btn btn-primary', + ]); + } + + private function renderUserMenu($user): string + { + $items = [ + Html::a('Profile', $this->urlGenerator->generate('user.profile'), [ + 'class' => 'dropdown-item', + ]), + Html::a('Settings', $this->urlGenerator->generate('user.settings'), [ + 'class' => 'dropdown-item', + ]), + '', + Html::a('Logout', $this->urlGenerator->generate('logout'), [ + 'class' => 'dropdown-item', + ]), + ]; + + return Html::div( + Html::button( + Html::encode($user->getName()) . ' ', + [ + 'class' => 'btn btn-secondary dropdown-toggle', + 'type' => 'button', + 'data-bs-toggle' => 'dropdown', + ] + ) . + Html::div(implode('', $items), ['class' => 'dropdown-menu']), + ['class' => 'dropdown'] + ); + } +} +``` + +## Widget Factory Setup + +### Bootstrap Configuration + +Initialize the widget factory in your application bootstrap: + +**config/bootstrap.php** +```php + [ + 'type()' => ['info'], + 'closeable()' => [true], + ], + App\Widget\CardWidget::class => [ + 'headerClass()' => ['card-header bg-primary text-white'], + ], +]; + +WidgetFactory::initialize($container, $widgetDefaults); +``` + +### DI Container Configuration + +**config/web/di.php** +```php +use App\Widget\AlertWidget; +use App\Widget\UserMenuWidget; + +return [ + // Widget configurations can be defined here if needed + AlertWidget::class => static fn() => new AlertWidget(), + + UserMenuWidget::class => static fn( + App\Service\UserService $userService, + Yiisoft\Router\UrlGeneratorInterface $urlGenerator + ) => new UserMenuWidget($userService, $urlGenerator), +]; +``` + +## Advanced Widget Examples + +### Data List Widget + +A widget that displays a list of items with pagination: + +```php +paginator = $paginator; + return $new; + } + + public function itemRenderer(callable $renderer): self + { + $new = clone $this; + $new->itemRenderer = $renderer; + return $new; + } + + public function containerClass(string $class): self + { + $new = clone $this; + $new->containerClass = $class; + return $new; + } + + public function itemClass(string $class): self + { + $new = clone $this; + $new->itemClass = $class; + return $new; + } + + public function emptyText(string $text): self + { + $new = clone $this; + $new->emptyText = $text; + return $new; + } + + protected function render(): string + { + if ($this->paginator === null) { + return ''; + } + + $items = $this->paginator->read(); + + if (empty($items)) { + return Html::div($this->emptyText, ['class' => 'empty-message']); + } + + $itemsHtml = ''; + foreach ($items as $item) { + $content = $this->itemRenderer + ? ($this->itemRenderer)($item) + : Html::encode((string) $item); + + $itemsHtml .= Html::div($content, ['class' => $this->itemClass]); + } + + return Html::div($itemsHtml, ['class' => $this->containerClass]); + } +} +``` + +Usage: + +```php + + +paginator($postPaginator) + ->containerClass('posts-list row') + ->itemClass('col-md-4 mb-3') + ->itemRenderer(function ($post) { + return $this->render('_post_card', ['post' => $post]); + }) ?> +``` + +### Form Widget + +A widget that simplifies form rendering: + +```php +model = $model; + return $new; + } + + public function action(string $action): self + { + $new = clone $this; + $new->action = $action; + return $new; + } + + public function method(string $method): self + { + $new = clone $this; + $new->method = $method; + return $new; + } + + public function options(array $options): self + { + $new = clone $this; + $new->options = $options; + return $new; + } + + public function field(string $attribute, array $options = []): self + { + $new = clone $this; + $new->fields[$attribute] = $options; + return $new; + } + + protected function render(): string + { + if ($this->model === null) { + return ''; + } + + $formOptions = array_merge([ + 'action' => $this->action, + 'method' => $this->method, + 'class' => 'form', + ], $this->options); + + $content = ''; + foreach ($this->fields as $attribute => $options) { + $content .= $this->renderField($attribute, $options); + } + + return Html::form($content, $formOptions); + } + + private function renderField(string $attribute, array $options): string + { + $label = $options['label'] ?? ucfirst($attribute); + $type = $options['type'] ?? 'text'; + $class = $options['class'] ?? 'form-control'; + + $field = Html::div( + Html::label($label, null, ['class' => 'form-label']) . + Html::input($type, $attribute, $this->getModelValue($attribute), [ + 'class' => $class, + 'id' => $attribute, + ]), + ['class' => 'mb-3'] + ); + + return $field; + } + + private function getModelValue(string $attribute): mixed + { + return $this->model->getAttributeValue($attribute); + } +} +``` + +### Breadcrumb Widget + +A widget for navigation breadcrumbs: + +```php +items = $items; + return $new; + } + + public function separator(string $separator): self + { + $new = clone $this; + $new->separator = $separator; + return $new; + } + + public function options(array $options): self + { + $new = clone $this; + $new->options = $options; + return $new; + } + + protected function render(): string + { + if (empty($this->items)) { + return ''; + } + + $links = []; + $itemCount = count($this->items); + + foreach ($this->items as $index => $item) { + if ($index === $itemCount - 1) { + // Last item (current page) - no link + $links[] = Html::span($item['label'], ['class' => 'breadcrumb-item active']); + } else { + // Regular breadcrumb item with link + $url = isset($item['url']) + ? (is_array($item['url']) + ? $this->urlGenerator->generate($item['url'][0], $item['url'][1] ?? []) + : $item['url']) + : '#'; + + $links[] = Html::span( + Html::a($item['label'], $url), + ['class' => 'breadcrumb-item'] + ); + } + } + + $options = array_merge(['class' => 'breadcrumb'], $this->options); + + return Html::nav( + Html::ol(implode('', $links), ['class' => 'breadcrumb']), + $options + ); + } +} +``` + +## Widget Best Practices + +### Configuration Pattern + +Use immutable configuration methods: + +```php +public function someProperty($value): self +{ + $new = clone $this; + $new->someProperty = $value; + return $new; +} +``` + +### Validation + +Validate widget configuration in the render method: + +```php +protected function render(): string +{ + if (empty($this->items)) { + throw new InvalidArgumentException('Items cannot be empty.'); + } + + // ... render logic +} +``` + +### HTML Encoding + +Always encode user data: + +```php +protected function render(): string +{ + return Html::div(Html::encode($this->userContent), [ + 'class' => 'user-content', + ]); +} +``` + +### Asset Management + +Register widget-specific assets: + +```php +assetManager->register(ChartWidgetAsset::class); + + // Render widget content + return $this->renderChart(); + } +} +``` + +## Using Widgets in Layouts + +Widgets are particularly useful in layouts for common UI elements: + +**views/layout/main.php** +```php + + + + + + + +
+ + +
+ +
+ +
+ +
+ +
+ + +``` + +## Testing Widgets + +### Unit Testing + +Test widget rendering logic: + +```php +message('Test message') + ->type('success'); + + $output = $widget->render(); + + $this->assertStringContainsString('Test message', $output); + $this->assertStringContainsString('alert-success', $output); + } + + public function testRenderEmpty(): void + { + $widget = AlertWidget::widget(); + $output = $widget->render(); + + $this->assertEmpty($output); + } +} +``` + +## Common Widget Patterns + +### Conditional Rendering + +```php +protected function render(): string +{ + if (!$this->shouldRender()) { + return ''; + } + + return $this->doRender(); +} + +private function shouldRender(): bool +{ + return !empty($this->items) && $this->isVisible; +} +``` + +### Template-based Rendering + +```php +protected function render(): string +{ + return $this->renderTemplate('widget-template', [ + 'items' => $this->items, + 'options' => $this->options, + ]); +} + +private function renderTemplate(string $template, array $data): string +{ + // Use a view renderer to render template files + return $this->viewRenderer->renderPartialAsString($template, $data); +} +``` + +### Event Integration + +```php +protected function render(): string +{ + $event = new BeforeWidgetRender($this); + $this->eventDispatcher->dispatch($event); + + $content = $this->doRender(); + + $afterEvent = new AfterWidgetRender($this, $content); + $this->eventDispatcher->dispatch($afterEvent); + + return $afterEvent->getContent(); +} +``` + +Widgets provide a powerful way to create reusable, configurable UI +components in Yii3 applications. They help maintain clean separation of +concerns and make your views more maintainable and testable. diff --git a/src/pt-BR/index.md b/src/pt-BR/index.md new file mode 100644 index 00000000..9bc6dff5 --- /dev/null +++ b/src/pt-BR/index.md @@ -0,0 +1,39 @@ +--- +features: + - + details: 'O Yii oferece o máximo de funcionalidade com o mínimo possível de sobrecarga.' + icon: '' + title: Rápido + - + details: 'Padrões sensatos e ferramentas embutidas ajudam você a escrever código sólido e seguro.' + icon: '' + title: Seguro + - + details: 'Escreva mais código em menos tempo com APIs simples e poderosas e com geração de código.' + icon: '' + title: Eficiente +hero: + actions: + - + link: guide/intro/what-is-yii.html + text: 'Comece agora' + theme: brand + class: homeHero2 + image: + alt: Yii + src: /images/yii_logo.svg + name: 'Yii3 Framework' + tagline: 'Um framework simples, poderoso e rápido. Conheça o guia definitivo e moderno do Yii que você sempre quis.' + text: Documentação +layout: home +--- + +

+ +- [Guia definitivo](guide/) — o guia completo que cobre todos os aspectos do + framework. +- [Cookbook da comunidade](cookbook/) — uma coleção de dicas, truques e + soluções da comunidade para tarefas comuns no desenvolvimento com Yii. +- [Detalhes internos](internals/) — documentação para quem contribui com o + próprio framework Yii, incluindo diretrizes, fluxos de trabalho e boas + práticas. diff --git a/src/pt-BR/internals/000-packages.md b/src/pt-BR/internals/000-packages.md new file mode 100644 index 00000000..b8f9434a --- /dev/null +++ b/src/pt-BR/internals/000-packages.md @@ -0,0 +1,84 @@ +# 000 — Packages + +Yii3 team divided the framework into several packages that conform to the +following agreements. + +For all packages, the GitHub repository name exactly matches the Packagist +package name. + +For a full list of packages and their building status, see [status page at +yiiframework.com](https://www.yiiframework.com/status/3.0). + +## Yii-specific packages (framework and extensions) + +- named `yiisoft/yii-something` or more specific: `yii-type-something` e.g.: + - modules: `yii-module-users`, `yii-module-pages` + - themes: `yii-theme-adminlte`, `yii-theme-hyde` + - widgets: `yii-widget-datepicker` + - ... +- titled as "Yii Framework ..." +- may have any dependencies and Yii-specific code + +## General purpose packages (libraries) + +- you can use these independently of Yii Framework +- named as `yiisoft/something` without yii-prefix +- titled as "Yii ..." +- must not have dependencies on any Yii-specific packages +- should have as fewer dependencies as possible + +## Configs and defaults + +The following applies to both Yii-specific packages and general purpose +packages: + +- Package may have `config` directory with Yii-specific defaults. +- Package may have "config-plugin" in "extra" section of `composer.json`. +- Package mustn't have dependencies in `require` section of `composer.json` + that are used in `config` only. +- You should namespace parameters with `vendor/package-name`: + +```php +return [ + 'vendor/package-name' => [ + 'param1' => 1, + 'param2' => 2, + ], +]; +``` + +## Versions + +All packages follow [SemVer](https://semver.org/) versioning: + +- `x.*.*` - incompatible API changes. +- `*.x.*` - add functionality (backwards-compatible). +- `*.*.x` - bug fixes (backwards-compatible). + +The first stable version should be 1.0.0. + +Each package version number doesn't depend on any other package version or +framework name/version, only on its own public contract. The framework as a +whole has the "Yii3" name. + +It's alright to use packages with different major versions together, as long +as they're compatible. + +## PHP versions support + +The support of PHP versions supported for a package depends on [PHP versions +life cycle](https://www.php.net/supported-versions.php). + +- Package versions with active support MUST support all PHP versions that + have active support. +- Both packages and application templates MUST have supported versions that + receive bug and security fixes. These SHOULD correspond to PHP versions + receiving security fixes. +- Packages and application templates MIGHT have supported versions that work + with unsupported PHP versions. +- Bumping the minimal PHP version in a package or an application template is + a minor change. + +## composer.json + +A logical OR operator in version ranges MUST use double pipe (`||`). For example: `"yiisoft/arrays": "^1.0 || ^2.0"`. diff --git a/src/pt-BR/internals/001-yii-values.md b/src/pt-BR/internals/001-yii-values.md new file mode 100644 index 00000000..b69a77e2 --- /dev/null +++ b/src/pt-BR/internals/001-yii-values.md @@ -0,0 +1,82 @@ +# 001 — Yii goal and values + +## Goal + +The Yii project aims to build and support _practical_ and _helpful_ tools +and community. + +## Values + +The values we express in our work support the goal. We try to + +- Be practical + - [High performance](#high-performance) + - [Sensible defaults and + flexibility](#sensible-defaults-and-flexibility) + - [Be practice-oriented](#be-practice-oriented) +- Be helpful + - [Be simple](#be-simple) + - [Be explicit](#be-explicit) + - [Be consistent](#be-consistent) + +## Be practical + +### High performance + +Performance is a necessary condition of practicality. Software shouldn't +waste machine resources or human resources. + +### Sensible defaults and flexibility + +We prefer sensible defaults and conventions that users can customize. We +seek a balance between flexibility, discipline and simplicity that meets +common needs. + +### Be practice-oriented + +We prefer practice to theory. For example: + +- Solutions for known use cases should avoid excess complexity by providing + only necessary flexibility. +- Standard implementations should take practical use into account. +- Experience is at least as useful as theory in guiding design. +- Context is critical in determining appropriateness. + +## Be helpful + +This value guides technical decisions as well as community activity. +Consideration of how software features help users should guide development. +Community-wise, we value any helpful contribution, be it a pull request or +an answer in the forum. + +When the other principles conflict, we choose a solution that's more helpful +to the community. + +### Be simple + +Solutions should be simple and expressive: + +- We use as much complexity as needed and no more. +- We avoid ugly solutions unless there is no alternative. +- Fewer rules are better than more rules. + +### Be Explicit + +We prefer explicit, obvious solutions and code. Solutions should clearly +express exactly what they do. For example: + +- A straightforward solution is better than an abstract one unless the + abstraction has a practical purpose. +- Loud fails are better than silent fails or masking errors. +- Explicit casts are better than PHP type juggling, type hints are good. +- No magic unless necessary. + +### Be consistent + +We try to be consistent in: + +- Code style +- Naming +- Design +- Structure +- Values and goals diff --git a/src/pt-BR/internals/002-issue-workflow.md b/src/pt-BR/internals/002-issue-workflow.md new file mode 100644 index 00000000..58f8df1c --- /dev/null +++ b/src/pt-BR/internals/002-issue-workflow.md @@ -0,0 +1,27 @@ +# 002 — Issue workflow + +The process of handing incoming issues is the following: + +![Issue workflow schema](/images/internals/002-issue-workflow.svg) + +## Roles + +We've many roles: + +- Process managers - initially triage issues and manage labels. +- Decision makers - participate in discussions moving them to resolutions. +- Bug hunters - verifying bugs. +- Contributors - create code for pull requests. +- Code reviewers - review pull requests. + +A single person may take one or more roles in the issue-resolving process. + +## Labels + +We label issues to mark many things: current status, issue type, component +affected. Status labels speak for themselves. + +## Milestones + +Issues aren't assigned to milestones unless they're critical or there is a +likely good pull request exists. diff --git a/src/pt-BR/internals/003-roadmap.md b/src/pt-BR/internals/003-roadmap.md new file mode 100644 index 00000000..92cb78f0 --- /dev/null +++ b/src/pt-BR/internals/003-roadmap.md @@ -0,0 +1,207 @@ +# 003 — Roadmap + +We want Yii 3 to: + +- Not limit a developer to choosing architecture. Allow anything from + "classic" MVC to DDD. +- Be based on the best practices such as SOLID, GRASP, etc. and teach them + to the community. +- Keep the most good things from Yii 2. +- Be more open to the global PHP community and infrastructure. + +## PSRs compliance + +PSR compliance helps with customizability, the ability to use general PHP +libraries and implement fewer wrappers. Here's the list of PSRs we want to +implement. + +### PSR-3 Logger + +Implemented as a [separate package that isn't dependent on a +framework](https://github.com/yiisoft/log). + +- [x] Framework packages should depend on interface only. +- [x] Split drivers into packages. +- [x] Clean-up code. +- [x] [Fix email target](https://github.com/yiisoft/log-target-email). + +### PSR-4 Autoloading + +- [x] Autoloading is fine already. +- [x] Document on how it works. + +### PSR-7 HTTP message + +- [x] Remove our own implementation. At least for now. +- [x] Framework packages should depend on interfaces only. + +### PSR-11 Container + +Implemented as a [separate package that isn't dependent on a +framework](https://github.com/yiisoft/di). + +- [x] Framework packages shouldn't use container directly. One should be + able to instantiate everything manually. +- [x] Finish refactoring. +- [x] Remove all framework-specific implementations from the package. Move + to a framework. +- [x] [Implement autoloader + fallback](https://github.com/yiisoft/di/issues/88) + +### PSR-12 Code style + +- [x] Make sure the code follows it. +- [x] Automate fixing style before release. + +### PSR-14 Event dispatcher + +- [x] [Implement as a separate + library](https://github.com/yiisoft/event-dispatcher). +- [x] Use in other packages. +- [x] Polish. + +### PSR-15 HTTP handlers + +- [x] Rewrite HTTP flow to PSR-7 request-response + formatting response via + emitter. +- [x] Offer SAPI emitter out of the box. +- [x] Make it possible to use alternative emitters such as RoadRunner. +- [x] Support middleware. +- [x] Implement filters as middleware: + - [x] [Rate limiting](https://github.com/yiisoft/yii-web/issues/63) + - [x] [Authentication](https://github.com/yiisoft/yii-web/issues/114) +- [x] Re-implement router w/ middleware support for route groups. +- [x] Filters should be middlewares. + +### PSR-16 Simple cache + +Implemented as a [separate package that isn't dependent on a +framework](https://github.com/yiisoft/cache). + +- [x] Framework packages should depend on interfaces only. +- [x] Split drivers into packages. +- [x] Clean-up code. + +### PSR-17 HTTP factories + +- [x] Use PSR factories. + +### PSR-18 HTTP client + +- [x] Remove our own implementation. At least for now. +- [x] Framework packages should depend on interfaces only. + +## Stricter types + +- [x] Make sure type hinting is used everywhere. +- [x] Make sure types are as definitive as possible. Avoid varying types if + possible. + +## Single application template + +- [x] Drop basic/advanced. +- [x] Create a [single application template that works out of the + box](https://github.com/yiisoft/app). + +## Router + +Implemented as a [separate package that isn't dependent on a +framework](https://github.com/yiisoft/router). + +- [x] DSL for configuration. +- [x] Ability to route to any callable. +- [x] Named routes. +- [x] Route groups w/ middleware support. + +## Best practices and SOLID compliance of all classes/packages + +- [x] Make sure interfaces follow the "interface segregation" principle. +- [x] Don't use public properties. +- [x] Don't use `init()`. +- [x] Don't inherit from `BaseObject` or `Component`. Remove these. +- [x] No globals. +- [x] No static calls except helpers that are final. +- [x] Prefer throwing exceptions to fixing input. + +## Development toolkit + +- [x] Release command line tool +- [x] Development command line tool (symlinks packages into usable + application) + +## Console + +- [x] Separate web and console application +- [x] Possibly eliminate base application (still needed) +- [x] Create an interface for the console (using Symfony one) +- [x] Implementation may be one of the popular ones (using Symfony one) +- [x] Ensure application can add commands via config + +## Documentação + +- [ ] Follow best practices. +- [ ] Don't use the "MVC" term. +- [ ] Upgrading from Yii 2. + +## RBAC + +RBAC is implemented as [a framework-independent +package](https://github.com/yiisoft/rbac). + +- [x] Finish refactoring. +- [x] Make sure it follows best practices. +- [x] Split drivers into packages. + +## View + +View is implemented as [framework-independent +package](https://github.com/yiisoft/view). + +- [x] Finish refactoring ([see + issues](https://github.com/yiisoft/view/issues)). +- [x] Port widgets. +- [x] Rethink and implement active form widgets. +- [x] Implement caching widgets. + +## Data abstractions and grid + +- [x] Finish [data abstractions](https://github.com/yiisoft/data). +- [x] Port sort, use data abstractions. Should be part of + [yii-dataview](https://github.com/yiisoft/yii-dataview). +- [x] Port paging, use data abstractions. Should be part of + [yii-dataview](https://github.com/yiisoft/yii-dataview). +- [x] Port grid, use data abstractions. Should be part of + [yii-dataview](https://github.com/yiisoft/yii-dataview). +- [x] Port list, use data abstractions. Should be part of + [yii-dataview](https://github.com/yiisoft/yii-dataview). + +## Validators + +- [x] Finish [the main package](https://github.com/yiisoft/validator) + redesign +- [x] Port necessary validators + +## Debug toolbar + +- [x] Port debug toolbar. + +## Gii + +- [x] Port Gii. + +## Infrastructure + +- [x] Cover [config](https://github.com/yiisoft/config) with tests. +- [x] Release stable [config](https://github.com/yiisoft/config). + +## Others + +- [x] [Decide on + namespaces](https://forum.yiiframework.com/t/lowercase-or-camelcase-namespaces/124983/52). +- [x] [Clean up error + handler](https://github.com/yiisoft/yii2/issues/14348). Make sure the + error handler catches fatals and is using response. +- [x] Make validators independent of models to allow reusing them in + handlers. +- [x] [Split + IdentityInterface](https://github.com/yiisoft/yii2/issues/13825). diff --git a/src/pt-BR/internals/004-namespaces.md b/src/pt-BR/internals/004-namespaces.md new file mode 100644 index 00000000..8f623dbd --- /dev/null +++ b/src/pt-BR/internals/004-namespaces.md @@ -0,0 +1,23 @@ +# 004 — Namespaces + +Package namespace rules are the following: + +1. PascalCase is used for namespace parts. +2. Root vendor namespace is `Yiisoft`. +3. Package name parts are used in namespace. +4. Adjective is added to a noun and is a single part. + + +Some examples: + +| Package | Namespace | +|----------------------------|---------------------------| +| yiisoft/yii-web | Yiisoft\Yii\Web | +| yiisoft/di | Yiisoft\Di | +| yiisoft/db-mysql | Yiisoft\Db\Mysql | +| yiisoft/friendly-exception | Yiisoft\FriendlyException | + +## References + +- [International forum + discussion](https://forum.yiiframework.com/t/use-yiisoft-as-a-root-namespace-instead-of-yii-for-yii-3-packages/125734) diff --git a/src/pt-BR/internals/005-development-tool.md b/src/pt-BR/internals/005-development-tool.md new file mode 100644 index 00000000..961d7e7e --- /dev/null +++ b/src/pt-BR/internals/005-development-tool.md @@ -0,0 +1,51 @@ +# 005 — Yii development tool + +For Yii3, the number of packages increased significantly to achieve more +reusability and independent releases. To ease development of the framework +itself, we've created a special tool available from +[yiisoft/yii-dev-tool](https://github.com/yiisoft/yii-dev-tool). + +``` +$ ./yii-dev + _ _ _ _ + | | | |(_)(_) Development Tool + | |_| || || | + \__, ||_||_| for Yii 3.0 + |___/ + +This tool helps with setting up a development environment for Yii 3 packages. + +Usage: + command [options] [arguments] + +Options: + -h, --help Display this help message + +Available commands: + checkout-branch Creates, if not exists, and checkout a git branch + commit Add and commit changes into each package repository + install Install packages + lint Check packages according to PSR12 standard + pull Pull changes from package repositories + push Push changes into package repositories + replicate Copy files specified in replicate.php into each package + status Show git status of packages + update Update packages +``` + +There are many commands available. The most important ones are `install` and +`update`. What it does is: + +1. Install/update all packages listed in + [`packages.php`](https://github.com/yiisoft/yii-dev-tool/blob/master/packages.php) + or individual package from that list if specified. +2. For every package installed check `vendor` directory for packages listed + in `packages.php`. If there is any, replace the package directory with a + symlink to another package source. + +As a result, you will have many packages using each other, so there is no +need to `git push` and `composer install` / `composer update` during +development. + +A [detailed example](https://github.com/yiisoft/yii-dev-tool#usage-example) +of using the tool is available in its README. diff --git a/src/pt-BR/internals/006-git-commit-messages.md b/src/pt-BR/internals/006-git-commit-messages.md new file mode 100644 index 00000000..18a29f3c --- /dev/null +++ b/src/pt-BR/internals/006-git-commit-messages.md @@ -0,0 +1,18 @@ +# 006 — Git commit messages + + +## Subject line + +- Use `#123` to reference issue by number +- Use imperative mood that's `Fix`, not `Fixed` +- Don't add a period at the end +- Use `[skip ci]` if there is no need to run unit tests +- Start with a capital letter +- Limit to 50 characters + +## Body + +Use the message body **if** you need an extra explanation. Explain why, not +how. + +- Limit line length to 72 characters diff --git a/src/pt-BR/internals/007-exceptions.md b/src/pt-BR/internals/007-exceptions.md new file mode 100644 index 00000000..f40cf62e --- /dev/null +++ b/src/pt-BR/internals/007-exceptions.md @@ -0,0 +1,16 @@ +# 007 — Exceptions + +- Throw exceptions instead of returning an error code. +- Exception class name must be suffixed with `Exception`. +- Use grammatically correct error messages including ending punctuation, + that's most exceptions must end with a period. +- `\InvalidArgumentException` must be used directly. There should be no + exceptions inherited from it. +- `\InvalidArgumentException` must never be caught. + +## References + +- [International community discussion and + poll](https://forum.yiiframework.com/t/naming-exceptions/126613/6) +- [Russian community discussion and + poll](https://yiiframework.ru/forum/viewtopic.php?f=39&t=51290) diff --git a/src/pt-BR/internals/008-interfaces.md b/src/pt-BR/internals/008-interfaces.md new file mode 100644 index 00000000..bfe91968 --- /dev/null +++ b/src/pt-BR/internals/008-interfaces.md @@ -0,0 +1,10 @@ +# 008 — Interfaces + +- Interface name should be suffixed with `Interface`. + +## References + +- [International community discussion and + poll](https://forum.yiiframework.com/t/naming-interfaces/126612/5) +- [Russian community discussion and + poll](https://yiiframework.ru/forum/viewtopic.php?f=39&t=51289) diff --git a/src/pt-BR/internals/009-design-decisions.md b/src/pt-BR/internals/009-design-decisions.md new file mode 100644 index 00000000..a9e0f54b --- /dev/null +++ b/src/pt-BR/internals/009-design-decisions.md @@ -0,0 +1,89 @@ +# 009 — Design Decisions + +In this document, we list important design decisions taken during Yii3 +development. + +## Remove magic properties + +Magic properties in Yii 2 were an interesting idea that allowed a developer +to start with public property and then seamlessly migrate to using +getter/setter called via magic methods without changing the code. + +The main reason for removal in Yii 3 is that it resulted in using public +properties everywhere, thus lack of encapsulation and code fragility. + +## Remove the service locator + +Service locator both Yii 1 and Yii 2 was convenient but was also abused a +lot. Although a dependency injection container was available in Yii 2, +service locator was generally preferred to cause both a dependency on the +service locator itself, high coupling, hard to test code. + +Yii 3 relies on dependency injection only lowering coupling significantly +and making code way more testable. + +## Extract general packages + +Yii 1 and Yii 2 were fully closed communities. All the code we had wasn't +useful outside Yii, and most of the "external" code wasn't useful in Yii +without wrappers. It was noted many times by communities external to Yii +that many parts of Yii are well-designed and unique, and they'd use these if +these were available as standalone packages. + +As part of Yii 3 packages such as cache, RBAC, view, etc. were extracted +into framework-independent packages. Benefits are: + +- Increased usage and contribution +- Yii team could delegate maintenance +- Independent releases are possible + +## Adopt PSRs + +The team adopted some PSRs in Yii 2, such as PSR-4 and PSR-2. Interfaces in +general weren't, although Yii is part of PHP-FIG. Mainly because when Yii 2 +was released, these were either in the making or not adopted enough. + +Yii3 benefits from PSRs since there are nowadays many ready-to-use libraries +that one can get via Composer: cache backends, middleware, loggers, DI +containers, etc. + +By implementing PSRs in general packages, we allow these to be used in more +projects, thus raising the contribution level. + +## Improve DI container + +The problem with the Yii 2 container was that it's tailored to be used with +Yii 2 components. API isn't well-designed to be used with general PHP +classes. + +In Yii3, we ensured that container can be used to conveniently configure any +PHP class. + +That should result in the absence of Yii-specific wrapper packages and more +direct usages of Composer packages. + +## Adopt strict types + +Strict types were introduced because: + +- PHP 7 is now mainstream +- While they solve no significant Yii 2 problems, they help to avoid many + day-to-day development issues + +## Adopt SemVer + +Yii 2 has its own version policy. Problems: + +- It wasn't standard +- Composer relies on SemVer +- It's hard to support a framework built on top of packages if the + versioning policy isn't strict + +## Prevent validators mutating data + +In Yii 1 and Yii 2, validators such as "date" were mutating data. It was +confusing for a validation process not initially meant to mutate data it +validates. + +[See related +discussion](https://forum.yiiframework.com/t/saving-or-killing-non-validation-in-validators/126086). diff --git a/src/pt-BR/internals/010-code-style.md b/src/pt-BR/internals/010-code-style.md new file mode 100644 index 00000000..3cf3869a --- /dev/null +++ b/src/pt-BR/internals/010-code-style.md @@ -0,0 +1,210 @@ +# 010 — Code style + +Code formatting used in Yii 3 packages is based on [PER Coding Style +3.0](https://www.php-fig.org/per/coding-style/) with extra rules added on +top of it. + +## Names + +- Use English only. +- Use camelCase notation, including abbreviations (e.g., `enableIdn`). +- Use the shortest possible, but an explanatory name. +- Never trim or abbreviate a name. +- Postfix classes, interfaces, traits and variables, which is a + [collection](https://en.wikipedia.org/wiki/Collection_(abstract_data_type)), + with `Collection`. +- Postfix middleware classes with `Middleware`. + +## Types + +- Declare [argument and return + types](https://www.php.net/manual/en/migration70.new-features.php) where + possible. +- [Use types for properties](https://wiki.php.net/rfc/typed_properties_v2). +- Use strict typing. Avoid mixed and union types where possible except + compatible types such as `string|Stringable`. + +## Comments + +Inline comments are to be avoided unless code couldn't be understood without +them. A good example is a workaround for a bug in a certain PHP version. + +Method comment is necessary except it adds nothing to what method name and +signature already has. + +Class comment should describe the purpose of the class. + +See [PHPDoc](014-docs.md#phpdoc). + +## Formatting + +### Line length + +The maximum line length is 120 characters. + +When a function or method call exceeds the limit, split arguments into +separate lines: + +```php +$this->assertSame( + ['' => ['Value must be no less than 5.']], + $result->getErrorMessagesIndexedByPath(), +); +``` + +### No alignment + +Property, variable and constant value assignments shouldn't be aligned. The +same applies to phpdoc tags. The reason is that aligned statements often +cause larger diff and even conflicts. + +```php +final class X +{ + const A = 'test'; + const BBB = 'test'; + + private int $property = 42; + private int $test = 123; + + /** + * @param int $number Just a number. + * @param array $options Well... options! + */ + public function doIt(int $number, array $options): void + { + $test = 123; + $anotherTest = 123; + } +} +``` + +### Chain calls + +Chained calls should be formatted for better readability. If it's a long +chain that doesn't fit the line length of 120 characters, then each call +should on a new line: + +```php +$object + ->withName('test') + ->withValue(87) + ->withStatus(Status::NEW) + ->withAuthor($author) + ->withDeadline($deadline); +``` + +If it's a short chain, it's alright for it to be on a single line: + +```php +$object = $object->withName('test'); +``` + +## Strings + +- When no variables involved, use `'Hello!'` +- To get variables into string prefer `"Hello, $username!"` + +## Classes and interfaces + +### Final by default + +Classes should be `final` by default. + +### Private by default + +Constants, properties and methods should be private by default. + +### Composition over inheritance + +Prefer [composition to inheritance](../guide/concept/di-container.md). + +### Property, constant and method order + +Order should be the following: + +- Constants +- Properties +- Methods + +Within each category, items should be sorted by visibility: + +- public +- protected +- private + +### Abstract classes + +Abstract classes *shouldn't* be prefixed or postfixed with `Abstract`. + +#### Immutable methods + +Immutable method convention is the following: + +```php +public function withName(string $name): self +{ + $new = clone $this; + $new->name = $name; + return $new; +} +``` + +1. Cloned object name is `$new`. +2. Return type is `self`. + +#### Boolean check methods + +Methods that are there to check if something is true should be named like +the following: + +```php +public function isDeleted(): bool; +public function hasName(): bool; +public function canDoIt(): bool; +``` + +#### Flags in methods + +Boolean flags in methods are better to be avoided. It's a sign the method +may be doing too much, and there should be two methods instead of one. + +```php +public function login(bool $refreshPage = true): void; +``` + +It is better to be two methods: + +```php +public function login(): void; +public function refreshPage(): void; +``` + +## Variables + +Add an underscore (`_`) prefix for unused variables. For example: + +```php +foreach ($items as $key => $_value) { + echo $key; +} +``` + +## Imports + +Prefer importing classes and functions to using fully qualified names: + +```php +use Yiisoft\Arrays\ArrayHelper; +use Yiisoft\Validator\DataSetInterface; +use Yiisoft\Validator\HasValidationErrorMessage; +use Yiisoft\Validator\Result; + +use function is_iterable; +``` + +## Additional conventions + +- [Namespaces](004-namespaces.md) +- [Exceptions](007-exceptions.md) +- [Interfaces](008-interfaces.md) diff --git a/src/pt-BR/internals/011-error-correction.md b/src/pt-BR/internals/011-error-correction.md new file mode 100644 index 00000000..8e2f2b46 --- /dev/null +++ b/src/pt-BR/internals/011-error-correction.md @@ -0,0 +1,5 @@ +# 011 — Error correction + +If it's unambiguous within a class what the developer who incorrectly used +the class meant, it's OK to correct the error. Otherwise, the error MUST +NOT be corrected. diff --git a/src/pt-BR/internals/012-tests.md b/src/pt-BR/internals/012-tests.md new file mode 100644 index 00000000..e09aa6d2 --- /dev/null +++ b/src/pt-BR/internals/012-tests.md @@ -0,0 +1,18 @@ +# 012 — Tests + +For each package, we're adding unit-tests that are run via +[PHPUnit](https://phpunit.de/). When designing tests, the following +guidelines should be taken into account. + +- Test class should be marked as `final` by default. +- `@test` annotation must not be used, prefix methods with `test`. +- The test method name must reflect the purpose of the test. +- "should" must not be used in the test method name. +- If necessary, the test method phpdoc may describe the desired behavior. +- The test must follow AAA: first arrange the necessary preconditions, then + act, then assert expected results. +- There must be one test case per test method that's a single AAA. +- Test must use public API. Private properties or methods shouldn't be + accessed, assumptions on internals of the class tested shouldn't be made. +- Tests shouldn't rely on composer-config-plugin and DI container unless + necessary. diff --git a/src/pt-BR/internals/013-code-review.md b/src/pt-BR/internals/013-code-review.md new file mode 100644 index 00000000..a363f954 --- /dev/null +++ b/src/pt-BR/internals/013-code-review.md @@ -0,0 +1,33 @@ +# 013 — Code review + +Code reviews are essential for the success of the project and are as +important as contributing code. + +Reviews are handled via GitHub pull requests. When the request is ready for +review, the "status: code review" label is added to it. + +[A full list of pull requests that need +review](https://github.com/search?q=org%3Ayiisoft+label%3A"status%3Acode+review"&state=open&type=Issues) +is available at GitHub. + +## Guidelines + +- Check out the pull request branch, open the project in the IDE, get a big + picture. +- Does the pull request make sense overall? +- Run tests and/or application using code from the pull request. Are these + OK? +- Read all lines of code in the pull request. +- Could it be done simpler? +- Are there security issues? +- Are there performance issues? +- When leaving comments, be polite. +- Avoid code-formatting comments. + +## Mandatory parts + +- [ ] Tests that fail without code and pass with code. +- [ ] Type hints. +- [ ] `declare(strict_types=1)`. +- [ ] Documentation: phpdoc, yiisoft/docs. +- [ ] Changelog entry (if package is stable). diff --git a/src/pt-BR/internals/014-docs.md b/src/pt-BR/internals/014-docs.md new file mode 100644 index 00000000..76c3ea24 --- /dev/null +++ b/src/pt-BR/internals/014-docs.md @@ -0,0 +1,223 @@ +# 014 — Documentation + +Documentation is one of the most important parts of Yii. + +## Package documentation + +Documentation for a package could either be in `README.md` or +`docs/{language}/{type}` where `{language}` is a language code and `{type}` +could be "guide," "cookbook" or something else. Usually `docs` is there if +the package usage or configuration isn't trivial or there's a need for +translation. + +Some indicators that it's time to create `docs`: + +1. There is a need for translation. +2. Many topics exist. Each of these is big by itself. + +If the total length of readme is less than about 200 lines, it's fine to +keep documentation in the readme. + +## Definitive guide + +The definitive guide, +[yiisoft/docs/guide](https://github.com/yiisoft/docs/tree/master/guide/en) +aims at covering usage of packages as a whole framework. Unlike package +documentation, it isn't focused on a single package but is covering certain +use-cases. + +The guide should follow [Microsoft style +guide](https://learn.microsoft.com/en-us/style-guide/welcome/). + +### Translation + +The definitive guide uses [po4a](https://github.com/mquinson/po4a) in GitHub Action for translations. + +Translation algorithm: + +- Install an application for working with `.po` translation files. For + example, [Poedit](https://poedit.net/), + [Lokalize](https://apps.kde.org/ru/lokalize/), + [Gtranslator](https://wiki.gnome.org/Apps/Gtranslator) or another. +- Find file what you want to translate in `_translations/guide/{lang}`. Note + that if the source file is in a subfolder, the subfolder name is appended + to the file name and separated by an underscore, for example, for + translating `guide/en/concept/aliases.md` file find + `_translations/guide/{lang}/concept_aliases.md.po` file. +- Open the file with the `.po` extension in `Poedit` from the folder with + the desired localization, for example + `_translations/guide/ru/intro_what-is-yii.md.po`. If there is no + localization yet, create an issue. +- Translate necessary strings and push the changes +- Open a pull request to the main repository + +> [!CAUTION] +> Do not change the translation in files in `/guide/{lang}` manually. + +If you have changed English and want to update translations: + +- Open a pull request to the main repository +- Pull updated branch after successful completion of workflow `Update docs + translation` in GitHub Action +- Update translation in `.po` files by `Poedit` +- Push changes + +## Blocks + +Blocks are in the [GitHub Alerts +format](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts): + +``` +> [!NOTE] +> Useful information that users should know, even when skimming content. + +> [!TIP] +> Helpful advice for doing things better or more easily. + +> [!IMPORTANT] +> Key information users need to know to achieve their goal. + +> [!WARNING] +> Urgent info that needs immediate user attention to avoid problems. + +> [!CAUTION] +> Advises about risks or negative outcomes of certain actions. +``` + +When translating documentation, these Block indicators should not be +translated. Keeps them intact as they are and only translate the block +content. For translating the label for the block, each guide translation +should have a `blocktypes.json` file containing the translations. The +following shows an example for German: + +```json +{ + "Note": "Hinweis", + "Tip": "Tipp", + "Important": "Wichtig", + "Warning": "Achtung", + "Caution": "Vorsicht" +} +``` + +## PHPDoc + +PHPDoc mustn't be added if it doesn't add anything to what it describes. The +following is a bad example: + +```php +use Psr\Log\LoggerInterface; + +/** + * MyService class + */ +final class MyService extends MyServiceBase +{ + /** + * @var LoggerInterface logger + */ + private LoggerInterface $logger; + + /** + * MyService constructor. + * @param LoggerInterface $logger + */ + public function __construct(LoggerInterface $logger) + { + $this->logger = $logger; + } + + /** + * @inheritDoc + */ + public function doit(): bool + { + return parent::doit(); + } +} +``` + +PHPDoc, if present, should describe the purpose of the element it's added +for. + +Skip default values in PHPDoc when PHP already shows them in a parameter +default, promoted property default, or property initializer. The declaration +is the source of truth, and repeating the value in text can become outdated +after code changes. + +Example of incorrect code: + +```php +/** + * @param bool $skipOnEmpty Whether to skip validation when the value is empty. Defaults to true. + */ +public function __construct( + private bool $skipOnEmpty = true, +) { +} +``` + +Example of a valid code: + +```php +/** + * @param bool $skipOnEmpty Whether to skip validation when the value is empty. + */ +public function __construct( + private bool $skipOnEmpty = true, +) { +} +``` + +The `@see` tags must explicitly refer to class methods, properties, and +constants. This is necessary for the correct display of links in IDEs, as +well as for the correct display of links in API documentation. + +Example of incorrect code: + +```php +/** + * @see SOME_CONST + * @see $prop + * @see doSomething() + */ +final class Example +{ + public const SOME_CONST = ''; + public int $prop; + public function doSomething(): void {} +} +``` + +Example of a valid code: + +```php +/** + * @see Example::SOME_CONST + * @see Example::$prop + * @see Example::doSomething() + */ +final class Example +{ + public const SOME_CONST = ''; + public int $prop; + public function doSomething(): void {} +} +``` + +## Readme checklist + +Each package readme should be placed into `README.md` and contain the +following: + +- [ ] Logo. +- [ ] Short description of the package. What does it do? +- [ ] Quality badges (build, code coverage). +- [ ] Screenshot (if applicable). +- [ ] Requirements. +- [ ] Installation. Usually `composer require`. +- [ ] Getting started. One or two common usage examples are demonstrated. +- [ ] Configuration. +- [ ] Contributing. It should contain a link to guidelines. +- [ ] Running tests. +- [ ] License. diff --git a/src/pt-BR/internals/015-phpstorm.md b/src/pt-BR/internals/015-phpstorm.md new file mode 100644 index 00000000..7995ffc6 --- /dev/null +++ b/src/pt-BR/internals/015-phpstorm.md @@ -0,0 +1,70 @@ +# 015 — PhpStorm metadata and attributes + +## PhpStorm metadata + +[PhpStorm +metadata](https://www.jetbrains.com/help/phpstorm/ide-advanced-metadata.html) +helps the IDE to understand code better in cases when regular types and +PHPDoc tags don't help. + +We use the following set of coding styles for metadata. + +### Metadata location + +- Metadata should be placed in `/.phpstorm.meta.php` directory. +- Configuration should be split into files. Each file should be named after + a class it configures. + +> [!NOTE] +> There is no support for subdirectories in PhpStorm yet. + +### Constants + +All constant dictionaries should be named as `{Class FQN}::{Group +name}`. Group name should be short and written in capital letters. Use +underscore as a word separator that's `\Yiisoft\Http\Status::STATUSES`. For +example: + +```php +expectedReturnValues( + \Psr\Http\Message\RequestInterface::getMethod(), + argumentsSet('\Yiisoft\Http\Method::METHODS'), +); + +registerArgumentsSet( + '\Yiisoft\Http\Method::METHODS', + \Yiisoft\Http\Method::GET, + \Yiisoft\Http\Method::POST, + \Yiisoft\Http\Method::PUT, + \Yiisoft\Http\Method::DELETE, + \Yiisoft\Http\Method::PATCH, + \Yiisoft\Http\Method::HEAD, + \Yiisoft\Http\Method::OPTIONS, +); +``` + +## PhpStorm attributes + +[PhpStorm attributes](https://github.com/JetBrains/phpstorm-attributes) CAN +be used in code, but package `jetbrains/phpstorm-attributes` MUST be added +as a dev dependency: + +```shell +composer require --dev jetbrains/phpstorm-attributes +``` + +### Using with ComposerRequireChecker + +When +[ComposerRequireChecker](https://github.com/maglnet/ComposerRequireChecker) +is also used within the same package, add involved attributes' class names +to whitelist in config. For example: + +```json +{ + "symbol-whitelist": [ + "JetBrains\\PhpStorm\\ExpectedValues", + "JetBrains\\PhpStorm\\Pure" + ] +} +``` diff --git a/src/pt-BR/internals/016-security-workflow.md b/src/pt-BR/internals/016-security-workflow.md new file mode 100644 index 00000000..2a09d5b7 --- /dev/null +++ b/src/pt-BR/internals/016-security-workflow.md @@ -0,0 +1,68 @@ +# 016 — Security workflow + +Security issues are typically sent via [a security +form](https://www.yiiframework.com/security). + +If an issue is reported directly to a public page such as a repository issue or a forum topic, get the message +and delete the issue. Say thanks to the reporter and point to the security form for next time. + +```mermaid +flowchart TD + form[Security form report] --> verify[Verify issue] + public[Public report] --> remove[Save details and delete public issue] + remove --> redirect[Point reporter to the security form] + redirect --> verify + verify -->|needs details| requestInfo[Request more information] + requestInfo --> verify + verify -->|valid| advisory[Create draft security advisory] + advisory --> severity[Set CVSS severity] + severity --> credit[Ask about reporter credit] + credit --> cve[Request CVE number] + cve --> patch[Prepare patch pull request] + patch --> wait[Wait for CVE allocation] + wait --> release[Release] + release --> publish[Publish advisory and submit FriendsOfPHP entry] +``` + +## Verify + +Verify that the issue is valid. Request more information if needed. + +## Add security advisory + +Create a draft GitHub security advisory. + +### Find out severity + +1. Get CVSS score using [NVD + calculator](https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator). +2. Choose severity based on the [rating + scale](https://www.first.org/cvss/specification-document#Qualitative-Severity-Rating-Scale). + +### Give credit to the reporter + +Ask the reporter if he wants a credit for finding the issue. If so, point to +his GitHub account. + +## Request a CVE number + +When you're ready, request a CVE. + +## Prepare a patch + +Prepare a pull request fixing the issue. GitHub allows doing it in a private +fork. + +## Wait till the CVE number is allocated + +It usually takes several days. + +## Release + +- Merge the patch pull request right before tagging the next package + release. +- Publish security advisory. +- Add CVE to + [FriendsOfPHP/security-advisories](https://github.com/FriendsOfPHP/security-advisories). + See [#488](https://github.com/FriendsOfPHP/security-advisories/pull/488) + as an example. diff --git a/src/pt-BR/internals/017-tags.md b/src/pt-BR/internals/017-tags.md new file mode 100644 index 00000000..637e1805 --- /dev/null +++ b/src/pt-BR/internals/017-tags.md @@ -0,0 +1,43 @@ +# 017 - Tags + +Unlike regular classes, tags are used in view templates, so syntax is +important. It should be both easy to write, easy to read and not too +verbose because similar constructs are meant to be used over and over again. + +## Class names + +- Tags aren't postfixed or prefixed unless it's an abstract base class. +- If the tag represents a specification, use a name used in the + specification. + +## Inheritance + +Inheritance is allowed with some restrictions: + +- If a class isn't abstract, it should be final. +- Hierarchy should be kept as linear as possible. + +## Immutability + +Tags should: + +- Have no state. +- Be immutable. Every method that modifies a setting returns a clone with + the setting changed. +- Be free of side effects. Many calls of the same method with the same + argument should give the same result. + +## Methods + +### Names + +- Unlike other classes, methods that return a clone of the object with some + properties modified aren't prefixed. +- Keep method names as short as possible but don't hurt readability. +- If the tag represents a specification, use a name used in the + specification. + +### Boolean flags + +The method that corresponds to the boolean attribute should be named after +the attribute and accept a boolean flag argument. diff --git a/src/pt-BR/internals/018-widgets.md b/src/pt-BR/internals/018-widgets.md new file mode 100644 index 00000000..4fb6bec2 --- /dev/null +++ b/src/pt-BR/internals/018-widgets.md @@ -0,0 +1,36 @@ +# 018 - Widgets + +Unlike regular classes, widgets are used in view templates, so syntax is +important. It should be both easy to write, easy to read and not too +verbose because similar constructs are meant to be used over and over again. + +## Class names + +Widgets aren't postfixed or prefixed. + +## Inheritance + +Inheritance is allowed with some restrictions: + +- If a class isn't abstract, it should be final. +- Hierarchy should be kept as linear as possible. + +## Immutability + +Widgets should: + +- Have no state. +- Be immutable. + +## Methods + +### Names + +- Unlike other classes, methods that return a clone of the object with some + properties modified aren't prefixed. +- Keep method names as short as possible but don't hurt readability. + +### Boolean flags + +The method that corresponds to the boolean attribute should be named after +the attribute and accept a boolean flag argument. diff --git a/src/pt-BR/internals/019-view-code-style.md b/src/pt-BR/internals/019-view-code-style.md new file mode 100644 index 00000000..c5a19173 --- /dev/null +++ b/src/pt-BR/internals/019-view-code-style.md @@ -0,0 +1,46 @@ +# 019 — View code style + +The PHP code in the view files shouldn't be complicated. The code must +contain the logic responsible for formatting the data, but not the logic for +requesting this data. + +## Heading + +View file heading is used to place phpdoc describing variables available and +to import classes: + +```php + +

getTitle()) ?>

+

getDescription()) ?>

+ +``` + +## Short echo + +Short echo is preferred: + +```php + +``` + +## Class methods + +All class methods used in view files must be public regardless if the view +is rendered by the class itself. diff --git a/src/pt-BR/internals/020-package-release.md b/src/pt-BR/internals/020-package-release.md new file mode 100644 index 00000000..9e98546d --- /dev/null +++ b/src/pt-BR/internals/020-package-release.md @@ -0,0 +1,56 @@ +# 020 — Package release + +## Criteria + +- No critical issues. +- Public API changes aren't likely. Some time passed w/o issues reported + that may require API changes. +- All dependencies are stable. +- Close to 100% test coverage with, ideally, a 100% MSI score. +- README is alright. +- Everything is type-hinted unless special cases. +- Psalm analysis passes on at least level 2. +- phpdoc is alright. +- Public API is alright. + +## Release branch policy + +Use `master` for all regular releases. + +Create a separate branch only when releasing a new version for a previous +major version. In this case, create the branch from the latest tag in that +previous major version line and apply only the changes needed for the +release. + +## Release instruction + +Release a package via [Yii Development Tool](005-development-tool.md). + +1. Check that you can sign commits locally (see +[Signing commits](https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits)). + +2. For regular releases, pull last changes from the `master` branch: + +```shell +./yii-dev git/checkout master package-name +./yii-dev git/pull package-name +``` + +For previous major version releases, use the branch created according to the +release branch policy instead of `master`. + +3. Check the package for compliance with the criteria above. + +4. Run `release/make` command: + +```shell +./yii-dev release/make package-name +``` + +5. Select the version type (major, minor or patch). + +6. On the question "Push commits and tags, and release on GitHub?" check a + diff. If the diff is alright, answer "yes." + +7. For major and minor releases, add a record with release notes on [Yii + Framework News](https://www.yiiframework.com/news). diff --git a/src/pt-BR/internals/021-changelog-upgrade.md b/src/pt-BR/internals/021-changelog-upgrade.md new file mode 100644 index 00000000..ee291e73 --- /dev/null +++ b/src/pt-BR/internals/021-changelog-upgrade.md @@ -0,0 +1,67 @@ +# 021 — Changelog and upgrade + +For all released packages, we've a detailed changelog and upgrade guide. + +## Changelog + +Changelog is written for each version released. The file name is +`CHANGELOG.md`. The format is the following: + +```markdown +# My package Change Log + +## 1.0.2 under development + +- no changes in this release. + +## 1.0.1 March 23, 2021 + +- Bug #42: Short description of the change (@author1, @author2) + +## 1.0.0 February 02, 2021 + +- Initial release. +``` + +There "My package" is the name of the package, `1.0.1` is the version +released followed by release date. For each version, there are a number of +lines listing the changes. "Bug" refers to a change type. The following +types are used: + +- New — New features. +- Chg — General changes. +- Enh — Existing feature enhancements. +- Bug — Bug fixes. + +In the changelog file lines should be ordered as New, Chg, Enh, Bug. + +"#42" above is the number of issue or pull requests corresponding to the +change. "author1" is the GitHub nickname of the code author. "author2" is an +additional author. An author's nickname MUST be prefixed with `@`. + +## Upgrade + +Upgrade guide is created when there is a new major version that isn't +compatible with the previous one. It describes steps necessary to upgrade +application code. + +The file name is `UPGRADE.md`. The format is the following: + +```markdown +# Upgrading Instructions for my package + +This file contains the upgrade notes. These notes highlight changes that could break your +application when you upgrade the package from one version to another. + +> **Important!** The following upgrading instructions are cumulative. That is, if you want +> to upgrade from version A to version C and there is version B between A and C, you need +> to follow the instructions for both A and B. + +## Upgrade from 2.x + +- Public method `test()` was removed. Use `perform()` instead. + +## Upgrade from 1.x + +- Clean up the cache after upgrading. Old cache is not compatible with new code. +``` diff --git a/src/pt-BR/internals/022-config-groups.md b/src/pt-BR/internals/022-config-groups.md new file mode 100644 index 00000000..8193bf82 --- /dev/null +++ b/src/pt-BR/internals/022-config-groups.md @@ -0,0 +1,73 @@ +# 022 — Config groups + +This document defines naming convention for the framework groups used with +[yiisoft/config](https://github.com/yiisoft/config). Note that this isn't a +naming convention for config files. These could be anything and are mapped +to group names via `composer.json`. + +## Config group name postfixes + +- "web" postfix applies to web only that's classic server HTML generation, + REST, RPC, etc. +- "console" postfix applies to console +- If there's no postfix, it's "common" and applies to both web and console +- "web" and "console" may override what's defined in "common" + +## Parameters + +Application config parameters that are used in all configs. + +- `params` — common parameters +- `params-web` — web application parameters +- `params-console` — console application parameters + +## Container + +Configuration for [yiisoft/di](https://github.com/yiisoft/di). + +### Definitions + +- `di` — common container definitions +- `di-web` — web container definitions +- `di-console` — console container definitions + +### Providers + +- `di-providers` — common container providers +- `di-providers-web` — web container providers +- `di-providers-console` — console container providers + +### Delegates + +- `di-delegates` — common container delegates +- `di-delegates-web` — web container delegates +- `di-delegates-console` — console container delegates + +### Tags + +- `di-tags` — common container tags +- `di-tags-web` — web container tags +- `di-tags-console` — console container tags + +## Events + +Configuration for [yiisoft/yii-event](https://github.com/yiisoft/yii-event). + +- `events` — common events +- `events-web` — web events +- `events-console` — console events + +## Bootstrap + +Application bootstrapping for +[yiisoft/yii-runner](https://github.com/yiisoft/yii-runner). + +- `bootstrap` — common bootstrap +- `bootstrap-web` — web bootstrap +- `bootstrap-console` — console bootstrap + +## Others + +- `routes` — [yiisoft/router](https://github.com/yiisoft/router) routes +- `widgets` — [yiisoft/widget](https://github.com/yiisoft/widget) default + widgets configuration diff --git a/src/pt-BR/internals/023-github-actions.md b/src/pt-BR/internals/023-github-actions.md new file mode 100644 index 00000000..2376c288 --- /dev/null +++ b/src/pt-BR/internals/023-github-actions.md @@ -0,0 +1,34 @@ +# 023 — GitHub Actions + +This document defines naming convention for the GitHub actions configuration +files. + +## Inputs and Outputs + +Input names and output names must use kebab-case format. + +For example: + +```yaml +inputs: + my-input: + description: 'My input' +``` + +## Secrets and Environment Variables + +Secret names and environment variable names must use SCREAMING_SNAKE_CASE +format. + +For example: + +```yaml +secrets: + MY_SECRET: + description: 'My secret' +``` + +```yaml +env: + MY_ENV_VAR: 1 +``` diff --git a/src/pt-BR/internals/index.md b/src/pt-BR/internals/index.md new file mode 100644 index 00000000..1c754e2e --- /dev/null +++ b/src/pt-BR/internals/index.md @@ -0,0 +1,48 @@ +# Detalhes internos do Yii Framework + +Esta seção contém documentação para quem contribui com o próprio framework +Yii. Ela cobre diretrizes, fluxos de trabalho e boas práticas para manter e +desenvolver os pacotes do Yii. + +## Sumário + +- [000 — Pacotes](000-packages.md) - Estrutura e convenções de nomes dos + pacotes +- [001 — Objetivo e valores do Yii](001-yii-values.md) - Objetivos e valores + centrais do projeto +- [002 — Fluxo de issues](002-issue-workflow.md) - Como lidar com issues +- [003 — Roadmap](003-roadmap.md) - Roadmap de desenvolvimento e planos + futuros +- [004 — Namespaces](004-namespaces.md) - Convenções de namespaces +- [005 — Ferramenta de desenvolvimento do Yii](005-development-tool.md) - + Ferramentas de desenvolvimento para pacotes do Yii +- [006 — Mensagens de commit no Git](006-git-commit-messages.md) - Formato + das mensagens de commit +- [007 — Exceções](007-exceptions.md) - Diretrizes para exceções +- [008 — Interfaces](008-interfaces.md) - Princípios de design de interfaces +- [009 — Decisões de design](009-design-decisions.md) - Decisões de + arquitetura e design +- [010 — Estilo de código](010-code-style.md) - Diretrizes de estilo de + código PHP +- [011 — Correção de erros](011-error-correction.md) - Tratamento e correção + de erros +- [012 — Testes](012-tests.md) - Diretrizes e práticas de testes +- [013 — Code review](013-code-review.md) - Processo e diretrizes de code + review +- [014 — Documentação](014-docs.md) - Diretrizes para escrever documentação +- [015 — Metadados e atributos do PhpStorm](015-phpstorm.md) - Integração + com o PhpStorm +- [016 — Fluxo de segurança](016-security-workflow.md) - Tratamento de + problemas de segurança +- [017 — Tags](017-tags.md) - Convenções de tags no Git +- [018 — Widgets](018-widgets.md) - Diretrizes para desenvolver widgets +- [019 — Estilo de código de views](019-view-code-style.md) - Estilo de + código para templates de view +- [020 — Release de pacotes](020-package-release.md) - Processo de release + de pacotes +- [021 — Changelog e upgrade](021-changelog-upgrade.md) - Mantendo + changelogs e notas de upgrade +- [022 — Grupos de configuração](022-config-groups.md) - Organização dos + grupos de configuração +- [023 - GitHub Actions](023-github-actions.md) - Configuração do GitHub + Actions From 23ed35263f7f49e557434e4194e934c83ce2a007 Mon Sep 17 00:00:00 2001 From: Yuri Neves Date: Fri, 23 Oct 2026 14:03:33 -0300 Subject: [PATCH 02/11] Translate "Handling requests" section to Brazilian Portuguese --- .../po/pt-BR/guide_runtime_cookies.md.po | 162 +++++-- .../pt-BR/guide_runtime_handling-errors.md.po | 262 ++++++++-- .../po/pt-BR/guide_runtime_logging.md.po | 327 +++++++++---- .../po/pt-BR/guide_runtime_request.md.po | 292 +++++++++--- .../po/pt-BR/guide_runtime_response.md.po | 108 ++++- .../po/pt-BR/guide_runtime_routing.md.po | 450 ++++++++++++++---- .../po/pt-BR/guide_runtime_sessions.md.po | 132 ++++- .../po/pt-BR/guide_start_databases.md.po | 2 +- ...guide_tutorial_using-yii-with-swoole.md.po | 2 +- .../internals_006-git-commit-messages.md.po | 2 +- src/pt-BR/guide/runtime/cookies.md | 142 +++--- src/pt-BR/guide/runtime/handling-errors.md | 194 ++++---- src/pt-BR/guide/runtime/logging.md | 441 ++++++++--------- src/pt-BR/guide/runtime/request.md | 162 ++++--- src/pt-BR/guide/runtime/response.md | 69 +-- src/pt-BR/guide/runtime/routing.md | 289 +++++------ src/pt-BR/guide/runtime/sessions.md | 67 +-- src/pt-BR/guide/start/databases.md | 2 +- .../guide/tutorial/using-yii-with-swoole.md | 2 +- .../internals/006-git-commit-messages.md | 2 +- 20 files changed, 2078 insertions(+), 1031 deletions(-) diff --git a/_translations/po/pt-BR/guide_runtime_cookies.md.po b/_translations/po/pt-BR/guide_runtime_cookies.md.po index e72bb7a3..04a0f3a6 100644 --- a/_translations/po/pt-BR/guide_runtime_cookies.md.po +++ b/_translations/po/pt-BR/guide_runtime_cookies.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2025-09-04 11:19+0500\n" "PO-Revision-Date: 2025-09-04 11:19+0500\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,23 +19,23 @@ msgstr "" #: en/runtime/cookies.md #, no-wrap msgid "Cookies" -msgstr "" +msgstr "Cookies" #. type: Plain text #: en/runtime/cookies.md msgid "Cookies are for persisting data between requests by sending it to the client browser using HTTP headers. The client sends data back to the server in request headers. Thus, cookies are handy to store small amounts of data, such as tokens or flags." -msgstr "" +msgstr "Os cookies servem para manter dados entre requisições, enviando-os ao navegador do cliente por headers HTTP. O cliente devolve os dados ao servidor nos headers da requisição. Por isso, os cookies são práticos para guardar pequenas quantidades de dados, como tokens ou flags." #. type: Title ## #: en/runtime/cookies.md #, no-wrap msgid "Reading cookies" -msgstr "" +msgstr "Lendo cookies" #. type: Plain text #: en/runtime/cookies.md msgid "You could obtain Cookie values from server request that's available as route handler (such as controller action) argument:" -msgstr "" +msgstr "Você pode obter os valores dos cookies a partir da requisição do servidor, que está disponível como argumento do handler da rota (por exemplo, uma action de controller):" #. type: Fenced code block (php) #: en/runtime/cookies.md @@ -48,16 +48,22 @@ msgid "" " // ...\n" "}\n" msgstr "" +"private function actionProfile(\\Psr\\Http\\Message\\ServerRequestInterface $request)\n" +"{\n" +" $cookieValues = $request->getCookieParams();\n" +" $cookieValue = $cookieValues['cookieName'] ?? null;\n" +" // ...\n" +"}\n" #. type: Plain text #: en/runtime/cookies.md msgid "In addition to getting cookie values directly from the server request, you can also use the [yiisoft/request-provider](https://github.com/yiisoft/request-provider) package, which provides a more structured way to handle cookies through the `\\Yiisoft\\RequestProvider\\RequestCookieProvider`. This approach can simplify your code and improve readability." -msgstr "" +msgstr "Além de obter os valores dos cookies direto da requisição do servidor, você também pode usar o pacote [yiisoft/request-provider](https://github.com/yiisoft/request-provider), que oferece uma forma mais estruturada de lidar com cookies por meio do `\\Yiisoft\\RequestProvider\\RequestCookieProvider`. Essa abordagem pode simplificar o código e melhorar a legibilidade." #. type: Plain text #: en/runtime/cookies.md msgid "Here’s an example of how to work with cookies using the `\\Yiisoft\\RequestProvider\\RequestCookieProvider`:" -msgstr "" +msgstr "Veja um exemplo de como trabalhar com cookies usando o `\\Yiisoft\\RequestProvider\\RequestCookieProvider`:" #. type: Fenced code block (php) #: en/runtime/cookies.md @@ -100,32 +106,68 @@ msgid "" "\n" "return $cookie->addToResponse($response);\n" msgstr "" +"final readonly class MyService\n" +"{\n" +" public function __construct(\n" +" private \\Yiisoft\\RequestProvider\\RequestCookieProvider $cookies\n" +" ) {}\n" +"\n" +" public function go(): void\n" +" {\n" +" // Check if a specific cookie exists\n" +" if ($this->cookies->has('foo')) {\n" +" // Retrieve the value of the cookie\n" +" $fooValue = $this->cookies->get('foo');\n" +" // Do something with the cookie value\n" +" }\n" +"\n" +" // Retrieve another cookie value\n" +" $barValue = $this->cookies->get('bar');\n" +" // Do something with the bar cookie value\n" +" }\n" +"}\n" +"\n" +"## Sending cookies\n" +"\n" +"Since sending cookies is, in fact, sending a header but since forming the header isn't trivial, there is\n" +"`\\Yiisoft\\Cookies\\Cookie` class to help with it:\n" +"\n" +"```php\n" +"$cookie = (new \\Yiisoft\\Cookies\\Cookie('cookieName', 'value'))\n" +" ->withPath('/')\n" +" ->withDomain('yiiframework.com')\n" +" ->withHttpOnly(true)\n" +" ->withSecure(true)\n" +" ->withSameSite(\\Yiisoft\\Cookies\\Cookie::SAME_SITE_STRICT)\n" +" ->withMaxAge(new \\DateInterval('P7D'));\n" +"\n" +"return $cookie->addToResponse($response);\n" #. type: Plain text #: en/runtime/cookies.md msgid "After forming a cookie call `addToResponse()` passing an instance of `\\Psr\\Http\\Message\\ResponseInterface` to add corresponding HTTP headers to it." -msgstr "" +msgstr "Depois de montar o cookie, chame `addToResponse()` passando uma instância de `\\Psr\\Http\\Message\\ResponseInterface` para adicionar os headers HTTP correspondentes a ela." #. type: Title ## #: en/runtime/cookies.md #, no-wrap msgid "Signing and encrypting cookies" -msgstr "" +msgstr "Assinando e criptografando cookies" #. type: Plain text #: en/runtime/cookies.md msgid "To prevent the substitution of the cookie value, the package provides two implementations:" -msgstr "" +msgstr "Para evitar que o valor do cookie seja substituído, o pacote oferece duas implementações:" #. type: Plain text #: en/runtime/cookies.md msgid "`Yiisoft\\Cookies\\CookieSigner` - signs each cookie with a unique prefix hash based on the value of the cookie and a secret key. `Yiisoft\\Cookies\\CookieEncryptor` - encrypts each cookie with a secret key." -msgstr "" +msgstr "`Yiisoft\\Cookies\\CookieSigner` - assina cada cookie com um prefixo de hash único baseado no valor do cookie e em uma chave secreta. `Yiisoft\\Cookies\\CookieEncryptor` - criptografa cada cookie com uma chave secreta." #. type: Plain text #: en/runtime/cookies.md msgid "Encryption is more secure than signing but has lower performance." -msgstr "" +msgstr "A criptografia é mais segura que a assinatura, mas tem desempenho menor." #. type: Fenced code block (php) #: en/runtime/cookies.md @@ -142,11 +184,21 @@ msgid "" "$signedCookie = $signer->sign($cookie);\n" "$encryptedCookie = $encryptor->encrypt($cookie);\n" msgstr "" +"$cookie = new \\Yiisoft\\Cookies\\Cookie('identity', 'identityValue');\n" +"\n" +"// The secret key used to sign and validate cookies.\n" +"$key = '0my1xVkjCJnD_q1yr6lUxcAdpDlTMwiU';\n" +"\n" +"$signer = new \\Yiisoft\\Cookies\\CookieSigner($key);\n" +"$encryptor = new \\Yiisoft\\Cookies\\CookieEncryptor($key);\n" +"\n" +"$signedCookie = $signer->sign($cookie);\n" +"$encryptedCookie = $encryptor->encrypt($cookie);\n" #. type: Plain text #: en/runtime/cookies.md msgid "To validate and get back the pure value, use the `validate()` and `decrypt()` method." -msgstr "" +msgstr "Para validar e obter de volta o valor puro, use os métodos `validate()` e `decrypt()`." #. type: Fenced code block (php) #: en/runtime/cookies.md @@ -155,11 +207,13 @@ msgid "" "$cookie = $signer->validate($signedCookie);\n" "$cookie = $encryptor->decrypt($encryptedCookie);\n" msgstr "" +"$cookie = $signer->validate($signedCookie);\n" +"$cookie = $encryptor->decrypt($encryptedCookie);\n" #. type: Plain text #: en/runtime/cookies.md msgid "If the cookie value is tampered with or hasn't been signed/encrypted before, a `\\RuntimeException` will be thrown. Therefore, if you aren't sure that the cookie value was signed/encrypted earlier, first use the `isSigned()` and `isEncrypted()` methods, respectively." -msgstr "" +msgstr "Se o valor do cookie tiver sido adulterado ou não tiver sido assinado/criptografado antes, uma `\\RuntimeException` será lançada. Por isso, se você não tem certeza de que o valor do cookie foi assinado/criptografado antes, use primeiro os métodos `isSigned()` e `isEncrypted()`, respectivamente." #. type: Fenced code block (php) #: en/runtime/cookies.md @@ -173,47 +227,54 @@ msgid "" " $cookie = $encryptor->decrypt($cookie);\n" "}\n" msgstr "" +"if ($signer->isSigned($cookie)) {\n" +" $cookie = $signer->validate($cookie);\n" +"}\n" +"\n" +"if ($encryptor->isEncrypted($cookie)) {\n" +" $cookie = $encryptor->decrypt($cookie);\n" +"}\n" #. type: Plain text #: en/runtime/cookies.md msgid "It makes sense to sign or encrypt the value of a cookie if you store important data that a user shouldn't change." -msgstr "" +msgstr "Faz sentido assinar ou criptografar o valor de um cookie quando você guarda dados importantes que o usuário não deve alterar." #. type: Title ### #: en/runtime/cookies.md #, no-wrap msgid "Automating encryption and signing" -msgstr "" +msgstr "Automatizando a criptografia e a assinatura" #. type: Plain text #: en/runtime/cookies.md msgid "To automate the encryption/signing and decryption/validation of cookie values, use an instance of `Yiisoft\\Cookies\\CookieMiddleware`, which is [PSR-15](https://www.php-fig.org/psr/psr-15/) middleware." -msgstr "" +msgstr "Para automatizar a criptografia/assinatura e a descriptografia/validação dos valores dos cookies, use uma instância de `Yiisoft\\Cookies\\CookieMiddleware`, que é um middleware [PSR-15](https://www.php-fig.org/psr/psr-15/)." #. type: Plain text #: en/runtime/cookies.md msgid "This middleware provides the following features:" -msgstr "" +msgstr "Esse middleware oferece os seguintes recursos:" #. type: Bullet: '- ' #: en/runtime/cookies.md msgid "Validates and decrypts the cookie parameter values from the request." -msgstr "" +msgstr "Valida e descriptografa os valores dos cookies vindos da requisição." #. type: Bullet: '- ' #: en/runtime/cookies.md msgid "Excludes the cookie parameter from the request if it was tampered with and logs information about it." -msgstr "" +msgstr "Remove o cookie da requisição se ele tiver sido adulterado e registra essa informação no log." #. type: Bullet: '- ' #: en/runtime/cookies.md msgid "Encrypts/signs cookie values and replaces their clean values in the `Set-Cookie` headers in the response." -msgstr "" +msgstr "Criptografa/assina os valores dos cookies e substitui os valores puros nos headers `Set-Cookie` da resposta." #. type: Plain text #: en/runtime/cookies.md msgid "In order for the middleware to know which values of which cookies need to be encrypted/signed, an array of settings must be passed to its constructor. The array keys are cookie name patterns and values are constant values of `CookieMiddleware::ENCRYPT` or `CookieMiddleware::SIGN`." -msgstr "" +msgstr "Para o middleware saber quais valores de quais cookies precisam ser criptografados/assinados, é preciso passar um array de configurações para o construtor dele. As chaves do array são padrões de nomes de cookies e os valores são as constantes `CookieMiddleware::ENCRYPT` ou `CookieMiddleware::SIGN`." #. type: Fenced code block (php) #: en/runtime/cookies.md @@ -231,16 +292,27 @@ msgid "" " 'prefix*' => CookieMiddleware::SIGN,\n" "];\n" msgstr "" +"use Yiisoft\\Cookies\\CookieMiddleware;\n" +"\n" +"$cookiesSettings = [\n" +" // Exact match with the name `identity`.\n" +" 'identity' => CookieMiddleware::ENCRYPT,\n" +" // Matches any number from 1 to 9 after the underscore.\n" +" 'name_[1-9]' => CookieMiddleware::SIGN,\n" +" // Matches any string after the prefix, including an\n" +" // empty string, except for the delimiters \"/\" and \"\\\".\n" +" 'prefix*' => CookieMiddleware::SIGN,\n" +"];\n" #. type: Plain text #: en/runtime/cookies.md msgid "For more information on using the wildcard pattern, see the [yiisoft/strings](https://github.com/yiisoft/strings#wildcardpattern-usage) package." -msgstr "" +msgstr "Para mais informações sobre o uso de padrões com curinga, veja o pacote [yiisoft/strings](https://github.com/yiisoft/strings#wildcardpattern-usage)." #. type: Plain text #: en/runtime/cookies.md msgid "Creating and using middleware:" -msgstr "" +msgstr "Criando e usando o middleware:" #. type: Fenced code block (php) #: en/runtime/cookies.md @@ -273,39 +345,65 @@ msgid "" "// The cookie values are encrypted/signed and appended to the response.\n" "$response = $middleware->process($request, $handler);\n" msgstr "" +"/**\n" +" * @var \\Psr\\Http\\Message\\ServerRequestInterface $request\n" +" * @var \\Psr\\Http\\Server\\RequestHandlerInterface $handler\n" +" * @var \\Psr\\Log\\LoggerInterface $logger\n" +" */\n" +"\n" +"// The secret key used to sign and validate cookies.\n" +"$key = '0my1xVkjCJnD_q1yr6lUxcAdpDlTMwiU';\n" +"$signer = new \\Yiisoft\\Cookies\\CookieSigner($key);\n" +"$encryptor = new \\Yiisoft\\Cookies\\CookieEncryptor($key);\n" +"\n" +"$cookiesSettings = [\n" +" 'identity' => \\Yiisoft\\Cookies\\CookieMiddleware::ENCRYPT,\n" +" 'session' => \\Yiisoft\\Cookies\\CookieMiddleware::SIGN,\n" +"];\n" +"\n" +"$middleware = new \\Yiisoft\\Cookies\\CookieMiddleware(\n" +" $logger\n" +" $encryptor,\n" +" $signer,\n" +" $cookiesSettings,\n" +");\n" +"\n" +"// The cookie parameter values from the request are decrypted/validated.\n" +"// The cookie values are encrypted/signed and appended to the response.\n" +"$response = $middleware->process($request, $handler);\n" #. type: Plain text #: en/runtime/cookies.md msgid "If the `$cookiesSettings` array is empty, no cookies will be encrypted and signed." -msgstr "" +msgstr "Se o array `$cookiesSettings` estiver vazio, nenhum cookie será criptografado ou assinado." #. type: Title ## #: en/runtime/cookies.md #, no-wrap msgid "Cookies security" -msgstr "" +msgstr "Segurança dos cookies" #. type: Plain text #: en/runtime/cookies.md msgid "You should configure each cookie to be secure. Important security settings are:" -msgstr "" +msgstr "Você deve configurar cada cookie para ser seguro. As configurações de segurança importantes são:" #. type: Bullet: '- ' #: en/runtime/cookies.md msgid "`httpOnly`. Setting it to `true` would prevent JavaScript to access cookie value." -msgstr "" +msgstr "`httpOnly`. Definir como `true` impede que o JavaScript acesse o valor do cookie." #. type: Bullet: '- ' #: en/runtime/cookies.md msgid "`secure`. Setting it to `true` would prevent sending cookie via `HTTP`. It will be sent via `HTTPS` only." -msgstr "" +msgstr "`secure`. Definir como `true` impede o envio do cookie via `HTTP`. Ele só será enviado via `HTTPS`." #. type: Bullet: '- ' #: en/runtime/cookies.md msgid "`sameSite`, if set to either `SAME_SITE_LAX` or `SAME_SITE_STRICT` would prevent sending a cookie in cross-site browsing context. `SAME_SITE_LAX` would prevent cookie sending during CSRF-prone request methods (e.g., POST, PUT, PATCH, etc.). `SAME_SITE_STRICT` would prevent cookies sending for all methods." -msgstr "" +msgstr "`sameSite`, se definido como `SAME_SITE_LAX` ou `SAME_SITE_STRICT`, impede o envio do cookie em contexto de navegação entre sites. `SAME_SITE_LAX` impede o envio do cookie em métodos de requisição sujeitos a CSRF (por exemplo, POST, PUT, PATCH etc.). `SAME_SITE_STRICT` impede o envio dos cookies em todos os métodos." #. type: Bullet: '- ' #: en/runtime/cookies.md msgid "Sign or encrypt the value of the cookie to prevent spoofing of values if the data in the value shouldn't be tampered with." -msgstr "" +msgstr "Assine ou criptografe o valor do cookie para evitar falsificação quando os dados não puderem ser adulterados." diff --git a/_translations/po/pt-BR/guide_runtime_handling-errors.md.po b/_translations/po/pt-BR/guide_runtime_handling-errors.md.po index 565f9fdd..9612056b 100644 --- a/_translations/po/pt-BR/guide_runtime_handling-errors.md.po +++ b/_translations/po/pt-BR/guide_runtime_handling-errors.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-05-05 22:01+0000\n" "PO-Revision-Date: 2026-05-05 22:01+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,83 +19,83 @@ msgstr "" #: ../src/guide/runtime/handling-errors.md #, no-wrap msgid "Handling errors" -msgstr "" +msgstr "Tratamento de erros" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "Yii has a [yiisoft/error-handler](https://github.com/yiisoft/error-handler) package that makes error handling a much more pleasant experience than before. In particular, the Yii error handler provides the following:" -msgstr "" +msgstr "O Yii tem o pacote [yiisoft/error-handler](https://github.com/yiisoft/error-handler), que torna o tratamento de erros muito mais agradável do que antes. Em particular, o error handler do Yii oferece:" #. type: Bullet: '- ' #: ../src/guide/runtime/handling-errors.md msgid "[PSR-15](https://www.php-fig.org/psr/psr-15/) middleware for catching unhandled errors." -msgstr "" +msgstr "Middleware [PSR-15](https://www.php-fig.org/psr/psr-15/) para capturar erros não tratados." #. type: Bullet: '- ' #: ../src/guide/runtime/handling-errors.md msgid "PSR-15 middleware for mapping certain exceptions to custom responses." -msgstr "" +msgstr "Middleware PSR-15 para mapear certas exceções para respostas personalizadas." #. type: Bullet: '- ' #: ../src/guide/runtime/handling-errors.md msgid "Production and debug modes." -msgstr "" +msgstr "Modos de produção e de debug." #. type: Bullet: '- ' #: ../src/guide/runtime/handling-errors.md msgid "Debug mode displays details, stacktrace, has dark and light themes and handy buttons to search for error without typing." -msgstr "" +msgstr "O modo debug mostra detalhes e o stacktrace, tem temas claro e escuro e botões práticos para pesquisar o erro sem digitar." #. type: Bullet: '- ' #: ../src/guide/runtime/handling-errors.md msgid "Takes PHP settings into account." -msgstr "" +msgstr "Leva em conta as configurações do PHP." #. type: Bullet: '- ' #: ../src/guide/runtime/handling-errors.md msgid "Handles out of memory errors, fatal errors, warnings, notices, and exceptions." -msgstr "" +msgstr "Trata erros de falta de memória, erros fatais, warnings, notices e exceções." #. type: Bullet: '- ' #: ../src/guide/runtime/handling-errors.md msgid "Can use any [PSR-3](https://www.php-fig.org/psr/psr-3/) compatible logger for error logging." -msgstr "" +msgstr "Pode usar qualquer logger compatível com a [PSR-3](https://www.php-fig.org/psr/psr-3/) para registrar os erros." #. type: Bullet: '- ' #: ../src/guide/runtime/handling-errors.md msgid "Detects a response format based on a mime type of the request." -msgstr "" +msgstr "Detecta o formato da resposta com base no mime type da requisição." #. type: Bullet: '- ' #: ../src/guide/runtime/handling-errors.md msgid "Supports responding with HTML, plain text, JSON, XML, and headers out of the box." -msgstr "" +msgstr "Suporta respostas em HTML, texto puro, JSON, XML e headers sem configuração extra." #. type: Bullet: '- ' #: ../src/guide/runtime/handling-errors.md msgid "You can implement your own error rendering for extra types." -msgstr "" +msgstr "Você pode implementar a sua própria renderização de erros para outros tipos." #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "This guide describes how to use the error handler in the [Yii framework](https://www.yiiframework.com/), for information about using it separate from Yii, see the [package description](https://github.com/yiisoft/error-handler)." -msgstr "" +msgstr "Este guia descreve como usar o error handler no [framework Yii](https://www.yiiframework.com/). Para usá-lo separado do Yii, veja a [descrição do pacote](https://github.com/yiisoft/error-handler)." #. type: Title ## #: ../src/guide/runtime/handling-errors.md #, no-wrap msgid "Using error handler" -msgstr "" +msgstr "Usando o error handler" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "The error handler consists of two parts. One part is `Yiisoft\\ErrorHandler\\Middleware\\ErrorCatcher` middleware that, when registered, catches exceptions that may appear during middleware stack execution and passes them to the handler. Another part is the error handler itself, `Yiisoft\\ErrorHandler\\ErrorHandler`, that's catching exceptions occurring outside the middleware stack and fatal errors. The handler also converts warnings and notices to exceptions and does more handy things." -msgstr "" +msgstr "O error handler tem duas partes. Uma é o middleware `Yiisoft\\ErrorHandler\\Middleware\\ErrorCatcher`, que, quando registrado, captura as exceções que podem surgir durante a execução da pilha de middlewares e as passa para o handler. A outra é o próprio error handler, `Yiisoft\\ErrorHandler\\ErrorHandler`, que captura as exceções que ocorrem fora da pilha de middlewares e os erros fatais. O handler também converte warnings e notices em exceções e faz outras coisas úteis." #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "Error handler is registered in the application itself. Usually it happens in `ApplicationRunner`. By default, the handler configuration comes from the container. You may configure it in the application configuration, `config/web.php` like the following:" -msgstr "" +msgstr "O error handler é registrado na própria aplicação. Normalmente isso acontece no `ApplicationRunner`. Por padrão, a configuração do handler vem do container. Você pode configurá-lo na configuração da aplicação, `config/web.php`, assim:" #. type: Fenced code block (php) #: ../src/guide/runtime/handling-errors.md @@ -130,11 +130,39 @@ msgid "" " // ...\n" "];\n" msgstr "" +"use Psr\\Log\\LoggerInterface;\n" +"use Yiisoft\\ErrorHandler\\ErrorHandler;\n" +"use Yiisoft\\ErrorHandler\\Renderer\\HtmlRenderer;\n" +"use Yiisoft\\ErrorHandler\\ThrowableRendererInterface;\n" +"\n" +"return [\n" +" // ...\n" +" ErrorHandler::class => static function (LoggerInterface $logger, ThrowableRendererInterface $renderer) {\n" +" $errorHandler = new ErrorHandler($logger, $renderer);\n" +" // Set the size of the reserved memory to 512 KB. Defaults to 256KB.\n" +" $errorHandler->memoryReserveSize(524_288);\n" +" return $errorHandler;\n" +" },\n" +" \n" +" ThrowableRendererInterface::class => static fn () => new HtmlRenderer([\n" +" // Defaults to the package file \"templates/production.php\".\n" +" 'template' => '/full/path/to/production/template/file',\n" +" // Defaults to package file \"templates/development.php\".\n" +" 'verboseTemplate' => '/full/path/to/development/template/file',\n" +" // Maximum number of source code lines to be displayed. Defaults to 19.\n" +" 'maxSourceLines' => 20,\n" +" // Maximum number of trace source code lines to be displayed. Defaults to 13.\n" +" 'maxTraceLines' => 5,\n" +" // Trace the header line with placeholders (file, line, icon) to be substituted. Defaults to `null`.\n" +" 'traceHeaderLine' => '{icon}',\n" +" ]),\n" +" // ...\n" +"];\n" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "As aforementioned, the error handler turns all non-fatal PHP errors into catchable exceptions (`Yiisoft\\ErrorHandler\\Exception\\ErrorException`). This means you can use the following code to deal with PHP errors:" -msgstr "" +msgstr "Como dito acima, o error handler transforma todos os erros não fatais do PHP em exceções que podem ser capturadas (`Yiisoft\\ErrorHandler\\Exception\\ErrorException`). Isso significa que você pode usar o código a seguir para lidar com erros do PHP:" #. type: Fenced code block (php) #: ../src/guide/runtime/handling-errors.md @@ -147,11 +175,17 @@ msgid "" "}\n" "// execution continues...\n" msgstr "" +"try {\n" +" 10 / 0;\n" +"} catch (\\Yiisoft\\ErrorHandler\\Exception\\ErrorException $e) {\n" +" // Write a log or something else.\n" +"}\n" +"// execution continues...\n" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "The package has another middleware, `Yiisoft\\ErrorHandler\\Middleware\\ExceptionResponder`. This middleware maps certain exceptions to custom responses. Configure it in the application configuration as follows:" -msgstr "" +msgstr "O pacote tem outro middleware, `Yiisoft\\ErrorHandler\\Middleware\\ExceptionResponder`. Esse middleware mapeia certas exceções para respostas personalizadas. Configure-o na configuração da aplicação assim:" #. type: Fenced code block (php) #: ../src/guide/runtime/handling-errors.md @@ -176,57 +210,75 @@ msgid "" " },\n" "];\n" msgstr "" +"use Psr\\Http\\Message\\ResponseFactoryInterface;\n" +"use Yiisoft\\ErrorHandler\\Middleware\\ExceptionResponder;\n" +"use Yiisoft\\Injector\\Injector;\n" +"\n" +"return [\n" +" // ...\n" +" ExceptionResponder::class => static function (ResponseFactoryInterface $responseFactory, Injector $injector) {\n" +" $exceptionMap = [\n" +" // Status code with which the factory creates the response.\n" +" MyNotFoundException::class => 404,\n" +" // PHP callable that must return a `Psr\\Http\\Message\\ResponseInterface`.\n" +" MyHttpException::class => static fn (MyHttpException $exception) => new MyResponse($exception),\n" +" // ...\n" +" ];\n" +" \n" +" return new ExceptionResponder($exceptionMap, $responseFactory, $injector);\n" +" },\n" +"];\n" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "Note that when configuring application middleware stack, you must place `Yiisoft\\ErrorHandler\\Middleware\\ExceptionResponder` before `Yiisoft\\ErrorHandler\\Middleware\\ErrorCatcher`." -msgstr "" +msgstr "Ao configurar a pilha de middlewares da aplicação, você deve colocar `Yiisoft\\ErrorHandler\\Middleware\\ExceptionResponder` antes de `Yiisoft\\ErrorHandler\\Middleware\\ErrorCatcher`." #. type: Title ## #: ../src/guide/runtime/handling-errors.md #, no-wrap msgid "Rendering error data" -msgstr "" +msgstr "Renderizando os dados do erro" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "One of the renderers could render error data into a certain format. The following renderers are available out of the box:" -msgstr "" +msgstr "Cada renderer converte os dados do erro para um formato específico. Os seguintes renderers já vêm prontos:" #. type: Bullet: '- ' #: ../src/guide/runtime/handling-errors.md msgid "`Yiisoft\\ErrorHandler\\Renderer\\HeaderRenderer` - Renders error into HTTP headers. It's used for `HEAD` request." -msgstr "" +msgstr "`Yiisoft\\ErrorHandler\\Renderer\\HeaderRenderer` - Renderiza o erro em headers HTTP. É usado em requisições `HEAD`." #. type: Bullet: '- ' #: ../src/guide/runtime/handling-errors.md msgid "`Yiisoft\\ErrorHandler\\Renderer\\HtmlRenderer` - Renders error into HTML." -msgstr "" +msgstr "`Yiisoft\\ErrorHandler\\Renderer\\HtmlRenderer` - Renderiza o erro em HTML." #. type: Bullet: '- ' #: ../src/guide/runtime/handling-errors.md msgid "`Yiisoft\\ErrorHandler\\Renderer\\JsonRenderer` - Renders error into JSON." -msgstr "" +msgstr "`Yiisoft\\ErrorHandler\\Renderer\\JsonRenderer` - Renderiza o erro em JSON." #. type: Bullet: '- ' #: ../src/guide/runtime/handling-errors.md msgid "`Yiisoft\\ErrorHandler\\Renderer\\PlainTextRenderer` - Renders error into plain text." -msgstr "" +msgstr "`Yiisoft\\ErrorHandler\\Renderer\\PlainTextRenderer` - Renderiza o erro em texto puro." #. type: Bullet: '- ' #: ../src/guide/runtime/handling-errors.md msgid "`Yiisoft\\ErrorHandler\\Renderer\\XmlRenderer` - Renders error into XML." -msgstr "" +msgstr "`Yiisoft\\ErrorHandler\\Renderer\\XmlRenderer` - Renderiza o erro em XML." #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "The renderer produces detailed error data depending on whether debug mode is enabled or disabled." -msgstr "" +msgstr "O renderer gera dados de erro mais ou menos detalhados conforme o modo debug esteja ativado ou não." #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "An Example of header rendering with a debugging mode turned off:" -msgstr "" +msgstr "Exemplo de renderização em headers com o modo debug desativado:" #. type: Fenced code block #: ../src/guide/runtime/handling-errors.md @@ -236,11 +288,14 @@ msgid "" "X-Error-Message: An internal server error occurred.\n" "...\n" msgstr "" +"...\n" +"X-Error-Message: An internal server error occurred.\n" +"...\n" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "An Example of header rendering with a debugging mode turned on:" -msgstr "" +msgstr "Exemplo de renderização em headers com o modo debug ativado:" #. type: Fenced code block #: ../src/guide/runtime/handling-errors.md @@ -254,22 +309,29 @@ msgid "" "X-Error-Line: 21\n" "...\n" msgstr "" +"...\n" +"X-Error-Type: Error\n" +"X-Error-Message: Call to undefined function App\\Controller\\myFunc()\n" +"X-Error-Code: 0\n" +"X-Error-File: /var/www/yii/app/src/Controller/SiteController.php\n" +"X-Error-Line: 21\n" +"...\n" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "Example of JSON rendering output with a debugging mode turned off:" -msgstr "" +msgstr "Exemplo de saída JSON com o modo debug desativado:" #. type: Fenced code block (json) #: ../src/guide/runtime/handling-errors.md #, no-wrap msgid "{\"message\":\"An internal server error occurred.\"}\n" -msgstr "" +msgstr "{\"message\":\"An internal server error occurred.\"}\n" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "An Example of JSON rendering output with debugging mode turned on:" -msgstr "" +msgstr "Exemplo de saída JSON com o modo debug ativado:" #. type: Fenced code block (json) #: ../src/guide/runtime/handling-errors.md @@ -298,52 +360,74 @@ msgid "" " ]\n" "}\n" msgstr "" +"{\n" +" \"type\": \"Error\",\n" +" \"message\": \"Call to undefined function App\\\\Controller\\\\myFunc()\",\n" +" \"code\": 0,\n" +" \"file\": \"/var/www/yii/app/src/Controller/SiteController.php\",\n" +" \"line\": 21,\n" +" \"trace\": [\n" +" {\n" +" \"function\": \"index\",\n" +" \"class\": \"App\\\\Controller\\\\SiteController\",\n" +" \"type\": \"->\"\n" +" },\n" +" {\n" +" \"file\": \"/var/www/yii/app/vendor/yiisoft/injector/src/Injector.php\",\n" +" \"line\": 63,\n" +" \"function\": \"invokeArgs\",\n" +" \"class\": \"ReflectionFunction\",\n" +" \"type\": \"->\"\n" +" },\n" +" ...\n" +" ]\n" +"}\n" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "Example of HTML rendering with debugging mode turned off:" -msgstr "" +msgstr "Exemplo de renderização HTML com o modo debug desativado:" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "![View production](/images/guide/runtime/view-production.png)" -msgstr "" +msgstr "![Tela de produção](/images/guide/runtime/view-production.png)" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "Example of HTML rendering with debugging mode on and a light theme:" -msgstr "" +msgstr "Exemplo de renderização HTML com o modo debug ativado e tema claro:" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "![View development with light theme](/images/guide/runtime/view-development-light.png)" -msgstr "" +msgstr "![Tela de desenvolvimento com tema claro](/images/guide/runtime/view-development-light.png)" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "Example of HTML rendering with debugging mode on and a dark theme:" -msgstr "" +msgstr "Exemplo de renderização HTML com o modo debug ativado e tema escuro:" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "![View development with dark theme](/images/guide/runtime/view-development-dark.png)" -msgstr "" +msgstr "![Tela de desenvolvimento com tema escuro](/images/guide/runtime/view-development-dark.png)" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "The error catcher chooses how to render an exception based on `accept` HTTP header. If it's `text/html` or any unknown content type, it will use the error or exception HTML template to display errors. For other mime types, the error handler will choose different renderers registered in a renderer provider. By default, it supports JSON, XML, and plain text." -msgstr "" +msgstr "O error catcher escolhe como renderizar uma exceção com base no header HTTP `accept`. Se ele for `text/html` ou um tipo de conteúdo desconhecido, usa o template HTML de erro ou de exceção para exibir os erros. Para outros mime types, o error handler escolhe entre os renderers registrados em um renderer provider. Por padrão, ele suporta JSON, XML e texto puro." #. type: Title ### #: ../src/guide/runtime/handling-errors.md #, no-wrap msgid "Implementing your own renderer" -msgstr "" +msgstr "Implementando o seu próprio renderer" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "You may customize the error response format by implementing `Yiisoft\\ErrorHandler\\ThrowableRendererInterface`. The renderer converts a throwable into `Yiisoft\\ErrorHandler\\ErrorData`, which contains the response body and headers." -msgstr "" +msgstr "Você pode personalizar o formato da resposta de erro implementando `Yiisoft\\ErrorHandler\\ThrowableRendererInterface`. O renderer converte um throwable em `Yiisoft\\ErrorHandler\\ErrorData`, que contém o corpo e os headers da resposta." #. type: Fenced code block (php) #: ../src/guide/runtime/handling-errors.md @@ -382,11 +466,43 @@ msgid "" " }\n" "}\n" msgstr "" +"use Psr\\Http\\Message\\ServerRequestInterface;\n" +"use Throwable;\n" +"use Yiisoft\\ErrorHandler\\ErrorData;\n" +"use Yiisoft\\ErrorHandler\\ThrowableRendererInterface;\n" +"use Yiisoft\\Http\\Header;\n" +"\n" +"final readonly class MyRenderer implements ThrowableRendererInterface\n" +"{\n" +" public function render(Throwable $t, ?ServerRequestInterface $request = null): ErrorData\n" +" {\n" +" return new ErrorData(\n" +" '{\"message\":\"An internal server error occurred.\"}',\n" +" [Header::CONTENT_TYPE => 'application/problem+json'],\n" +" );\n" +" }\n" +"\n" +" public function renderVerbose(Throwable $t, ?ServerRequestInterface $request = null): ErrorData\n" +" {\n" +" return new ErrorData(\n" +" json_encode(\n" +" [\n" +" 'type' => $t::class,\n" +" 'message' => $t->getMessage(),\n" +" 'file' => $t->getFile(),\n" +" 'line' => $t->getLine(),\n" +" ],\n" +" JSON_THROW_ON_ERROR | JSON_UNESCAPED_SLASHES,\n" +" ),\n" +" [Header::CONTENT_TYPE => 'application/problem+json'],\n" +" );\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "Register the renderer in `config/common/di/error-handler.php`:" -msgstr "" +msgstr "Registre o renderer em `config/common/di/error-handler.php`:" #. type: Fenced code block (php) #: ../src/guide/runtime/handling-errors.md @@ -427,22 +543,56 @@ msgid "" " ],\n" "];\n" msgstr "" +"use Psr\\Container\\ContainerInterface;\n" +"use App\\Error\\MyRenderer;\n" +"use Yiisoft\\Definitions\\DynamicReference;\n" +"use Yiisoft\\ErrorHandler\\Renderer\\HtmlRenderer;\n" +"use Yiisoft\\ErrorHandler\\Renderer\\JsonRenderer;\n" +"use Yiisoft\\ErrorHandler\\Renderer\\PlainTextRenderer;\n" +"use Yiisoft\\ErrorHandler\\Renderer\\XmlRenderer;\n" +"use Yiisoft\\ErrorHandler\\RendererProvider\\CompositeRendererProvider;\n" +"use Yiisoft\\ErrorHandler\\RendererProvider\\ContentTypeRendererProvider;\n" +"use Yiisoft\\ErrorHandler\\RendererProvider\\HeadRendererProvider;\n" +"use Yiisoft\\ErrorHandler\\ThrowableResponseFactory;\n" +"use Yiisoft\\ErrorHandler\\ThrowableResponseFactoryInterface;\n" +"\n" +"return [\n" +" ThrowableResponseFactoryInterface::class => [\n" +" 'class' => ThrowableResponseFactory::class,\n" +" '__construct()' => [\n" +" 'rendererProvider' => DynamicReference::to(\n" +" static fn (ContainerInterface $container) => new CompositeRendererProvider(\n" +" new HeadRendererProvider(),\n" +" new ContentTypeRendererProvider($container, [\n" +" 'application/problem+json' => MyRenderer::class,\n" +" 'application/json' => JsonRenderer::class,\n" +" 'application/xml' => XmlRenderer::class,\n" +" 'text/xml' => XmlRenderer::class,\n" +" 'text/plain' => PlainTextRenderer::class,\n" +" 'text/html' => HtmlRenderer::class,\n" +" '*/*' => HtmlRenderer::class,\n" +" ]),\n" +" ),\n" +" ),\n" +" ],\n" +" ],\n" +"];\n" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "The `renderers` array maps `Accept` header content types to renderer class names. When you provide this array, it replaces the default map, so include the default renderer classes you still need." -msgstr "" +msgstr "O array `renderers` mapeia os tipos de conteúdo do header `Accept` para nomes de classes de renderer. Quando você informa esse array, ele substitui o mapa padrão, então inclua as classes de renderer padrão que ainda precisar." #. type: Title ## #: ../src/guide/runtime/handling-errors.md #, no-wrap msgid "Friendly exceptions" -msgstr "" +msgstr "Exceções amigáveis" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "Yii error renderer supports [friendly exceptions](https://github.com/yiisoft/friendly-exception) that make error handling an even more pleasant experience for your team. The idea is to offer a readable name and possible solutions to the problem:" -msgstr "" +msgstr "O renderer de erros do Yii suporta [exceções amigáveis](https://github.com/yiisoft/friendly-exception), que deixam o tratamento de erros ainda mais agradável para o seu time. A ideia é oferecer um nome legível e possíveis soluções para o problema:" #. type: Fenced code block (php) #: ../src/guide/runtime/handling-errors.md @@ -465,8 +615,24 @@ msgid "" " }\n" "}\n" msgstr "" +"use Yiisoft\\FriendlyException\\FriendlyExceptionInterface;\n" +"\n" +"final readonly class RequestTimeoutException extends \\RuntimeException implements FriendlyExceptionInterface\n" +"{\n" +" public function getName(): string\n" +" {\n" +" return 'Request timed out';\n" +" }\n" +" \n" +" public function getSolution(): ?string\n" +" {\n" +" return <<<'SOLUTION'\n" +"Likely it is a result of resource request is not responding in a timely fashion. Try increasing timeout.\n" +"SOLUTION;\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "When the application throws such an exception, the error renderer would display the name and the solution if the debug mode is on." -msgstr "" +msgstr "Quando a aplicação lança uma exceção desse tipo, o renderer de erros mostra o nome e a solução se o modo debug estiver ativado." diff --git a/_translations/po/pt-BR/guide_runtime_logging.md.po b/_translations/po/pt-BR/guide_runtime_logging.md.po index 55153f4d..2c8dc76d 100644 --- a/_translations/po/pt-BR/guide_runtime_logging.md.po +++ b/_translations/po/pt-BR/guide_runtime_logging.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-10-15 10:10+0000\n" "PO-Revision-Date: 2026-10-15 10:10+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,53 +19,53 @@ msgstr "" #: ../src/guide/runtime/logging.md #, no-wrap msgid "Logging" -msgstr "" +msgstr "Logs" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "Yii relies on [PSR-3 interfaces](https://www.php-fig.org/psr/psr-3/) for logging, so you could configure any PSR-3 compatible logging library to do the actual job." -msgstr "" +msgstr "O Yii usa as [interfaces PSR-3](https://www.php-fig.org/psr/psr-3/) para logs, então você pode configurar qualquer biblioteca de log compatível com a PSR-3 para fazer o trabalho." #. type: Plain text #: ../src/guide/runtime/logging.md msgid "Yii provides its own logger that's highly customizable and extensible. Using it, you can log various types of messages, filter them, and gather them at different targets, such as files or emails." -msgstr "" +msgstr "O Yii oferece o seu próprio logger, que é bem personalizável e extensível. Com ele, você pode registrar vários tipos de mensagens, filtrá-las e reuni-las em destinos diferentes, como arquivos ou e-mails." #. type: Plain text #: ../src/guide/runtime/logging.md msgid "Using the Yii logging framework involves the following steps:" -msgstr "" +msgstr "Usar o sistema de logs do Yii envolve os seguintes passos:" #. type: Bullet: '* ' #: ../src/guide/runtime/logging.md msgid "Record [log messages](#log-messages) at various places in your code;" -msgstr "" +msgstr "Registrar [mensagens de log](#mensagens-de-log) em vários pontos do código;" #. type: Bullet: '* ' #: ../src/guide/runtime/logging.md msgid "Configure [log targets](#log-targets) in the application configuration to filter and export log messages;" -msgstr "" +msgstr "Configurar [destinos de log](#destinos-de-log) na configuração da aplicação para filtrar e exportar as mensagens;" #. type: Bullet: '* ' #: ../src/guide/runtime/logging.md msgid "Examine the filtered logged messages exported by different targets (e.g. the Yii debugger)." -msgstr "" +msgstr "Examinar as mensagens filtradas exportadas pelos diferentes destinos (por exemplo, o debugger do Yii)." #. type: Plain text #: ../src/guide/runtime/logging.md msgid "In this section, the focus in on the first two steps." -msgstr "" +msgstr "Esta seção foca nos dois primeiros passos." #. type: Title ## #: ../src/guide/runtime/logging.md #, no-wrap msgid "Default log destination" -msgstr "" +msgstr "Destino padrão dos logs" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "Yii3 application templates ([web](https://github.com/yiisoft/app/blob/master/config/common/di/logger.php) and [API](https://github.com/yiisoft/app-api/blob/master/config/common/di/logger.php)) configure `Yiisoft\\Log\\StreamTarget`, which writes to standard output (`stdout`, or `php://stdout`) by default. They don't create application log files, such as `runtime/logs/app.log`. `StreamTarget` also supports standard error (`stderr`, or `php://stderr`), but you must configure it explicitly." -msgstr "" +msgstr "Os templates de aplicação do Yii3 ([web](https://github.com/yiisoft/app/blob/master/config/common/di/logger.php) e [API](https://github.com/yiisoft/app-api/blob/master/config/common/di/logger.php)) configuram o `Yiisoft\\Log\\StreamTarget`, que por padrão escreve na saída padrão (`stdout`, ou `php://stdout`). Eles não criam arquivos de log da aplicação, como `runtime/logs/app.log`. O `StreamTarget` também suporta a saída de erro padrão (`stderr`, ou `php://stderr`), mas você precisa configurá-la explicitamente." #. type: Plain text #: ../src/guide/runtime/logging.md @@ -74,22 +74,24 @@ msgid "" "This works well with Docker, which [collects container output](https://docs.docker.com/engine/logging/).\n" "Use `docker logs ` to read it when the container's logging driver supports that command.\n" msgstr "" +"Isso funciona bem com o Docker, que [coleta a saída dos containers](https://docs.docker.com/engine/logging/).\n" +"Use `docker logs ` para lê-la quando o driver de log do container suportar esse comando.\n" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "Without containers, the destination depends on how you start PHP and capture its output. For example, PHP-FPM discards worker output by default unless you enable `catch_workers_output`. See [web server logging configuration](../../cookbook/configuring-webservers/general.md#application-logs). To have Yii write application log files directly, configure a [file target](#logging-to-files)." -msgstr "" +msgstr "Sem containers, o destino depende de como você inicia o PHP e captura a saída dele. Por exemplo, o PHP-FPM descarta a saída dos workers por padrão, a menos que você ative `catch_workers_output`. Veja a [configuração de logs do servidor web](../../cookbook/configuring-webservers/general.md#application-logs). Para o Yii escrever arquivos de log da aplicação diretamente, configure um [destino em arquivo](#logs-em-arquivos)." #. type: Title ## #: ../src/guide/runtime/logging.md #, no-wrap msgid "Log Messages" -msgstr "" +msgstr "Mensagens de log" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "To record log messages, you need an instance of PSR-3 logger. A class that writes log messages should receive it as a dependency:" -msgstr "" +msgstr "Para registrar mensagens de log, você precisa de uma instância de um logger PSR-3. Uma classe que escreve mensagens de log deve recebê-lo como dependência:" #. type: Fenced code block (php) #: ../src/guide/runtime/logging.md @@ -105,56 +107,65 @@ msgid "" " }\n" "}\n" msgstr "" +"class MyService\n" +"{\n" +" private $logger;\n" +" \n" +" public function __construct(\\Psr\\Log\\LoggerInterface $logger)\n" +" {\n" +" $this->logger = $logger; \n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "Recording a log message is as simple as calling one of the following logging methods that correspond to log levels:" -msgstr "" +msgstr "Registrar uma mensagem de log é tão simples quanto chamar um dos métodos a seguir, que correspondem aos níveis de log:" #. type: Bullet: '- ' #: ../src/guide/runtime/logging.md msgid "`emergency` - System is unusable." -msgstr "" +msgstr "`emergency` - O sistema está inutilizável." #. type: Bullet: '- ' #: ../src/guide/runtime/logging.md msgid "`alert` - Action must be taken immediately. Example: Entire website down, database unavailable, etc. This should trigger the SMS alerts and wake you up." -msgstr "" +msgstr "`alert` - É preciso agir imediatamente. Exemplo: site inteiro fora do ar, banco de dados indisponível etc. Isso deve disparar os alertas por SMS e acordar você." #. type: Bullet: '- ' #: ../src/guide/runtime/logging.md msgid "`critical` - Critical conditions. Example: Application component unavailable, unexpected exception." -msgstr "" +msgstr "`critical` - Condições críticas. Exemplo: componente da aplicação indisponível, exceção inesperada." #. type: Bullet: '- ' #: ../src/guide/runtime/logging.md msgid "`error` - Runtime errors that don't require immediate action but should typically be logged and monitored." -msgstr "" +msgstr "`error` - Erros em tempo de execução que não exigem ação imediata, mas normalmente devem ser registrados e monitorados." #. type: Bullet: '- ' #: ../src/guide/runtime/logging.md msgid "`warning` - Exceptional occurrences that aren't errors. Example: Use of deprecated APIs, poor use of an API, undesirable things that aren't necessarily wrong." -msgstr "" +msgstr "`warning` - Ocorrências excepcionais que não são erros. Exemplo: uso de APIs obsoletas, uso inadequado de uma API, coisas indesejáveis que não estão necessariamente erradas." #. type: Bullet: '- ' #: ../src/guide/runtime/logging.md msgid "`notice` - Normal but significant events." -msgstr "" +msgstr "`notice` - Eventos normais, mas significativos." #. type: Bullet: '- ' #: ../src/guide/runtime/logging.md msgid "`info` - Interesting events. Example: User logs in, SQL logs." -msgstr "" +msgstr "`info` - Eventos interessantes. Exemplo: login de usuário, logs de SQL." #. type: Bullet: '- ' #: ../src/guide/runtime/logging.md msgid "`debug` - Detailed debug information." -msgstr "" +msgstr "`debug` - Informações detalhadas de debug." #. type: Plain text #: ../src/guide/runtime/logging.md msgid "Each method has two arguments. The first is a message. The Second is a context array that typically has structured data that doesn't fit a message well but still does offer important information. In case you provide an exception as context, you should pass the \"exception\" key. Another special key is \"category.\" Categories are handy to better organize and filter log messages." -msgstr "" +msgstr "Cada método tem dois argumentos. O primeiro é a mensagem. O segundo é um array de contexto, que normalmente tem dados estruturados que não cabem bem na mensagem, mas trazem informações importantes. Se você passar uma exceção no contexto, use a chave \"exception\". Outra chave especial é \"category\". As categorias ajudam a organizar e filtrar melhor as mensagens de log." #. type: Fenced code block (php) #: ../src/guide/runtime/logging.md @@ -176,16 +187,31 @@ msgid "" " }\n" "}\n" msgstr "" +"use \\Psr\\Log\\LoggerInterface;\n" +"\n" +"final readonly class MyService\n" +"{\n" +" public function __construct(\n" +" private LoggerInterface $logger\n" +" )\n" +" { \n" +" }\n" +"\n" +" public function serve(): void\n" +" {\n" +" $this->logger->info('MyService is serving', ['context' => __METHOD__]); \n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "When deciding on a category for a message, you may choose a hierarchical naming scheme, which will make it easier for [log targets](#log-targets) to filter messages based on their categories. A simple yet effective naming scheme is to use the PHP magic constant `__METHOD__` for the category names. This is also the approach used in the core Yii framework code." -msgstr "" +msgstr "Ao escolher a categoria de uma mensagem, você pode adotar um esquema de nomes hierárquico, o que facilita para os [destinos de log](#destinos-de-log) filtrarem as mensagens pela categoria. Um esquema simples e eficaz é usar a constante mágica do PHP `__METHOD__` como nome da categoria. Essa também é a abordagem usada no código do core do Yii." #. type: Plain text #: ../src/guide/runtime/logging.md msgid "The `__METHOD__` constant evaluates as the name of the method (prefixed with the fully qualified class name) where the constant appears. For example, it's equal to the string `'App\\\\Service\\\\MyService::serve'` if the above line of code is called within this method." -msgstr "" +msgstr "A constante `__METHOD__` resulta no nome do método (prefixado com o nome completo da classe) onde ela aparece. Por exemplo, ela é igual à string `'App\\\\Service\\\\MyService::serve'` se a linha de código acima for chamada dentro desse método." #. type: Plain text #: ../src/guide/runtime/logging.md @@ -194,27 +220,29 @@ msgid "" "> [!IMPORTANT]\n" "> The logging methods described above are actually shortcuts to the [[\\Psr\\Log\\LoggerInterface::log()]].\n" msgstr "" +"> [!IMPORTANT]\n" +"> Os métodos de log descritos acima são, na verdade, atalhos para [[\\Psr\\Log\\LoggerInterface::log()]].\n" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "Note that PSR-3 package provides `\\Psr\\Log\\NullLogger` class that provides the same set of methods but doesn't log anything. That means that you don't have to check if logger is configured with `if ($logger !== null)` and, instead, can assume that logger is always present." -msgstr "" +msgstr "O pacote PSR-3 tem a classe `\\Psr\\Log\\NullLogger`, que oferece o mesmo conjunto de métodos, mas não registra nada. Isso significa que você não precisa verificar se o logger está configurado com `if ($logger !== null)` e pode assumir que o logger sempre existe." #. type: Title ## #: ../src/guide/runtime/logging.md #, no-wrap msgid "Log targets" -msgstr "" +msgstr "Destinos de log" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "A log target is an instance of a class that extends the [[\\Yiisoft\\Log\\Target]]. It filters the log messages by their severity levels and categories and then exports them to some medium. For example, a [[\\Yiisoft\\Log\\Target\\File\\FileTarget|file target]]exports the filtered log messages to a file, while a [[Yiisoft\\Log\\Target\\Email\\EmailTarget|email target]] exports the log messages to specified email addresses." -msgstr "" +msgstr "Um destino de log é uma instância de uma classe que estende [[\\Yiisoft\\Log\\Target]]. Ele filtra as mensagens de log pelo nível de severidade e pela categoria e depois as exporta para algum meio. Por exemplo, um [[\\Yiisoft\\Log\\Target\\File\\FileTarget|destino em arquivo]] exporta as mensagens filtradas para um arquivo, enquanto um [[Yiisoft\\Log\\Target\\Email\\EmailTarget|destino por e-mail]] exporta as mensagens para os endereços de e-mail definidos." #. type: Plain text #: ../src/guide/runtime/logging.md msgid "You can register many log targets in an application by configuring them through the `\\Yiisoft\\Log\\Logger` constructor:" -msgstr "" +msgstr "Você pode registrar vários destinos de log em uma aplicação configurando-os no construtor de `\\Yiisoft\\Log\\Logger`:" #. type: Fenced code block (php) #: ../src/guide/runtime/logging.md @@ -234,16 +262,29 @@ msgid "" " $emailTarget\n" "]);\n" msgstr "" +"use \\Psr\\Log\\LogLevel;\n" +"\n" +"$fileTarget = new \\Yiisoft\\Log\\Target\\File\\FileTarget('/path/to/app.log');\n" +"$fileTarget->setLevels([LogLevel::ERROR, LogLevel::WARNING]);\n" +"\n" +"$emailTarget = new \\Yiisoft\\Log\\Target\\Email\\EmailTarget($mailer, ['to' => 'log@example.com']);\n" +"$emailTarget->setLevels([LogLevel::EMERGENCY, LogLevel::ALERT, LogLevel::CRITICAL]);\n" +"$emailTarget->setCategories(['Yiisoft\\Cache\\*']); \n" +"\n" +"$logger = new \\Yiisoft\\Log\\Logger([\n" +" $fileTarget,\n" +" $emailTarget\n" +"]);\n" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "In the above code, two log targets are registered:" -msgstr "" +msgstr "No código acima, dois destinos de log são registrados:" #. type: Bullet: '* ' #: ../src/guide/runtime/logging.md msgid "the first target selects error and warning messages and writes them to `/path/to/app.log` file;" -msgstr "" +msgstr "o primeiro seleciona as mensagens de erro e de warning e as grava no arquivo `/path/to/app.log`;" #. type: Plain text #: ../src/guide/runtime/logging.md @@ -252,63 +293,65 @@ msgid "" "* the second target selects emergency, alert, and critical messages under the categories whose names start with\n" "`Yiisoft\\Cache\\`, and sends them in an email to both `admin@example.com` and `developer@example.com`.\n" msgstr "" +"* o segundo seleciona as mensagens de emergency, alert e critical das categorias cujos nomes começam com\n" +"`Yiisoft\\Cache\\` e as envia por e-mail para `admin@example.com` e `developer@example.com`.\n" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "Yii comes with the following built-in log targets. Please refer to the API documentation about these classes to learn how to configure and use them." -msgstr "" +msgstr "O Yii vem com os seguintes destinos de log embutidos. Consulte a documentação da API dessas classes para saber como configurá-los e usá-los." #. type: Bullet: '* ' #: ../src/guide/runtime/logging.md msgid "[[\\Yiisoft\\Log\\PsrTarget]]: passes log messages to another PSR-3 compatible logger." -msgstr "" +msgstr "[[\\Yiisoft\\Log\\PsrTarget]]: repassa as mensagens de log para outro logger compatível com a PSR-3." #. type: Bullet: '* ' #: ../src/guide/runtime/logging.md msgid "[[\\Yiisoft\\Log\\StreamTarget]]: writes log messages into a specified output stream." -msgstr "" +msgstr "[[\\Yiisoft\\Log\\StreamTarget]]: escreve as mensagens de log em um stream de saída definido." #. type: Bullet: '* ' #: ../src/guide/runtime/logging.md msgid "[[\\Yiisoft\\Log\\Target\\Db\\DbTarget]]: saves log messages in database." -msgstr "" +msgstr "[[\\Yiisoft\\Log\\Target\\Db\\DbTarget]]: salva as mensagens de log no banco de dados." #. type: Bullet: '* ' #: ../src/guide/runtime/logging.md msgid "[[\\Yiisoft\\Log\\Target\\Email\\EmailTarget]]: sends log messages to pre-specified email addresses." -msgstr "" +msgstr "[[\\Yiisoft\\Log\\Target\\Email\\EmailTarget]]: envia as mensagens de log para endereços de e-mail definidos." #. type: Bullet: '* ' #: ../src/guide/runtime/logging.md msgid "[[\\Yiisoft\\Log\\Target\\File\\FileTarget]]: saves log messages in files." -msgstr "" +msgstr "[[\\Yiisoft\\Log\\Target\\File\\FileTarget]]: salva as mensagens de log em arquivos." #. type: Bullet: '* ' #: ../src/guide/runtime/logging.md msgid "[[\\Yiisoft\\Log\\Target\\Syslog\\SyslogTarget]]: saves log messages to syslog by calling the PHP function `syslog()`." -msgstr "" +msgstr "[[\\Yiisoft\\Log\\Target\\Syslog\\SyslogTarget]]: salva as mensagens de log no syslog chamando a função PHP `syslog()`." #. type: Title ### #: ../src/guide/runtime/logging.md #, no-wrap msgid "Logging to files" -msgstr "" +msgstr "Logs em arquivos" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "To write application logs to a file, install the file target package:" -msgstr "" +msgstr "Para gravar os logs da aplicação em um arquivo, instale o pacote do destino em arquivo:" #. type: Fenced code block (shell) #: ../src/guide/runtime/logging.md #, no-wrap msgid "composer require yiisoft/log-target-file\n" -msgstr "" +msgstr "composer require yiisoft/log-target-file\n" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "In your application's `config/common/di/logger.php`, replace the `StreamTarget` reference with `FileTarget`:" -msgstr "" +msgstr "No `config/common/di/logger.php` da sua aplicação, troque a referência ao `StreamTarget` por `FileTarget`:" #. type: Fenced code block (php) #: ../src/guide/runtime/logging.md @@ -330,16 +373,31 @@ msgid "" " ],\n" "];\n" msgstr "" +"use Psr\\Log\\LoggerInterface;\n" +"use Yiisoft\\Definitions\\ReferencesArray;\n" +"use Yiisoft\\Log\\Logger;\n" +"use Yiisoft\\Log\\Target\\File\\FileTarget;\n" +"\n" +"return [\n" +" LoggerInterface::class => [\n" +" 'class' => Logger::class,\n" +" '__construct()' => [\n" +" 'targets' => ReferencesArray::from([\n" +" FileTarget::class,\n" +" ]),\n" +" ],\n" +" ],\n" +"];\n" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "The package's default configuration writes to `@runtime/logs/app.log` and enables log rotation. To change the path, set `$params['yiisoft/log-target-file']['fileTarget']['file']` in `config/common/params.php`. Ensure that the PHP process can write to the log directory, and keep it outside the web server's document root." -msgstr "" +msgstr "A configuração padrão do pacote grava em `@runtime/logs/app.log` e ativa a rotação de logs. Para mudar o caminho, defina `$params['yiisoft/log-target-file']['fileTarget']['file']` em `config/common/params.php`. Garanta que o processo do PHP consiga escrever no diretório de logs e mantenha esse diretório fora do document root do servidor web." #. type: Plain text #: ../src/guide/runtime/logging.md msgid "The file target package's default configuration also filters out `alert`, `critical`, and `notice` messages. The templates' `StreamTarget` accepts all eight log levels. To keep that behavior, add the following entry to the array that `config/common/params.php` returns:" -msgstr "" +msgstr "A configuração padrão do pacote de destino em arquivo também descarta as mensagens `alert`, `critical` e `notice`. O `StreamTarget` dos templates aceita os oito níveis de log. Para manter esse comportamento, adicione a seguinte entrada ao array retornado por `config/common/params.php`:" #. type: Fenced code block (php) #: ../src/guide/runtime/logging.md @@ -365,52 +423,71 @@ msgid "" " ],\n" "];\n" msgstr "" +"use Psr\\Log\\LogLevel;\n" +"\n" +"return [\n" +" // Other application parameters...\n" +" 'yiisoft/log-target-file' => [\n" +" 'fileTarget' => [\n" +" 'levels' => [\n" +" LogLevel::EMERGENCY,\n" +" LogLevel::ALERT,\n" +" LogLevel::CRITICAL,\n" +" LogLevel::ERROR,\n" +" LogLevel::WARNING,\n" +" LogLevel::NOTICE,\n" +" LogLevel::INFO,\n" +" LogLevel::DEBUG,\n" +" ],\n" +" ],\n" +" ],\n" +"];\n" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "In the following, we will describe the features common to all log targets." -msgstr "" +msgstr "A seguir, descrevemos os recursos comuns a todos os destinos de log." #. type: Title ### #: ../src/guide/runtime/logging.md #, no-wrap msgid "Message Filtering" -msgstr "" +msgstr "Filtragem de mensagens" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "For each log target, you can configure its levels and categories to specify which severity levels and categories of the messages the target should process." -msgstr "" +msgstr "Para cada destino de log, você pode configurar os níveis e as categorias, definindo quais níveis de severidade e quais categorias de mensagens o destino deve processar." #. type: Plain text #: ../src/guide/runtime/logging.md msgid "The target `setLevels()` method takes an array consisting of one or several of `\\Psr\\Log\\LogLevel` constants." -msgstr "" +msgstr "O método `setLevels()` do destino recebe um array com uma ou mais constantes de `\\Psr\\Log\\LogLevel`." #. type: Plain text #: ../src/guide/runtime/logging.md msgid "By default, the target will process messages of *any* severity level." -msgstr "" +msgstr "Por padrão, o destino processa mensagens de *qualquer* nível de severidade." #. type: Plain text #: ../src/guide/runtime/logging.md msgid "The target `setCategories()` method takes an array consisting of message category names or patterns. A target will only process messages whose category can be found or match one of the patterns in this array. A category pattern is a category name prefix with an asterisk `*` at its end. A category name matches a category pattern if it starts with the same prefix of the pattern. For example, `Yiisoft\\Cache\\Cache::set` and `Yiisoft\\Cache\\Cache::get` both match the pattern `Yiisoft\\Cache\\*`." -msgstr "" +msgstr "O método `setCategories()` do destino recebe um array com nomes ou padrões de categorias de mensagens. O destino só processa as mensagens cuja categoria esteja no array ou case com um dos padrões dele. Um padrão de categoria é um prefixo de nome de categoria com um asterisco `*` no final. Um nome de categoria casa com o padrão se começar com o mesmo prefixo. Por exemplo, `Yiisoft\\Cache\\Cache::set` e `Yiisoft\\Cache\\Cache::get` casam com o padrão `Yiisoft\\Cache\\*`." #. type: Plain text #: ../src/guide/runtime/logging.md msgid "By default, the target will process messages of *any* category." -msgstr "" +msgstr "Por padrão, o destino processa mensagens de *qualquer* categoria." #. type: Plain text #: ../src/guide/runtime/logging.md msgid "Besides allowing the categories by the `setCategories()` method, you may also deny certain categories by the `setExcept()` method. If the category of a message is found or matches one of the patterns in this property, the target will NOT process it." -msgstr "" +msgstr "Além de permitir categorias com o método `setCategories()`, você também pode negar certas categorias com o método `setExcept()`. Se a categoria de uma mensagem estiver nessa lista ou casar com um dos padrões dela, o destino NÃO vai processá-la." #. type: Plain text #: ../src/guide/runtime/logging.md msgid "The following target configuration specifies that the target should only process error and warning messages under the categories whose names match either `Yiisoft\\Cache\\*` or `App\\Exceptions\\HttpException:*`, but not `App\\Exceptions\\HttpException:404`." -msgstr "" +msgstr "A configuração a seguir define que o destino só deve processar mensagens de erro e de warning das categorias cujos nomes casem com `Yiisoft\\Cache\\*` ou `App\\Exceptions\\HttpException:*`, mas não com `App\\Exceptions\\HttpException:404`." #. type: Fenced code block (php) #: ../src/guide/runtime/logging.md @@ -421,17 +498,21 @@ msgid "" "$fileTarget->setCategories(['Yiisoft\\Cache\\*', 'App\\Exceptions\\HttpException:*']);\n" "$fileTarget->setExcept(['App\\Exceptions\\HttpException:404']);\n" msgstr "" +"$fileTarget = new \\Yiisoft\\Log\\Target\\File\\FileTarget('/path/to/app.log');\n" +"$fileTarget->setLevels([LogLevel::ERROR, LogLevel::WARNING]);\n" +"$fileTarget->setCategories(['Yiisoft\\Cache\\*', 'App\\Exceptions\\HttpException:*']);\n" +"$fileTarget->setExcept(['App\\Exceptions\\HttpException:404']);\n" #. type: Title ### #: ../src/guide/runtime/logging.md #, no-wrap msgid "Message Formatting" -msgstr "" +msgstr "Formatação de mensagens" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "Log targets export the filtered log messages in a certain format. For example, if you install a log target of the class [[\\Yiisoft\\Log\\Target\\File\\FileTarget]], you may find a log message similar to the following in the log file:" -msgstr "" +msgstr "Os destinos de log exportam as mensagens filtradas em um certo formato. Por exemplo, se você instalar um destino de log da classe [[\\Yiisoft\\Log\\Target\\File\\FileTarget]], pode encontrar no arquivo de log uma mensagem parecida com esta:" #. type: Fenced code block #: ../src/guide/runtime/logging.md @@ -445,22 +526,29 @@ msgid "" "memory: 4398536\n" "category: 'application'\n" msgstr "" +"2020-12-05 09:27:52.223800 [info][application] Some message\n" +"\n" +"Message context:\n" +"\n" +"time: 1607160472.2238\n" +"memory: 4398536\n" +"category: 'application'\n" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "By default, log messages have the following format:" -msgstr "" +msgstr "Por padrão, as mensagens de log têm o seguinte formato:" #. type: Fenced code block #: ../src/guide/runtime/logging.md #, no-wrap msgid "Timestamp Prefix[Level][Category] Message Context\n" -msgstr "" +msgstr "Timestamp Prefix[Level][Category] Message Context\n" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "You may customize this format by calling [[\\Yiisoft\\Log\\Target::setFormat()|setFormat()]] method, which takes a PHP callable returning a custom-formatted message." -msgstr "" +msgstr "Você pode personalizar esse formato chamando o método [[\\Yiisoft\\Log\\Target::setFormat()|setFormat()]], que recebe um callable PHP que retorna a mensagem formatada." #. type: Fenced code block (php) #: ../src/guide/runtime/logging.md @@ -479,11 +567,23 @@ msgid "" "// Result:\n" "// (APP) [info] Text message\n" msgstr "" +"$fileTarget = new \\Yiisoft\\Log\\Target\\File\\FileTarget('/path/to/app.log');\n" +"\n" +"$fileTarget->setFormat(static function (\\Yiisoft\\Log\\Message $message) {\n" +" $category = strtoupper($message->context('category'));\n" +" return \"({$category}) [{$message->level()}] {$message->message()}\";\n" +"});\n" +"\n" +"$logger = new \\Yiisoft\\Log\\Logger([$fileTarget]);\n" +"$logger->info('Text message', ['category' => 'app']);\n" +"\n" +"// Result:\n" +"// (APP) [info] Text message\n" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "In addition, if you're comfortable with the default message format but need to change the timestamp format or add custom data to the message, you can call the [[\\Yiisoft\\Log\\Target::setTimestampFormat()|setTimestampFormat()]] and [[\\Yiisoft\\Log\\Target::setPrefix()|setPrefix()]] methods. For example, the following code changes the timestamp format and configures a log target to prefix each log message with the current user ID (IP address and Session ID are removed for privacy reasons)." -msgstr "" +msgstr "Além disso, se o formato padrão da mensagem servir para você, mas for preciso mudar o formato do timestamp ou adicionar dados à mensagem, você pode chamar os métodos [[\\Yiisoft\\Log\\Target::setTimestampFormat()|setTimestampFormat()]] e [[\\Yiisoft\\Log\\Target::setPrefix()|setPrefix()]]. Por exemplo, o código a seguir muda o formato do timestamp e configura um destino de log para prefixar cada mensagem com o ID do usuário atual (o endereço IP e o ID da sessão foram removidos por questões de privacidade)." #. type: Fenced code block (php) #: ../src/guide/runtime/logging.md @@ -505,17 +605,32 @@ msgid "" "// Message context: ...\n" "// Common context: ...\n" msgstr "" +"$fileTarget = new \\Yiisoft\\Log\\Target\\File\\FileTarget('/path/to/app.log');\n" +"$userId = '123e4567-e89b-12d3-a456-426655440000';\n" +"\n" +"// Default: 'Y-m-d H: i: s.u'\n" +"$fileTarget->setTimestampFormat('D d F Y');\n" +"// Default: ''\n" +"$fileTarget->setPrefix(static fn () => \"[{$userId}]\");\n" +"\n" +"$logger = new \\Yiisoft\\Log\\Logger([$fileTarget]);\n" +"$logger->info('Text', ['category' => 'user']);\n" +"\n" +"// Result:\n" +"// Fri 04 December 2020 [123e4567-e89b-12d3-a456-426655440000][info][user] Text\n" +"// Message context: ...\n" +"// Common context: ...\n" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "The PHP callable that's passed to the [[\\Yiisoft\\Log\\Target::setFormat()|setFormat()]] and [[\\Yiisoft\\Log\\Target::setPrefix()|setPrefix()]] methods has the following signature:" -msgstr "" +msgstr "O callable PHP passado para os métodos [[\\Yiisoft\\Log\\Target::setFormat()|setFormat()]] e [[\\Yiisoft\\Log\\Target::setPrefix()|setPrefix()]] tem a seguinte assinatura:" #. type: Fenced code block (php) #: ../src/guide/runtime/logging.md #, no-wrap msgid "function (\\Yiisoft\\Log\\Message $message, array $commonContext): string;\n" -msgstr "" +msgstr "function (\\Yiisoft\\Log\\Message $message, array $commonContext): string;\n" #. type: Plain text #: ../src/guide/runtime/logging.md @@ -527,6 +642,11 @@ msgid "" "For example, the following log target configuration specifies that only the\n" "value of the `$_SERVER` variable will be appended to the log messages.\n" msgstr "" +"Além dos prefixos, os destinos de log também acrescentam algumas informações de contexto comuns a cada mensagem de log.\n" +"Você pode ajustar esse comportamento chamando o método [[\\Yiisoft\\Log\\Target::setCommonContext()|setCommonContext()]]\n" +"do destino, passando um array de dados no formato `key => value` com o que você quer incluir.\n" +"Por exemplo, a configuração de destino a seguir define que apenas o\n" +"valor da variável `$_SERVER` será acrescentado às mensagens de log.\n" #. type: Fenced code block (php) #: ../src/guide/runtime/logging.md @@ -535,17 +655,19 @@ msgid "" "$fileTarget = new \\Yiisoft\\Log\\Target\\File\\FileTarget('/path/to/app.log');\n" "$fileTarget->setCommonContext(['server' => $_SERVER]);\n" msgstr "" +"$fileTarget = new \\Yiisoft\\Log\\Target\\File\\FileTarget('/path/to/app.log');\n" +"$fileTarget->setCommonContext(['server' => $_SERVER]);\n" #. type: Title ### #: ../src/guide/runtime/logging.md #, no-wrap msgid "Message Trace Level" -msgstr "" +msgstr "Nível de trace das mensagens" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "During development, it's often desirable to see where each log message is coming from. You can achieve this by calling the [[\\Yiisoft\\Log\\Logger::setTraceLevel()|setTraceLevel()]] method like the following:" -msgstr "" +msgstr "Durante o desenvolvimento, muitas vezes é útil ver de onde vem cada mensagem de log. Você pode fazer isso chamando o método [[\\Yiisoft\\Log\\Logger::setTraceLevel()|setTraceLevel()]] assim:" #. type: Fenced code block (php) #: ../src/guide/runtime/logging.md @@ -554,11 +676,13 @@ msgid "" "$logger = new \\Yiisoft\\Log\\Logger($targets);\n" "$logger->setTraceLevel(3);\n" msgstr "" +"$logger = new \\Yiisoft\\Log\\Logger($targets);\n" +"$logger->setTraceLevel(3);\n" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "This application configuration sets the trace level to be 3, so each log message will be appended with at most three levels of the call stack at which the log message is recorded. You can also set a list of paths to exclude from the trace by calling the [[\\Yiisoft\\Log\\Logger::setExcludedTracePaths()|setExcludedTracePaths()]] method." -msgstr "" +msgstr "Essa configuração define o nível de trace como 3, então cada mensagem de log recebe no máximo três níveis da pilha de chamadas do ponto em que a mensagem foi registrada. Você também pode definir uma lista de caminhos a excluir do trace chamando o método [[\\Yiisoft\\Log\\Logger::setExcludedTracePaths()|setExcludedTracePaths()]]." #. type: Fenced code block (php) #: ../src/guide/runtime/logging.md @@ -567,6 +691,8 @@ msgid "" "$logger = new \\Yiisoft\\Log\\Logger($targets);\n" "$logger->setExcludedTracePaths(['/path/to/file', '/path/to/folder']);\n" msgstr "" +"$logger = new \\Yiisoft\\Log\\Logger($targets);\n" +"$logger->setExcludedTracePaths(['/path/to/file', '/path/to/folder']);\n" #. type: Plain text #: ../src/guide/runtime/logging.md @@ -576,17 +702,20 @@ msgid "" "> Getting call stack information isn't trivial. Therefore, you should only use this feature during development\n" "or when debugging an application.\n" msgstr "" +"> [!IMPORTANT]\n" +"> Obter informações da pilha de chamadas não é trivial. Por isso, use esse recurso apenas durante o desenvolvimento\n" +"ou ao depurar uma aplicação.\n" #. type: Title ### #: ../src/guide/runtime/logging.md #, no-wrap msgid "Message flushing and exporting" -msgstr "" +msgstr "Envio (flush) e exportação de mensagens" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "As aforementioned, log messages are maintained in an array by [[\\Yiisoft\\Log\\Logger|logger object]]. To limit the memory consumption by this array, the logger will flush the recorded messages to the [log targets](#log-targets) each time the array accumulates a certain number of log messages. You can customize this number by calling the [[\\Yiisoft\\Log\\Logger::setFlushInterval()]] method:" -msgstr "" +msgstr "Como dito acima, as mensagens de log ficam em um array no [[\\Yiisoft\\Log\\Logger|objeto logger]]. Para limitar o consumo de memória desse array, o logger envia as mensagens registradas para os [destinos de log](#destinos-de-log) sempre que o array acumula um certo número de mensagens. Você pode personalizar esse número chamando o método [[\\Yiisoft\\Log\\Logger::setFlushInterval()]]:" #. type: Fenced code block (php) #: ../src/guide/runtime/logging.md @@ -595,6 +724,8 @@ msgid "" "$logger = new \\Yiisoft\\Log\\Logger($targets);\n" "$logger->setFlushInterval(100); // default is 1000\n" msgstr "" +"$logger = new \\Yiisoft\\Log\\Logger($targets);\n" +"$logger->setFlushInterval(100); // default is 1000\n" #. type: Plain text #: ../src/guide/runtime/logging.md @@ -604,6 +735,9 @@ msgid "" "> Message flushing also occurs when the application ends,\n" "which ensures log targets can receive complete log messages.\n" msgstr "" +"> [!IMPORTANT]\n" +"> O envio das mensagens também acontece quando a aplicação termina,\n" +"o que garante que os destinos de log recebam as mensagens completas.\n" #. type: Plain text #: ../src/guide/runtime/logging.md @@ -615,6 +749,11 @@ msgid "" "[[\\Yiisoft\\Log\\Target::setExportInterval()|setExportInterval()]] method of individual\n" "[log targets](#log-targets), like the following:\n" msgstr "" +"Quando o [[\\Yiisoft\\Log\\Logger|objeto logger]] envia as mensagens para os [destinos de log](#destinos-de-log),\n" +"elas não são exportadas imediatamente. A exportação só acontece quando um destino de log\n" +" acumula um certo número de mensagens filtradas. Você pode personalizar esse número chamando o método\n" +"[[\\Yiisoft\\Log\\Target::setExportInterval()|setExportInterval()]] de cada\n" +"[destino de log](#destinos-de-log), assim:\n" #. type: Fenced code block (php) #: ../src/guide/runtime/logging.md @@ -623,11 +762,13 @@ msgid "" "$fileTarget = new \\Yiisoft\\Log\\Target\\File\\FileTarget('/path/to/app.log');\n" "$fileTarget->setExportInterval(100); // default is 1000\n" msgstr "" +"$fileTarget = new \\Yiisoft\\Log\\Target\\File\\FileTarget('/path/to/app.log');\n" +"$fileTarget->setExportInterval(100); // default is 1000\n" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "Because of the flushing and exporting level setting, by default when you call any logging method, you will NOT see the log message immediately in the log targets. This could be a problem for some long-running console applications. To make each log message appear immediately in the log targets, you should set both flush interval and export interval to be 1, as shown below:" -msgstr "" +msgstr "Por causa dessas configurações de envio e exportação, por padrão, quando você chama qualquer método de log, NÃO vai ver a mensagem imediatamente nos destinos de log. Isso pode ser um problema em aplicações de console de longa duração. Para que cada mensagem apareça imediatamente nos destinos de log, defina tanto o intervalo de envio quanto o de exportação como 1, como mostrado abaixo:" #. type: Fenced code block (php) #: ../src/guide/runtime/logging.md @@ -639,6 +780,11 @@ msgid "" "$logger = new \\Yiisoft\\Log\\Logger([$fileTarget]);\n" "$logger->setFlushInterval(1);\n" msgstr "" +"$fileTarget = new \\Yiisoft\\Log\\Target\\File\\FileTarget('/path/to/app.log');\n" +"$fileTarget->setExportInterval(1);\n" +"\n" +"$logger = new \\Yiisoft\\Log\\Logger([$fileTarget]);\n" +"$logger->setFlushInterval(1);\n" #. type: Plain text #: ../src/guide/runtime/logging.md @@ -647,17 +793,19 @@ msgid "" "> [!NOTE]\n" "> Frequent message flushing and exporting will degrade the performance of your application.\n" msgstr "" +"> [!NOTE]\n" +"> Enviar e exportar mensagens com frequência piora o desempenho da sua aplicação.\n" #. type: Title ### #: ../src/guide/runtime/logging.md #, no-wrap msgid "Toggling log targets" -msgstr "" +msgstr "Ativando e desativando destinos de log" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "You can enable or disable a log target by calling its [[\\Yiisoft\\Log\\Target::enable()|enable()] ] and [[\\Yiisoft\\Log\\Target::disable()|disable()]] methods. You may do so via the log target configuration or by the following PHP statement in your code:" -msgstr "" +msgstr "Você pode ativar ou desativar um destino de log chamando os métodos [[\\Yiisoft\\Log\\Target::enable()|enable()] ] e [[\\Yiisoft\\Log\\Target::disable()|disable()]]. Você pode fazer isso na configuração do destino de log ou com a seguinte instrução PHP no seu código:" #. type: Fenced code block (php) #: ../src/guide/runtime/logging.md @@ -672,52 +820,60 @@ msgid "" " }\n" "}\n" msgstr "" +"$fileTarget = new \\Yiisoft\\Log\\Target\\File\\FileTarget('/path/to/app.log');\n" +"$logger = new \\Yiisoft\\Log\\Logger([$fileTarget, /*Other targets*/]);\n" +"\n" +"foreach ($logger->getTargets() as $target) {\n" +" if ($target instanceof \\Yiisoft\\Log\\Target\\File\\FileTarget) {\n" +" $target->disable();\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "To check whether the log target is enabled, call the `isEnabled()` method. You also may pass callable to [[\\Yiisoft\\Log\\Target::setEnabled()|setEnabled()]] to define a dynamic condition for whether the log target should be enabled or not." -msgstr "" +msgstr "Para verificar se o destino de log está ativado, chame o método `isEnabled()`. Você também pode passar um callable para [[\\Yiisoft\\Log\\Target::setEnabled()|setEnabled()]] para definir uma condição dinâmica que diz se o destino de log deve estar ativado ou não." #. type: Title ### #: ../src/guide/runtime/logging.md #, no-wrap msgid "Creating new targets" -msgstr "" +msgstr "Criando novos destinos" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "Creating a new log target class is straightforward. You mainly need to implement the [[\\Yii\\Log\\Target::export()]] abstract method that sends all accumulated log messages to a designated medium." -msgstr "" +msgstr "Criar uma nova classe de destino de log é simples. Basicamente, você precisa implementar o método abstrato [[\\Yii\\Log\\Target::export()]], que envia todas as mensagens de log acumuladas para um meio definido." #. type: Plain text #: ../src/guide/runtime/logging.md msgid "The following protected methods will also be available for child targets:" -msgstr "" +msgstr "Os seguintes métodos protegidos também ficam disponíveis para os destinos filhos:" #. type: Bullet: '- ' #: ../src/guide/runtime/logging.md msgid "`getMessages` - Get a list of log messages ([[\\Yii\\Log\\Message]] instances)." -msgstr "" +msgstr "`getMessages` - Retorna uma lista de mensagens de log (instâncias de [[\\Yii\\Log\\Message]])." #. type: Bullet: '- ' #: ../src/guide/runtime/logging.md msgid "`getFormattedMessages` - Get a list of log messages formatted as strings." -msgstr "" +msgstr "`getFormattedMessages` - Retorna uma lista de mensagens de log formatadas como strings." #. type: Bullet: '- ' #: ../src/guide/runtime/logging.md msgid "`formatMessages` - Get all log messages formatted as a string." -msgstr "" +msgstr "`formatMessages` - Retorna todas as mensagens de log formatadas como uma string." #. type: Bullet: '- ' #: ../src/guide/runtime/logging.md msgid "`getCommonContext` - Get an array with common context data in the `key => value` format." -msgstr "" +msgstr "`getCommonContext` - Retorna um array com os dados de contexto comuns no formato `key => value`." #. type: Plain text #: ../src/guide/runtime/logging.md msgid "For more details, you may refer to any of the log target classes included in the package." -msgstr "" +msgstr "Para mais detalhes, consulte qualquer uma das classes de destino de log incluídas no pacote." #. type: Plain text #: ../src/guide/runtime/logging.md @@ -727,6 +883,9 @@ msgid "" "> Instead of creating your own loggers, you may try any PSR-3 compatible logger such\n" "as [Monolog](https://github.com/Seldaek/monolog) by using [[\\Yii\\Log\\PsrTarget]].\n" msgstr "" +"> [!TIP]\n" +"> Em vez de criar os seus próprios loggers, você pode experimentar qualquer logger compatível com a PSR-3, como\n" +"o [Monolog](https://github.com/Seldaek/monolog), usando [[\\Yii\\Log\\PsrTarget]].\n" #. type: Fenced code block (php) #: ../src/guide/runtime/logging.md @@ -741,3 +900,11 @@ msgid "" "\n" "$logger->info('Text message');\n" msgstr "" +"/**\n" +" * @var \\Psr\\Log\\LoggerInterface $psrLogger\n" +" */\n" +"\n" +"$psrTarget = new \\Yiisoft\\Log\\PsrTarget($psrLogger);\n" +"$logger = new \\Yiisoft\\Log\\Logger([$psrTarget]);\n" +"\n" +"$logger->info('Text message');\n" diff --git a/_translations/po/pt-BR/guide_runtime_request.md.po b/_translations/po/pt-BR/guide_runtime_request.md.po index fbbc4714..a11198c2 100644 --- a/_translations/po/pt-BR/guide_runtime_request.md.po +++ b/_translations/po/pt-BR/guide_runtime_request.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-06-02 21:36+0000\n" "PO-Revision-Date: 2026-06-02 21:36+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,12 +19,12 @@ msgstr "" #: ../src/guide/runtime/request.md #, no-wrap msgid "Request" -msgstr "" +msgstr "Requisição" #. type: Plain text #: ../src/guide/runtime/request.md msgid "HTTP request has a method, URI, a set of headers and a body:" -msgstr "" +msgstr "Uma requisição HTTP tem um método, uma URI, um conjunto de headers e um corpo:" #. type: Fenced code block #: ../src/guide/runtime/request.md @@ -40,16 +40,25 @@ msgid "" " \"body\": \"Hello there, we need to build Yii application together!\"\n" "}\n" msgstr "" +"POST /contact HTTP/1.1\n" +"Host: example.org\n" +"Accept-Language: en-us\n" +"Accept-Encoding: gzip, deflate\n" +"\n" +"{\n" +" \"subject\": \"Hello\",\n" +" \"body\": \"Hello there, we need to build Yii application together!\"\n" +"}\n" #. type: Plain text #: ../src/guide/runtime/request.md msgid "The method is `POST`, URI is `/contact`. Extra headers are specifying host, preferred language and encoding. The body could be anything. In this case, it's a JSON payload." -msgstr "" +msgstr "O método é `POST` e a URI é `/contact`. Os headers extras informam o host, o idioma preferido e a codificação. O corpo pode ser qualquer coisa. Neste caso, é um payload JSON." #. type: Plain text #: ../src/guide/runtime/request.md msgid "Yii uses [PSR-7 `ServerRequest`](https://www.php-fig.org/psr/psr-7/) as request representation. The object is available in controller actions and other types of middleware:" -msgstr "" +msgstr "O Yii usa o [`ServerRequest` da PSR-7](https://www.php-fig.org/psr/psr-7/) para representar a requisição. O objeto está disponível nas actions de controllers e em outros tipos de middleware:" #. type: Fenced code block (php) #: ../src/guide/runtime/request.md @@ -60,68 +69,72 @@ msgid "" " // ...\n" "}\n" msgstr "" +"public function view(ServerRequestInterface $request): ResponseInterface\n" +"{\n" +" // ...\n" +"}\n" #. type: Title ## #: ../src/guide/runtime/request.md #, no-wrap msgid "Method" -msgstr "" +msgstr "Método" #. type: Plain text #: ../src/guide/runtime/request.md msgid "The method could be obtained from a request object:" -msgstr "" +msgstr "O método pode ser obtido do objeto de requisição:" #. type: Fenced code block (php) #: ../src/guide/runtime/request.md #, no-wrap msgid "$method = $request->getMethod();\n" -msgstr "" +msgstr "$method = $request->getMethod();\n" #. type: Plain text #: ../src/guide/runtime/request.md msgid "Usually it's one of the:" -msgstr "" +msgstr "Normalmente ele é um destes:" #. type: Bullet: '- ' #: ../src/guide/runtime/request.md msgid "GET" -msgstr "" +msgstr "GET" #. type: Bullet: '- ' #: ../src/guide/runtime/request.md msgid "POST" -msgstr "" +msgstr "POST" #. type: Bullet: '- ' #: ../src/guide/runtime/request.md msgid "PUT" -msgstr "" +msgstr "PUT" #. type: Bullet: '- ' #: ../src/guide/runtime/request.md msgid "DELETE" -msgstr "" +msgstr "DELETE" #. type: Bullet: '- ' #: ../src/guide/runtime/request.md msgid "HEAD" -msgstr "" +msgstr "HEAD" #. type: Bullet: '- ' #: ../src/guide/runtime/request.md msgid "PATCH" -msgstr "" +msgstr "PATCH" #. type: Bullet: '- ' #: ../src/guide/runtime/request.md msgid "OPTIONS" -msgstr "" +msgstr "OPTIONS" #. type: Plain text #: ../src/guide/runtime/request.md msgid "In case you want to make sure the request method is of a certain type, there is a special class with method names:" -msgstr "" +msgstr "Se você quiser garantir que o método da requisição é de um tipo específico, existe uma classe especial com os nomes dos métodos:" #. type: Fenced code block (php) #: ../src/guide/runtime/request.md @@ -133,114 +146,119 @@ msgid "" " // method is POST\n" "}\n" msgstr "" +"use Yiisoft\\Http\\Method;\n" +"\n" +"if ($request->getMethod() === Method::POST) {\n" +" // method is POST\n" +"}\n" #. type: Title ## #: ../src/guide/runtime/request.md #, no-wrap msgid "URI" -msgstr "" +msgstr "URI" #. type: Plain text #: ../src/guide/runtime/request.md msgid "A URI has:" -msgstr "" +msgstr "Uma URI tem:" #. type: Bullet: '- ' #: ../src/guide/runtime/request.md msgid "Scheme (`http`, `https`)" -msgstr "" +msgstr "Esquema (`http`, `https`)" #. type: Bullet: '- ' #: ../src/guide/runtime/request.md msgid "Host (`yiiframework.com`)" -msgstr "" +msgstr "Host (`yiiframework.com`)" #. type: Bullet: '- ' #: ../src/guide/runtime/request.md msgid "Port (`80`, `443`)" -msgstr "" +msgstr "Porta (`80`, `443`)" #. type: Bullet: '- ' #: ../src/guide/runtime/request.md msgid "Path (`/posts/1`)" -msgstr "" +msgstr "Caminho (`/posts/1`)" #. type: Bullet: '- ' #: ../src/guide/runtime/request.md msgid "Query string (`page=1&sort=+id`)" -msgstr "" +msgstr "Query string (`page=1&sort=+id`)" #. type: Bullet: '- ' #: ../src/guide/runtime/request.md msgid "Fragment (`#anchor`)" -msgstr "" +msgstr "Fragmento (`#anchor`)" #. type: Plain text #: ../src/guide/runtime/request.md msgid "You can obtain `UriInterface` from request like the following:" -msgstr "" +msgstr "Você pode obter a `UriInterface` da requisição assim:" #. type: Fenced code block (php) #: ../src/guide/runtime/request.md #, no-wrap msgid "$uri = $request->getUri();\n" -msgstr "" +msgstr "$uri = $request->getUri();\n" #. type: Plain text #: ../src/guide/runtime/request.md msgid "Then you can get various details from its methods:" -msgstr "" +msgstr "Depois, pode obter vários detalhes pelos métodos dela:" #. type: Bullet: '- ' #: ../src/guide/runtime/request.md msgid "`getScheme()`" -msgstr "" +msgstr "`getScheme()`" #. type: Bullet: '- ' #: ../src/guide/runtime/request.md msgid "`getAuthority()`" -msgstr "" +msgstr "`getAuthority()`" #. type: Bullet: '- ' #: ../src/guide/runtime/request.md msgid "`getUserInfo()`" -msgstr "" +msgstr "`getUserInfo()`" #. type: Bullet: '- ' #: ../src/guide/runtime/request.md msgid "`getHost()`" -msgstr "" +msgstr "`getHost()`" #. type: Bullet: '- ' #: ../src/guide/runtime/request.md msgid "`getPort()`" -msgstr "" +msgstr "`getPort()`" #. type: Bullet: '- ' #: ../src/guide/runtime/request.md msgid "`getPath()`" -msgstr "" +msgstr "`getPath()`" #. type: Bullet: '- ' #: ../src/guide/runtime/request.md msgid "`getQuery()`" -msgstr "" +msgstr "`getQuery()`" #. type: Bullet: '- ' #: ../src/guide/runtime/request.md msgid "`getFragment()`" -msgstr "" +msgstr "`getFragment()`" #. type: Title ## #: ../src/guide/runtime/request.md ../src/guide/runtime/response.md #, no-wrap msgid "Headers" -msgstr "" +msgstr "Headers" #. type: Plain text #: ../src/guide/runtime/request.md msgid "There are various methods to inspect request headers. To get all headers as an array:" -msgstr "" +msgstr "Há vários métodos para inspecionar os headers da requisição. Para obter todos os headers como array:" #. type: Fenced code block (php) #: ../src/guide/runtime/request.md @@ -251,22 +269,26 @@ msgid "" " // ...\n" "}\n" msgstr "" +"$headers = $request->getHeaders();\n" +"foreach ($headers as $name => $values) {\n" +" // ...\n" +"}\n" #. type: Plain text #: ../src/guide/runtime/request.md msgid "To get a single header:" -msgstr "" +msgstr "Para obter um único header:" #. type: Fenced code block (php) #: ../src/guide/runtime/request.md #, no-wrap msgid "$values = $request->getHeader('Accept-Encoding');\n" -msgstr "" +msgstr "$values = $request->getHeader('Accept-Encoding');\n" #. type: Plain text #: ../src/guide/runtime/request.md msgid "Also, you could get value as a comma-separated string instead of an array. That's especially handy if a header has a single value:" -msgstr "" +msgstr "Você também pode obter o valor como uma string separada por vírgulas em vez de um array. Isso é bem prático quando o header tem um único valor:" #. type: Fenced code block (php) #: ../src/guide/runtime/request.md @@ -277,11 +299,15 @@ msgid "" " // Note that header presence and name may vary depending on the library used. \n" "}\n" msgstr "" +"if ($request->getHeaderLine('X-Requested-With') === 'XMLHttpRequest') {\n" +" // This is an AJAX request made with jQuery.\n" +" // Note that header presence and name may vary depending on the library used. \n" +"}\n" #. type: Plain text #: ../src/guide/runtime/request.md msgid "To check if a header is present in the request:" -msgstr "" +msgstr "Para verificar se um header está presente na requisição:" #. type: Fenced code block (php) #: ../src/guide/runtime/request.md @@ -291,45 +317,47 @@ msgid "" " // ...\n" "}\n" msgstr "" +"if ($request->hasHeader('Accept-Encoding')) {\n" +" // ...\n" +"}\n" #. type: Title ## -#: ../src/guide/runtime/request.md ../src/guide/runtime/response.md -#: ../src/internals/006-git-commit-messages.md +#: ../src/guide/runtime/request.md ../src/guide/runtime/response.md ../src/internals/006-git-commit-messages.md #, no-wrap msgid "Body" -msgstr "" +msgstr "Corpo" #. type: Plain text #: ../src/guide/runtime/request.md msgid "There are two methods to get body contents. The first is getting the body as it is without parsing:" -msgstr "" +msgstr "Há dois métodos para obter o conteúdo do corpo. O primeiro retorna o corpo como está, sem parsing:" #. type: Fenced code block (php) #: ../src/guide/runtime/request.md #, no-wrap msgid "$body = $request->getBody();\n" -msgstr "" +msgstr "$body = $request->getBody();\n" #. type: Plain text #: ../src/guide/runtime/request.md msgid "The `$body` would be an instance of `Psr\\Http\\Message\\StreamInterface`." -msgstr "" +msgstr "`$body` será uma instância de `Psr\\Http\\Message\\StreamInterface`." #. type: Plain text #: ../src/guide/runtime/request.md msgid "Also, you could get a parsed body:" -msgstr "" +msgstr "Você também pode obter o corpo já interpretado:" #. type: Fenced code block (php) #: ../src/guide/runtime/request.md #, no-wrap msgid "$bodyParameters = $request->getParsedBody();\n" -msgstr "" +msgstr "$bodyParameters = $request->getParsedBody();\n" #. type: Plain text #: ../src/guide/runtime/request.md msgid "Parsing depends on PSR-7 implementation and may require middleware for custom body formats." -msgstr "" +msgstr "O parsing depende da implementação da PSR-7 e pode exigir um middleware para formatos de corpo personalizados." #. type: Fenced code block (php) #: ../src/guide/runtime/request.md @@ -358,17 +386,39 @@ msgid "" " }\n" "}\n" msgstr "" +"getHeaderLine('Content-Type');\n" +"\n" +" if (strpos($contentType, 'application/json') !== false) {\n" +" $body = $request->getBody();\n" +" $parsedBody = $this->parse($body);\n" +" $request = $request->withParsedBody($parsedBody);\n" +" \n" +" }\n" +"\n" +" return $next->handle($request);\n" +" }\n" +"}\n" #. type: Title ## #: ../src/guide/runtime/request.md #, no-wrap msgid "File uploads" -msgstr "" +msgstr "Upload de arquivos" #. type: Plain text #: ../src/guide/runtime/request.md msgid "Uploaded files that user submitted from a form with `enctype` attribute equals to `multipart/form-data` are handled via special request method:" -msgstr "" +msgstr "Os arquivos enviados pelo usuário em um formulário com o atributo `enctype` igual a `multipart/form-data` são tratados por um método especial da requisição:" #. type: Fenced code block (php) #: ../src/guide/runtime/request.md @@ -381,16 +431,22 @@ msgid "" " }\n" "}\n" msgstr "" +"$files = $request->getUploadedFiles();\n" +"foreach ($files as $file) {\n" +" if ($file->getError() === UPLOAD_ERR_OK) {\n" +" $file->moveTo('path/to/uploads/new_filename.ext');\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/runtime/request.md msgid "Always validate the upload before reading the stream or moving the file. The file may be missing, too large for PHP configuration, only partially uploaded, rejected by a PHP extension, or not match the file type and size your application expects. Yii Validator provides the `Yiisoft\\Validator\\Rule\\File` rule for this. It accepts PSR-7 `UploadedFileInterface` values and validates upload error codes, extension, MIME type, and size. Use `Yiisoft\\Validator\\Rule\\Each` when a field contains several files." -msgstr "" +msgstr "Sempre valide o upload antes de ler o stream ou mover o arquivo. O arquivo pode estar ausente, ser grande demais para a configuração do PHP, ter sido enviado só em parte, ter sido rejeitado por uma extensão do PHP ou não corresponder ao tipo e ao tamanho que a sua aplicação espera. O Yii Validator oferece a regra `Yiisoft\\Validator\\Rule\\File` para isso. Ela aceita valores `UploadedFileInterface` da PSR-7 e valida os códigos de erro do upload, a extensão, o tipo MIME e o tamanho. Use `Yiisoft\\Validator\\Rule\\Each` quando um campo tiver vários arquivos." #. type: Plain text #: ../src/guide/runtime/request.md msgid "The following example handles a single `avatar` upload. It validates the uploaded file with Yii Validator, stores the file outside the public directory, and generates its own file name instead of trusting the client-provided name." -msgstr "" +msgstr "O exemplo a seguir trata o upload de um único `avatar`. Ele valida o arquivo enviado com o Yii Validator, guarda o arquivo fora do diretório público e gera o próprio nome do arquivo em vez de confiar no nome informado pelo cliente." #. type: Fenced code block (php) #: ../src/guide/runtime/request.md @@ -501,54 +557,158 @@ msgid "" " }\n" "}\n" msgstr "" +"\n" +" */\n" +" private const EXTENSIONS = [\n" +" 'image/jpeg' => 'jpg',\n" +" 'image/png' => 'png',\n" +" 'image/webp' => 'webp',\n" +" ];\n" +"\n" +" public function __construct(\n" +" private Aliases $aliases,\n" +" private ResponseFactoryInterface $responseFactory,\n" +" ) {\n" +" }\n" +"\n" +" public function __invoke(ServerRequestInterface $request): ResponseInterface\n" +" {\n" +" $file = $request->getUploadedFiles()['avatar'] ?? null;\n" +"\n" +" $result = (new Validator())->validate(\n" +" ['avatar' => $file],\n" +" [\n" +" 'avatar' => [\n" +" new File(\n" +" extensions: ['jpg', 'jpeg', 'png', 'webp'],\n" +" mimeTypes: array_keys(self::EXTENSIONS),\n" +" maxSize: self::MAX_SIZE,\n" +" ),\n" +" new Image(skipOnError: true),\n" +" ],\n" +" ],\n" +" );\n" +"\n" +" if (!$result->isValid() || !$file instanceof UploadedFileInterface) {\n" +" $messages = $result->getPropertyErrorMessages('avatar');\n" +" return $this->badRequest(\n" +" $messages === [] ? 'Upload a file in the \"avatar\" field.' : implode(' ', $messages),\n" +" );\n" +" }\n" +"\n" +" $uploadDirectory = $this->aliases->get('@runtime/uploads/avatars');\n" +" $this->ensureDirectory($uploadDirectory);\n" +"\n" +" $temporaryPath = $uploadDirectory . DIRECTORY_SEPARATOR . bin2hex(random_bytes(16)) . '.upload';\n" +" $file->moveTo($temporaryPath);\n" +"\n" +" $mediaType = (new finfo(FILEINFO_MIME_TYPE))->file($temporaryPath);\n" +"\n" +" if (!is_string($mediaType) || !isset(self::EXTENSIONS[$mediaType])) {\n" +" unlink($temporaryPath);\n" +" return $this->badRequest('Only JPEG, PNG, and WebP images are allowed.');\n" +" }\n" +"\n" +" $fileName = bin2hex(random_bytes(16)) . '.' . self::EXTENSIONS[$mediaType];\n" +" $targetPath = $uploadDirectory . DIRECTORY_SEPARATOR . $fileName;\n" +"\n" +" if (!rename($temporaryPath, $targetPath)) {\n" +" unlink($temporaryPath);\n" +" throw new RuntimeException('Unable to store uploaded file.');\n" +" }\n" +"\n" +" $response = $this->responseFactory->createResponse(Status::CREATED);\n" +" $response->getBody()->write('Stored as ' . $fileName);\n" +"\n" +" return $response;\n" +" }\n" +"\n" +" private function badRequest(string $message): ResponseInterface\n" +" {\n" +" $response = $this->responseFactory->createResponse(Status::BAD_REQUEST);\n" +" $response->getBody()->write($message);\n" +"\n" +" return $response;\n" +" }\n" +"\n" +" private function ensureDirectory(string $directory): void\n" +" {\n" +" if (!is_dir($directory) && !mkdir($directory, 0775, true) && !is_dir($directory)) {\n" +" throw new RuntimeException(sprintf('Directory \"%s\" was not created.', $directory));\n" +" }\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/runtime/request.md msgid "Notes:" -msgstr "" +msgstr "Observações:" #. type: Bullet: '- ' #: ../src/guide/runtime/request.md msgid "Store uploads under `@runtime` or another non-public directory unless the files are intentionally public." -msgstr "" +msgstr "Guarde os uploads em `@runtime` ou em outro diretório não público, a menos que os arquivos sejam públicos de propósito." #. type: Bullet: '- ' #: ../src/guide/runtime/request.md msgid "Do not use `getClientFilename()` as a storage path. A browser controls it, so it may contain unsafe characters, path-like values, or duplicate names." -msgstr "" +msgstr "Não use `getClientFilename()` como caminho de armazenamento. Quem controla esse valor é o navegador, então ele pode ter caracteres inseguros, valores que parecem caminhos ou nomes duplicados." #. type: Bullet: '- ' #: ../src/guide/runtime/request.md msgid "Do not rely on `getClientMediaType()` alone. It comes from the client. Use `File` MIME type validation, `Image` for image validation and dimension checks, or another server-side parser appropriate for the file format." -msgstr "" +msgstr "Não confie apenas em `getClientMediaType()`. Esse valor vem do cliente. Use a validação de tipo MIME da regra `File`, a regra `Image` para validar imagens e dimensões, ou outro parser no servidor adequado ao formato do arquivo." #. type: Bullet: '- ' #: ../src/guide/runtime/request.md msgid "Check PHP limits such as `upload_max_filesize`, `post_max_size`, and `max_file_uploads` when expected files are rejected before the action runs." -msgstr "" +msgstr "Verifique limites do PHP como `upload_max_filesize`, `post_max_size` e `max_file_uploads` quando arquivos esperados forem rejeitados antes de a action rodar." #. type: Bullet: '- ' #: ../src/guide/runtime/request.md msgid "When a form uploads several files, the array returned by `getUploadedFiles()` has the same shape as the file input names. Validate them with `Each(new File(...))` and move each `UploadedFileInterface` separately." -msgstr "" +msgstr "Quando um formulário envia vários arquivos, o array retornado por `getUploadedFiles()` tem o mesmo formato dos nomes dos inputs de arquivo. Valide-os com `Each(new File(...))` e mova cada `UploadedFileInterface` separadamente." #. type: Bullet: '- ' #: ../src/guide/runtime/request.md msgid "`File` can also validate string file paths and `SplFileInfo` instances. Do not pass user-submitted paths directly: use PSR-7 uploaded file objects from the request, or perform upload provenance checks before validating filesystem paths." -msgstr "" +msgstr "A regra `File` também valida caminhos de arquivo em string e instâncias de `SplFileInfo`. Não passe caminhos enviados pelo usuário diretamente: use os objetos de arquivo enviado da PSR-7 vindos da requisição, ou verifique a origem do upload antes de validar caminhos do sistema de arquivos." #. type: Title ## #: ../src/guide/runtime/request.md #, no-wrap msgid "Attributes" -msgstr "" +msgstr "Atributos" #. type: Plain text #: ../src/guide/runtime/request.md msgid "Application middleware may set custom request attributes using `withAttribute()` method. You can get these attributes with `getAttribute()`." -msgstr "" +msgstr "Os middlewares da aplicação podem definir atributos personalizados na requisição com o método `withAttribute()`. Você pode ler esses atributos com `getAttribute()`." #. type: Plain text #: ../src/guide/runtime/request.md msgid "Route arguments, such as `id` from a `/posts/{id}` route pattern, aren't request attributes. Use `#[RouteArgument]` in an action parameter or inject `Yiisoft\\Router\\CurrentRoute` when you need route arguments or route metadata." -msgstr "" +msgstr "Argumentos de rota, como o `id` de um padrão de rota `/posts/{id}`, não são atributos da requisição. Use `#[RouteArgument]` em um parâmetro da action ou injete `Yiisoft\\Router\\CurrentRoute` quando precisar de argumentos ou metadados da rota." diff --git a/_translations/po/pt-BR/guide_runtime_response.md.po b/_translations/po/pt-BR/guide_runtime_response.md.po index e73575db..1adbd321 100644 --- a/_translations/po/pt-BR/guide_runtime_response.md.po +++ b/_translations/po/pt-BR/guide_runtime_response.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-05-09 20:32+0000\n" "PO-Revision-Date: 2026-05-09 20:32+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,25 +19,24 @@ msgstr "" #: ../src/guide/runtime/request.md ../src/guide/runtime/response.md #, no-wrap msgid "Headers" -msgstr "" +msgstr "Headers" #. type: Title ## -#: ../src/guide/runtime/request.md ../src/guide/runtime/response.md -#: ../src/internals/006-git-commit-messages.md +#: ../src/guide/runtime/request.md ../src/guide/runtime/response.md ../src/internals/006-git-commit-messages.md #, no-wrap msgid "Body" -msgstr "" +msgstr "Corpo" #. type: Title # #: ../src/guide/runtime/response.md #, no-wrap msgid "Response" -msgstr "" +msgstr "Resposta" #. type: Plain text #: ../src/guide/runtime/response.md msgid "HTTP response has status code and message, a set of headers and a body:" -msgstr "" +msgstr "Uma resposta HTTP tem um código e uma mensagem de status, um conjunto de headers e um corpo:" #. type: Fenced code block #: ../src/guide/runtime/response.md @@ -53,16 +52,25 @@ msgid "" "\n" "Hello!\n" msgstr "" +"HTTP/1.1 200 OK\n" +"Date: Mon, 27 Jul 2009 12:28:53 GMT\n" +"Server: Apache/2.2.14 (Win32)\n" +"Last-Modified: Wed, 22 Jul 2009 19:15:56 GMT\n" +"Content-Length: 6 \n" +"Content-Type: text/html\n" +"Connection: Closed\n" +"\n" +"Hello!\n" #. type: Plain text #: ../src/guide/runtime/response.md msgid "Yii uses [PSR-7 `Response`](https://www.php-fig.org/psr/psr-7/) in the web application to represent response." -msgstr "" +msgstr "O Yii usa o [`Response` da PSR-7](https://www.php-fig.org/psr/psr-7/) na aplicação web para representar a resposta." #. type: Plain text #: ../src/guide/runtime/response.md msgid "The object should be constructed and returned as a result of the execution of controller actions or other middleware. Usually, the middleware has a response factory injected into its constructor." -msgstr "" +msgstr "O objeto deve ser criado e retornado como resultado da execução das actions de controllers ou de outros middlewares. Normalmente, o middleware recebe uma response factory injetada no construtor." #. type: Fenced code block (php) #: ../src/guide/runtime/response.md @@ -88,17 +96,36 @@ msgid "" " }\n" "}\n" msgstr "" +"use Psr\\Http\\Message\\ResponseFactoryInterface;\n" +"use Psr\\Http\\Message\\ResponseInterface;\n" +"use Psr\\Http\\Message\\ServerRequestInterface;\n" +"\n" +"final readonly class PostAction\n" +"{\n" +" public function __construct(\n" +" private ResponseFactoryInterface $responseFactory\n" +" )\n" +" {\n" +" }\n" +"\n" +" public function view(ServerRequestInterface $request): ResponseInterface\n" +" {\n" +" $response = $this->responseFactory->createResponse();\n" +" $response->getBody()->write('Hello!');\n" +" return $response;\n" +" }\n" +"}\n" #. type: Title ## #: ../src/guide/runtime/response.md #, no-wrap msgid "Status code" -msgstr "" +msgstr "Código de status" #. type: Plain text #: ../src/guide/runtime/response.md msgid "You can set a status code like the following:" -msgstr "" +msgstr "Você pode definir o código de status assim:" #. type: Fenced code block (php) #: ../src/guide/runtime/response.md @@ -108,59 +135,62 @@ msgid "" "\n" "$response = $response->withStatus(Status::NOT_FOUND);\n" msgstr "" +"use Yiisoft\\Http\\Status;\n" +"\n" +"$response = $response->withStatus(Status::NOT_FOUND);\n" #. type: Plain text #: ../src/guide/runtime/response.md msgid "Majority of status codes are available from `Status` class for convenience and readability." -msgstr "" +msgstr "A maioria dos códigos de status está disponível na classe `Status`, por conveniência e legibilidade." #. type: Plain text #: ../src/guide/runtime/response.md msgid "Router may return a response before an action runs. For example, an `OPTIONS` request to a known route path gets an automatic `204 No Content` response with an `Allow` header that lists supported methods. See [Automatic OPTIONS responses](routing.md#automatic-options-responses) for routing details." -msgstr "" +msgstr "O router pode retornar uma resposta antes de a action rodar. Por exemplo, uma requisição `OPTIONS` para o caminho de uma rota conhecida recebe automaticamente uma resposta `204 No Content` com um header `Allow` listando os métodos suportados. Veja [Respostas OPTIONS automáticas](routing.md#respostas-options-automaticas) para os detalhes de roteamento." #. type: Plain text #: ../src/guide/runtime/response.md msgid "You can set headers like this:" -msgstr "" +msgstr "Você pode definir headers assim:" #. type: Fenced code block (php) #: ../src/guide/runtime/response.md #, no-wrap msgid "$response = $response->withHeader('Content-type', 'application/json');\n" -msgstr "" +msgstr "$response = $response->withHeader('Content-type', 'application/json');\n" #. type: Plain text #: ../src/guide/runtime/response.md msgid "If there is a need to append a header value to the existing header:" -msgstr "" +msgstr "Se for preciso acrescentar um valor a um header existente:" #. type: Fenced code block (php) #: ../src/guide/runtime/response.md #, no-wrap msgid "$response = $response->withAddedHeader('Set-Cookie', 'qwerty=219ffwef9w0f; Domain=somecompany.co.uk; Path=/; Expires=Wed, 30 Aug 2019 00:00:00 GMT');\n" -msgstr "" +msgstr "$response = $response->withAddedHeader('Set-Cookie', 'qwerty=219ffwef9w0f; Domain=somecompany.co.uk; Path=/; Expires=Wed, 30 Aug 2019 00:00:00 GMT');\n" #. type: Plain text #: ../src/guide/runtime/response.md msgid "And, if needed, headers could be removed:" -msgstr "" +msgstr "E, se necessário, os headers podem ser removidos:" #. type: Fenced code block (php) #: ../src/guide/runtime/response.md #, no-wrap msgid "$response = $response->withoutHeader('Set-Cookie');\n" -msgstr "" +msgstr "$response = $response->withoutHeader('Set-Cookie');\n" #. type: Plain text #: ../src/guide/runtime/response.md msgid "Response body is an object implementing `Psr\\Http\\Message\\StreamInterface`." -msgstr "" +msgstr "O corpo da resposta é um objeto que implementa `Psr\\Http\\Message\\StreamInterface`." #. type: Plain text #: ../src/guide/runtime/response.md msgid "You can write to it via the interface itself:" -msgstr "" +msgstr "Você pode escrever nele pela própria interface:" #. type: Fenced code block (php) #: ../src/guide/runtime/response.md @@ -169,18 +199,20 @@ msgid "" "$body = $response->getBody();\n" "$body->write('Hello');\n" msgstr "" +"$body = $response->getBody();\n" +"$body->write('Hello');\n" #. type: Title ## #: ../src/guide/runtime/response.md #, no-wrap msgid "Examples" -msgstr "" +msgstr "Exemplos" #. type: Title ### #: ../src/guide/runtime/response.md #, no-wrap msgid "Redirecting" -msgstr "" +msgstr "Redirecionando" #. type: Fenced code block (php) #: ../src/guide/runtime/response.md @@ -192,11 +224,16 @@ msgid "" " ->withStatus(Status::PERMANENT_REDIRECT)\n" " ->withHeader('Location', 'https://www.example.com'); \n" msgstr "" +"use Yiisoft\\Http\\Status;\n" +"\n" +"return $response\n" +" ->withStatus(Status::PERMANENT_REDIRECT)\n" +" ->withHeader('Location', 'https://www.example.com'); \n" #. type: Plain text #: ../src/guide/runtime/response.md msgid "Note that there are different statuses used for redirection:" -msgstr "" +msgstr "Existem status diferentes usados para redirecionamento:" #. type: Plain text #: ../src/guide/runtime/response.md @@ -210,12 +247,19 @@ msgid "" "| 307 | `Status::TEMPORARY_REDIRECT` | Like 302, but guarantees the HTTP method won't change. |\n" "| 303 | `Status::SEE_OTHER` | After form submissions to prevent duplicate submissions if the user refreshes. Explicitly tells to use `GET` for the redirect, even if the original request was `POST`. |\n" msgstr "" +"| Código | Constante | Para que serve |\n" +"|--------|------------------------------|----------------|\n" +"| 301 | `Status::MOVED_PERMANENTLY` | Mudança permanente na estrutura de URLs. Os mecanismos de busca atualizam os índices e os navegadores guardam em cache. |\n" +"| 308 | `Status::PERMANENT_REDIRECT` | Como o 301, mas garante que o método HTTP não muda. |\n" +"| 302 | `Status::FOUND` | Mudanças temporárias, como páginas de manutenção. A URL original ainda deve ser usada nas próximas requisições. Os mecanismos de busca normalmente não atualizam os índices. |\n" +"| 307 | `Status::TEMPORARY_REDIRECT` | Como o 302, mas garante que o método HTTP não muda. |\n" +"| 303 | `Status::SEE_OTHER` | Depois do envio de formulários, para evitar envios duplicados se o usuário recarregar a página. Indica explicitamente que o redirecionamento deve usar `GET`, mesmo que a requisição original tenha sido `POST`. |\n" #. type: Title ### #: ../src/guide/runtime/response.md #, no-wrap msgid "Responding with JSON" -msgstr "" +msgstr "Respondendo com JSON" #. type: Fenced code block (php) #: ../src/guide/runtime/response.md @@ -234,3 +278,15 @@ msgid "" " ->withStatus(Status::OK)\n" " ->withHeader('Content-Type', 'application/json');\n" msgstr "" +"use Yiisoft\\Http\\Status;\n" +"use Yiisoft\\Json\\Json;\n" +"\n" +"$data = [\n" +" 'account' => 'samdark',\n" +" 'value' => 42\n" +"];\n" +"\n" +"$response->getBody()->write(Json::encode($data));\n" +"return $response\n" +" ->withStatus(Status::OK)\n" +" ->withHeader('Content-Type', 'application/json');\n" diff --git a/_translations/po/pt-BR/guide_runtime_routing.md.po b/_translations/po/pt-BR/guide_runtime_routing.md.po index 37ed53d5..a0bee429 100644 --- a/_translations/po/pt-BR/guide_runtime_routing.md.po +++ b/_translations/po/pt-BR/guide_runtime_routing.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-06-05 20:33+0000\n" "PO-Revision-Date: 2026-06-05 20:33+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,33 +19,33 @@ msgstr "" #: ../src/guide/runtime/routing.md #, no-wrap msgid "Routing and URL generation" -msgstr "" +msgstr "Roteamento e geração de URLs" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "Usually, a Yii application processes certain requests with certain handlers. It selects a handler based on the request URL. The part of the application that does the job is a router, and the process of selecting a handler, instantiating it and running a handler method is *routing*." -msgstr "" +msgstr "Normalmente, uma aplicação Yii processa certas requisições com certos handlers. Ela escolhe o handler com base na URL da requisição. A parte da aplicação que faz esse trabalho é o router, e o processo de escolher um handler, instanciá-lo e executar um método dele é o *roteamento*." #. type: Plain text #: ../src/guide/runtime/routing.md msgid "The reverse process of routing is *URL generation*, which creates a URL from a given named route, route arguments, and query parameters. When you later request the created URL, the routing process can resolve it back into the original route arguments and query parameters." -msgstr "" +msgstr "O processo inverso do roteamento é a *geração de URLs*, que cria uma URL a partir de uma rota nomeada, de argumentos de rota e de parâmetros de query. Quando você requisita depois a URL criada, o roteamento consegue convertê-la de volta nos argumentos de rota e parâmetros de query originais." #. type: Plain text #: ../src/guide/runtime/routing.md msgid "Routing and URL generation are separate services, but they use a common set of routes for both URL matching and URL generation." -msgstr "" +msgstr "Roteamento e geração de URLs são serviços separados, mas usam o mesmo conjunto de rotas tanto para casar URLs quanto para gerá-las." #. type: Title ## #: ../src/guide/runtime/routing.md #, no-wrap msgid "Configuring routes" -msgstr "" +msgstr "Configurando rotas" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "By configuring routes, you can let your application recognize arbitrary URL formats without modifying your existing application code. You can configure routes in `/config/routes.php`. The structure of the file is the following:" -msgstr "" +msgstr "Configurando rotas, você faz a aplicação reconhecer formatos arbitrários de URL sem modificar o código existente. Você pode configurar as rotas em `/config/routes.php`. A estrutura do arquivo é a seguinte:" #. type: Fenced code block (php) #: ../src/guide/runtime/routing.md @@ -64,51 +64,63 @@ msgid "" " ->name('site/index')\n" "];\n" msgstr "" +"action([SiteController::class, 'index'])\n" +" ->name('site/index')\n" +"];\n" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "The file returns an array of routes. When defining a route, you start with a method corresponding to a certain HTTP request type:" -msgstr "" +msgstr "O arquivo retorna um array de rotas. Ao definir uma rota, você começa com um método que corresponde a um tipo de requisição HTTP:" #. type: Bullet: '- ' #: ../src/guide/runtime/routing.md msgid "get" -msgstr "" +msgstr "get" #. type: Bullet: '- ' #: ../src/guide/runtime/routing.md msgid "post" -msgstr "" +msgstr "post" #. type: Bullet: '- ' #: ../src/guide/runtime/routing.md msgid "put" -msgstr "" +msgstr "put" #. type: Bullet: '- ' #: ../src/guide/runtime/routing.md msgid "delete" -msgstr "" +msgstr "delete" #. type: Bullet: '- ' #: ../src/guide/runtime/routing.md msgid "patch" -msgstr "" +msgstr "patch" #. type: Bullet: '- ' #: ../src/guide/runtime/routing.md msgid "head" -msgstr "" +msgstr "head" #. type: Bullet: '- ' #: ../src/guide/runtime/routing.md msgid "options" -msgstr "" +msgstr "options" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "If you need many methods, you can use `methods()`:" -msgstr "" +msgstr "Se você precisar de vários métodos, pode usar `methods()`:" #. type: Fenced code block (php) #: ../src/guide/runtime/routing.md @@ -128,31 +140,44 @@ msgid "" " ->name('site/user')\n" "];\n" msgstr "" +"action([SiteController::class, 'user'])\n" +" ->name('site/user')\n" +"];\n" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "All these methods accept a route pattern. The route pattern defines how the router matches the URL when routing and how it generates URL based on route name and parameters. You will learn about the actual syntax later in this guide. Specify a handler with `action()` as:" -msgstr "" +msgstr "Todos esses métodos aceitam um padrão de rota. O padrão de rota define como o router casa a URL durante o roteamento e como gera a URL a partir do nome da rota e dos parâmetros. Você vai conhecer a sintaxe mais adiante neste guia. Defina o handler com `action()` como:" #. type: Bullet: '- ' #: ../src/guide/runtime/routing.md msgid "[Middleware](../structure/middleware.md) class name." -msgstr "" +msgstr "Nome de uma classe de [middleware](../structure/middleware.md)." #. type: Bullet: '- ' #: ../src/guide/runtime/routing.md msgid "Handler action (an array of [HandlerClass, handlerMethod])." -msgstr "" +msgstr "Uma action de handler (um array no formato [HandlerClass, handlerMethod])." #. type: Bullet: '- ' #: ../src/guide/runtime/routing.md msgid "A callable." -msgstr "" +msgstr "Um callable." #. type: Plain text #: ../src/guide/runtime/routing.md msgid "In case of a handler action, a class of type `HandlerClass` is instantiated and its `handlerMethod` is called:" -msgstr "" +msgstr "No caso de uma action de handler, uma classe do tipo `HandlerClass` é instanciada e o seu método `handlerMethod` é chamado:" #. type: Fenced code block (php) #: ../src/guide/runtime/routing.md @@ -169,11 +194,21 @@ msgid "" " }\n" "}\n" msgstr "" +"use Psr\\Http\\Message\\ServerRequestInterface;\n" +"use Psr\\Http\\Message\\ResponseInterface;\n" +"\n" +"final readonly class HandlerClass\n" +"{\n" +" public function handle(ServerRequestInterface $request): ResponseInterface\n" +" {\n" +" // ...\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "The callable is called as is:" -msgstr "" +msgstr "O callable é chamado como está:" #. type: Fenced code block (php) #: ../src/guide/runtime/routing.md @@ -185,27 +220,32 @@ msgid "" " return $response;\n" "}\n" msgstr "" +"static function (ServerRequestInterface $request, RequestHandlerInterface $next) use ($responseFactory) {\n" +" $response = $responseFactory->createResponse();\n" +" $response->getBody()->write('You are at homepage.');\n" +" return $response;\n" +"}\n" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "For handler action and callable typed parameters are automatically injected using the dependency injection container passed to the route." -msgstr "" +msgstr "Para actions de handler e callables, os parâmetros tipados são injetados automaticamente pelo container de injeção de dependência passado para a rota." #. type: Plain text #: ../src/guide/runtime/routing.md msgid "Get current request and handler by type-hinting for `ServerRequestInterface` and `RequestHandlerInterface`." -msgstr "" +msgstr "Obtenha a requisição e o handler atuais usando os type hints `ServerRequestInterface` e `RequestHandlerInterface`." #. type: Title ### #: ../src/guide/runtime/routing.md #, no-wrap msgid "Route arguments in actions" -msgstr "" +msgstr "Argumentos de rota nas actions" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "Named route parameters are stored in `CurrentRoute`. To pass a route parameter to an action method parameter, use the `RouteArgument` attribute:" -msgstr "" +msgstr "Os parâmetros nomeados da rota ficam guardados em `CurrentRoute`. Para passar um parâmetro de rota para um parâmetro do método da action, use o atributo `RouteArgument`:" #. type: Fenced code block (php) #: ../src/guide/runtime/routing.md @@ -233,11 +273,32 @@ msgid "" " }\n" "}\n" msgstr "" +"action([PostController::class, 'view'])\n" +" ->name('post/view')\n" +"];\n" +"\n" +"final readonly class PostController\n" +"{\n" +" public function view(#[RouteArgument('id')] int $id): ResponseInterface\n" +" {\n" +" // $id contains the value from the {id} route parameter.\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "If a parameter has the same name as the action parameter, you can omit the attribute name:" -msgstr "" +msgstr "Se o parâmetro tiver o mesmo nome do parâmetro da action, você pode omitir o nome no atributo:" #. type: Fenced code block (php) #: ../src/guide/runtime/routing.md @@ -248,11 +309,15 @@ msgid "" " // ...\n" "}\n" msgstr "" +"public function view(#[RouteArgument] int $id): ResponseInterface\n" +"{\n" +" // ...\n" +"}\n" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "You can also inject `CurrentRoute` into an action or a service when you need several arguments or route metadata:" -msgstr "" +msgstr "Você também pode injetar `CurrentRoute` em uma action ou em um serviço quando precisar de vários argumentos ou de metadados da rota:" #. type: Fenced code block (php) #: ../src/guide/runtime/routing.md @@ -276,21 +341,38 @@ msgid "" " }\n" "}\n" msgstr "" +"getArgument('id');\n" +" $routeName = $currentRoute->getName();\n" +"\n" +" // ...\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "Route arguments aren't request attributes. Read them from `CurrentRoute` or action parameters marked with `RouteArgument`." -msgstr "" +msgstr "Argumentos de rota não são atributos da requisição. Leia-os de `CurrentRoute` ou de parâmetros da action marcados com `RouteArgument`." #. type: Plain text #: ../src/guide/runtime/routing.md msgid "For optional route parameters, provide a default value either in the route with `defaults()` or in the action method signature." -msgstr "" +msgstr "Para parâmetros de rota opcionais, informe um valor padrão na rota com `defaults()` ou na assinatura do método da action." #. type: Plain text #: ../src/guide/runtime/routing.md msgid "You could add extra handlers to wrap primary one with `middleware()` method:" -msgstr "" +msgstr "Você pode adicionar handlers extras em volta do principal com o método `middleware()`:" #. type: Fenced code block (php) #: ../src/guide/runtime/routing.md @@ -310,16 +392,29 @@ msgid "" " ->middleware(LimitDownloadRate::class)\n" "];\n" msgstr "" +"action([DownloadController::class, 'download'])\n" +" ->name('download/id')\n" +" ->middleware(LimitDownloadRate::class)\n" +"];\n" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "Check [\"the middleware\"](../structure/middleware.md) guide to learn more about how to implement middleware." -msgstr "" +msgstr "Veja o guia sobre [\"middleware\"](../structure/middleware.md) para saber mais sobre como implementar middlewares." #. type: Plain text #: ../src/guide/runtime/routing.md msgid "This is especially useful when grouping routes:" -msgstr "" +msgstr "Isso é especialmente útil ao agrupar rotas:" #. type: Fenced code block (php) #: ../src/guide/runtime/routing.md @@ -350,21 +445,45 @@ msgid "" " )\n" "];\n" msgstr "" +"middleware(ApiDataWrapper::class)\n" +" ->routes(\n" +" Route::get('/info/v2')\n" +" ->action(ApiInfo::class)\n" +" ->name('api/info/v2')\n" +" ->middleware(JsonDataResponseMiddleware::class),\n" +" Route::get('/user')\n" +" ->action([ApiUserController::class, 'index'])\n" +" ->name('api/user/index'),\n" +" Route::get('/user/{login}')\n" +" ->action([ApiUserController::class, 'profile'])\n" +" ->middleware(JsonDataResponseMiddleware::class)\n" +" ->name('api/user/profile'),\n" +" )\n" +"];\n" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "Router executes `ApiDataWrapper` before handling any URL starting with `/api`." -msgstr "" +msgstr "O router executa `ApiDataWrapper` antes de tratar qualquer URL que comece com `/api`." #. type: Plain text #: ../src/guide/runtime/routing.md msgid "You could name a route with a `name()` method. It's a good idea to choose a route name based on the handler's name." -msgstr "" +msgstr "Você pode dar um nome a uma rota com o método `name()`. É uma boa ideia escolher o nome da rota com base no nome do handler." #. type: Plain text #: ../src/guide/runtime/routing.md msgid "You can set a default value for a route parameter. For example:" -msgstr "" +msgstr "Você pode definir um valor padrão para um parâmetro de rota. Por exemplo:" #. type: Fenced code block (php) #: ../src/guide/runtime/routing.md @@ -385,43 +504,57 @@ msgid "" " ->defaults(['id' => '42'])\n" "];\n" msgstr "" +"action([SiteController::class, 'user'])\n" +" ->name('site/user')\n" +" ->defaults(['id' => '42'])\n" +"];\n" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "This configuration would result in a match with both `/user` and `/user/123`. In both cases `CurrentRoute` service will contain `id` argument filled. In the first case it will be default `42` and in the second case it will be `123`." -msgstr "" +msgstr "Essa configuração casa tanto com `/user` quanto com `/user/123`. Nos dois casos, o serviço `CurrentRoute` vai ter o argumento `id` preenchido. No primeiro caso, ele será o padrão `42` e, no segundo, `123`." #. type: Plain text #: ../src/guide/runtime/routing.md msgid "In cause URL should be valid for a single host, you can specify it with `host()`." -msgstr "" +msgstr "Se a URL só deve valer para um host, você pode defini-lo com `host()`." #. type: Title ### #: ../src/guide/runtime/routing.md ../src/guide/start/databases.md #, no-wrap msgid "Routing" -msgstr "" +msgstr "Roteamento" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "Yii routing is flexible, and internally it may use different routing implementations. The actual matching algorithm may vary, but the basic idea stays the same." -msgstr "" +msgstr "O roteamento do Yii é flexível e, internamente, pode usar diferentes implementações. O algoritmo de casamento pode variar, mas a ideia básica é a mesma." #. type: Plain text #: ../src/guide/runtime/routing.md msgid "Router matches routes defined in config from top to bottom. If there is a match, further matching isn't performed and the router executes the route handler to get the response. If there is no match at all, router passes handling to the next middleware in the [application middleware set](../structure/middleware.md)." -msgstr "" +msgstr "O router casa as rotas definidas na configuração de cima para baixo. Se houver um casamento, ele para de procurar e executa o handler da rota para obter a resposta. Se nenhuma rota casar, o router passa o tratamento para o próximo middleware do [conjunto de middlewares da aplicação](../structure/middleware.md)." #. type: Title ### #: ../src/guide/runtime/routing.md #, no-wrap msgid "Automatic OPTIONS responses" -msgstr "" +msgstr "Respostas OPTIONS automáticas" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "When the request path matches a route but the HTTP method doesn't, router returns a `405 Method Not Allowed` response with an `Allow` header:" -msgstr "" +msgstr "Quando o caminho da requisição casa com uma rota, mas o método HTTP não, o router retorna uma resposta `405 Method Not Allowed` com o header `Allow`:" #. type: Fenced code block (http) #: ../src/guide/runtime/routing.md @@ -430,11 +563,13 @@ msgid "" "HTTP/1.1 405 Method Not Allowed\n" "Allow: GET\n" msgstr "" +"HTTP/1.1 405 Method Not Allowed\n" +"Allow: GET\n" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "For an `OPTIONS` request to the same path, router returns an empty `204 No Content` response with the same `Allow` header:" -msgstr "" +msgstr "Para uma requisição `OPTIONS` no mesmo caminho, o router retorna uma resposta vazia `204 No Content` com o mesmo header `Allow`:" #. type: Fenced code block (http) #: ../src/guide/runtime/routing.md @@ -443,11 +578,13 @@ msgid "" "HTTP/1.1 204 No Content\n" "Allow: GET\n" msgstr "" +"HTTP/1.1 204 No Content\n" +"Allow: GET\n" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "This response is generated from the configured routes before the route action runs. If an API endpoint needs CORS headers, attach CORS middleware to a route group:" -msgstr "" +msgstr "Essa resposta é gerada a partir das rotas configuradas, antes de a action da rota ser executada. Se um endpoint de API precisar de headers CORS, adicione um middleware de CORS a um grupo de rotas:" #. type: Fenced code block (php) #: ../src/guide/runtime/routing.md @@ -473,17 +610,36 @@ msgid "" " )\n" "];\n" msgstr "" +"withCors(CorsMiddleware::class)\n" +" ->routes(\n" +" Route::methods([Method::GET, Method::POST], '/posts')\n" +" ->action([PostController::class, 'index'])\n" +" ->name('api/posts')\n" +" )\n" +"];\n" #. type: Title ## #: ../src/guide/runtime/routing.md #, no-wrap msgid "Generating URLs" -msgstr "" +msgstr "Gerando URLs" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "To generate URL based on a route, a route should have a name:" -msgstr "" +msgstr "Para gerar uma URL a partir de uma rota, a rota precisa ter um nome:" #. type: Fenced code block (php) #: ../src/guide/runtime/routing.md @@ -505,11 +661,26 @@ msgid "" " ->name('test/submit')\n" "];\n" msgstr "" +"action([TestController::class, 'index'])\n" +" ->name('test/index'),\n" +" Route::post('/test/submit/{id}')\n" +" ->action([TestController::class, 'submit'])\n" +" ->name('test/submit')\n" +"];\n" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "The generation looks like the following:" -msgstr "" +msgstr "A geração fica assim:" #. type: Fenced code block (php) #: ../src/guide/runtime/routing.md @@ -538,21 +709,43 @@ msgid "" " }\n" "}\n" msgstr "" +"generate('test/submit', ['id' => '42']);\n" +" // ...\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "In the above code, we get a generator instance with the help of [automatic dependency injection](../concept/di-container.md) that works with action handlers. In another service, you can get the instance with similar constructor injection. In views URL generator is available as `$url`." -msgstr "" +msgstr "No código acima, obtemos uma instância do gerador com a ajuda da [injeção de dependência automática](../concept/di-container.md), que funciona com handlers de action. Em outro serviço, você pode obter a instância com uma injeção no construtor parecida. Nas views, o gerador de URLs está disponível como `$url`." #. type: Plain text #: ../src/guide/runtime/routing.md msgid "Then we use `generate()` method to get the actual URL. It accepts a route name, route arguments, query parameters, and a hash fragment. The code will return `/test/submit/42`." -msgstr "" +msgstr "Depois usamos o método `generate()` para obter a URL. Ele aceita o nome da rota, argumentos de rota, parâmetros de query e um fragmento (hash). O código retorna `/test/submit/42`." #. type: Plain text #: ../src/guide/runtime/routing.md msgid "Route arguments are used to fill placeholders in the route pattern. Arguments that aren't used in the pattern are added to the query string when the query parameters array doesn't already contain the same name:" -msgstr "" +msgstr "Os argumentos de rota preenchem os placeholders do padrão da rota. Os argumentos que não aparecem no padrão são adicionados à query string, desde que o array de parâmetros de query ainda não tenha o mesmo nome:" #. type: Fenced code block (php) #: ../src/guide/runtime/routing.md @@ -565,44 +758,50 @@ msgid "" ");\n" "// $url is \"/test/submit/42?page=1&utm=newsletter\".\n" msgstr "" +"$url = $urlGenerator->generate(\n" +" 'test/submit',\n" +" ['id' => '42', 'utm' => 'newsletter'],\n" +" ['page' => '1']\n" +");\n" +"// $url is \"/test/submit/42?page=1&utm=newsletter\".\n" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "If you need absolute URL, use `generateAbsolute()` instead." -msgstr "" +msgstr "Se você precisar de uma URL absoluta, use `generateAbsolute()`." #. type: Title ### #: ../src/guide/runtime/routing.md #, no-wrap msgid "Generating URL from the current route" -msgstr "" +msgstr "Gerando a URL a partir da rota atual" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "Use `generateFromCurrent()` when a link should keep the current route and most of its arguments. For example, a detail page can link to another page number while keeping the current route name and `id` argument:" -msgstr "" +msgstr "Use `generateFromCurrent()` quando um link deve manter a rota atual e a maior parte dos seus argumentos. Por exemplo, uma página de detalhes pode apontar para outro número de página mantendo o nome da rota atual e o argumento `id`:" #. type: Fenced code block (php) #: ../src/guide/runtime/routing.md #, no-wrap msgid "$url = $urlGenerator->generateFromCurrent(['page' => '2']);\n" -msgstr "" +msgstr "$url = $urlGenerator->generateFromCurrent(['page' => '2']);\n" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "The method also keeps query parameters from the current request. Pass explicit query parameters when a link should replace or add query string values." -msgstr "" +msgstr "O método também mantém os parâmetros de query da requisição atual. Passe parâmetros de query explícitos quando o link precisar substituir ou adicionar valores na query string." #. type: Title ### #: ../src/guide/runtime/routing.md #, no-wrap msgid "Locale-based URLs" -msgstr "" +msgstr "URLs com locale" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "When the locale is part of the URL path, define it as a route argument. For a Yii application with routes in `config/common/routes.php`, wrap localized routes in a group with a locale parameter:" -msgstr "" +msgstr "Quando o locale faz parte do caminho da URL, defina-o como um argumento de rota. Em uma aplicação Yii com as rotas em `config/common/routes.php`, coloque as rotas localizadas em um grupo com um parâmetro de locale:" #. type: Fenced code block (php) #: ../src/guide/runtime/routing.md @@ -629,16 +828,36 @@ msgid "" " )\n" "];\n" msgstr "" +"routes(\n" +" Route::get('/')\n" +" ->action(HomePageAction::class)\n" +" ->name('home'),\n" +" Route::get('/posts/{slug}')\n" +" ->action(PostViewAction::class)\n" +" ->name('post/view')\n" +" )\n" +"];\n" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "The route `/de/posts/welcome` matches the `post/view` route and stores `_locale` as a route argument with the `de` value." -msgstr "" +msgstr "A rota `/de/posts/welcome` casa com a rota `post/view` e guarda `_locale` como argumento de rota com o valor `de`." #. type: Plain text #: ../src/guide/runtime/routing.md msgid "In middleware that chooses the request locale, read this argument from `CurrentRoute`:" -msgstr "" +msgstr "No middleware que escolhe o locale da requisição, leia esse argumento de `CurrentRoute`:" #. type: Fenced code block (php) #: ../src/guide/runtime/routing.md @@ -682,11 +901,48 @@ msgid "" " }\n" "}\n" msgstr "" +"currentRoute->getArgument('_locale', self::DEFAULT_LOCALE);\n" +"\n" +" $this->translator->setLocale($locale);\n" +" $this->view->setLocale($locale);\n" +" $this->urlGenerator->setDefaultArgument('_locale', $locale);\n" +"\n" +" return $handler->handle($request);\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "Register this middleware in the localized route group before the route action:" -msgstr "" +msgstr "Registre esse middleware no grupo de rotas localizadas, antes da action da rota:" #. type: Fenced code block (php) #: ../src/guide/runtime/routing.md @@ -707,11 +963,25 @@ msgid "" " )\n" "];\n" msgstr "" +"use App\\Web\\HomePage\\Action as HomePageAction;\n" +"use App\\Web\\Middleware\\LocaleMiddleware;\n" +"use Yiisoft\\Router\\Group;\n" +"use Yiisoft\\Router\\Route;\n" +"\n" +"return [\n" +" Group::create('/{_locale:en-US|de}')\n" +" ->middleware(LocaleMiddleware::class)\n" +" ->routes(\n" +" Route::get('/')\n" +" ->action(HomePageAction::class)\n" +" ->name('home')\n" +" )\n" +"];\n" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "After the middleware sets the default `_locale` argument, URL generation can omit it:" -msgstr "" +msgstr "Depois que o middleware define o argumento padrão `_locale`, a geração de URLs pode omiti-lo:" #. type: Fenced code block (php) #: ../src/guide/runtime/routing.md @@ -720,11 +990,13 @@ msgid "" "$url = $urlGenerator->generate('post/view', ['slug' => 'welcome']);\n" "// On a German page, $url is \"/de/posts/welcome\".\n" msgstr "" +"$url = $urlGenerator->generate('post/view', ['slug' => 'welcome']);\n" +"// On a German page, $url is \"/de/posts/welcome\".\n" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "For a language switcher, use `generateFromCurrent()` and replace only the locale argument:" -msgstr "" +msgstr "Para um seletor de idioma, use `generateFromCurrent()` e substitua apenas o argumento de locale:" #. type: Fenced code block (php) #: ../src/guide/runtime/routing.md @@ -735,33 +1007,37 @@ msgid "" " fallbackRouteName: 'home'\n" ");\n" msgstr "" +"$url = $urlGenerator->generateFromCurrent(\n" +" ['_locale' => 'en-US'],\n" +" fallbackRouteName: 'home'\n" +");\n" #. type: Title ## #: ../src/guide/runtime/routing.md #, no-wrap msgid "Route patterns" -msgstr "" +msgstr "Padrões de rota" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "Route patterns used depend on the underlying implementation used. The default implementation is [nikic/FastRoute](https://github.com/nikic/FastRoute)." -msgstr "" +msgstr "Os padrões de rota dependem da implementação usada por baixo. A implementação padrão é o [nikic/FastRoute](https://github.com/nikic/FastRoute)." #. type: Plain text #: ../src/guide/runtime/routing.md msgid "Basic patterns are static like `/test`. That means they must match exactly in order for a route match." -msgstr "" +msgstr "Os padrões básicos são estáticos, como `/test`. Isso significa que eles precisam casar exatamente para a rota ser escolhida." #. type: Title ### #: ../src/guide/runtime/routing.md #, no-wrap msgid "Named Parameters" -msgstr "" +msgstr "Parâmetros nomeados" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "A pattern can include one or more named parameters which are specified in the pattern in the format of `{ParamName:RegExp}`, where `ParamName` specifies the parameter name and `RegExp` is an optional regular expression used to match parameter values. If `RegExp` isn't specified, it means the parameter value should be a string without any slash." -msgstr "" +msgstr "Um padrão pode ter um ou mais parâmetros nomeados, escritos no formato `{ParamName:RegExp}`, onde `ParamName` é o nome do parâmetro e `RegExp` é uma expressão regular opcional usada para casar o valor. Se `RegExp` não for informada, o valor do parâmetro deve ser uma string sem barras." #. type: Plain text #: ../src/guide/runtime/routing.md @@ -770,61 +1046,63 @@ msgid "" "> [!NOTE]\n" "> You can only use regular expressions inside parameters. The rest of the pattern is considered plain text.\n" msgstr "" +"> [!NOTE]\n" +"> Você só pode usar expressões regulares dentro dos parâmetros. O resto do padrão é tratado como texto puro.\n" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "You can't use capturing groups. For example `{lang:(en|de)}` isn't a valid placeholder, because `()` is a capturing group. Instead, you can use either `{lang:en|de}` or `{lang:(?:en|de)}`." -msgstr "" +msgstr "Você não pode usar grupos de captura. Por exemplo, `{lang:(en|de)}` não é um placeholder válido, porque `()` é um grupo de captura. Em vez disso, use `{lang:en|de}` ou `{lang:(?:en|de)}`." #. type: Plain text #: ../src/guide/runtime/routing.md msgid "On a route match router fills `CurrentRoute` arguments with values matching the corresponding parts of the URL. When you use the rule to create a URL, it will take the values of the provided parameters and insert them at the places where the parameters are declared." -msgstr "" +msgstr "Quando uma rota casa, o router preenche os argumentos de `CurrentRoute` com os valores das partes correspondentes da URL. Quando você usa a regra para criar uma URL, ela pega os valores dos parâmetros informados e os insere nas posições onde os parâmetros foram declarados." #. type: Plain text #: ../src/guide/runtime/routing.md msgid "Let's use some examples to illustrate how named parameters work. Assume you've declared the following three patterns:" -msgstr "" +msgstr "Vamos usar alguns exemplos para mostrar como os parâmetros nomeados funcionam. Suponha que você declarou os três padrões a seguir:" #. type: Bullet: '1. ' #: ../src/guide/runtime/routing.md msgid "`'posts/{year:\\d{4}}/{category}`" -msgstr "" +msgstr "`'posts/{year:\\d{4}}/{category}`" #. type: Bullet: '2. ' #: ../src/guide/runtime/routing.md msgid "`'posts'`" -msgstr "" +msgstr "`'posts'`" #. type: Bullet: '3. ' #: ../src/guide/runtime/routing.md msgid "`'post/{id:\\d+}'`" -msgstr "" +msgstr "`'post/{id:\\d+}'`" #. type: Bullet: '- ' #: ../src/guide/runtime/routing.md msgid "`/posts` match the second pattern;" -msgstr "" +msgstr "`/posts` casa com o segundo padrão;" #. type: Bullet: '- ' #: ../src/guide/runtime/routing.md msgid "`/posts/2014/php` match a first pattern. Parameters are the `year` whose value is 2014 and the `category` whose value is `php`;" -msgstr "" +msgstr "`/posts/2014/php` casa com o primeiro padrão. Os parâmetros são `year`, com valor 2014, e `category`, com valor `php`;" #. type: Bullet: '- ' #: ../src/guide/runtime/routing.md msgid "`/post/100` match a third pattern. The `id` parameter value is 100;" -msgstr "" +msgstr "`/post/100` casa com o terceiro padrão. O valor do parâmetro `id` é 100;" #. type: Bullet: '- ' #: ../src/guide/runtime/routing.md msgid "`/posts/php` doesn't match." -msgstr "" +msgstr "`/posts/php` não casa." #. type: Plain text #: ../src/guide/runtime/routing.md msgid "When generating URLs, you should use the following parameters:" -msgstr "" +msgstr "Ao gerar URLs, você deve usar os seguintes parâmetros:" #. type: Fenced code block (php) #: ../src/guide/runtime/routing.md @@ -834,17 +1112,20 @@ msgid "" "echo $url->generate('second');\n" "echo $url->generate('third', ['id' => '42']);\n" msgstr "" +"echo $url->generate('first', ['year' => '2020', 'category' => 'Virology']);\n" +"echo $url->generate('second');\n" +"echo $url->generate('third', ['id' => '42']);\n" #. type: Title ### #: ../src/guide/runtime/routing.md #, no-wrap msgid "Optional parts" -msgstr "" +msgstr "Partes opcionais" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "You should wrap optional pattern parts with `[` and `]`. For example, `/posts[/{id}]` pattern would match both `http://example.com/posts` and `http://example.com/posts/42`. Router would fill `id` argument of `CurrentRoute` service in the second case only. In this case, you could specify the default value:" -msgstr "" +msgstr "Coloque as partes opcionais do padrão entre `[` e `]`. Por exemplo, o padrão `/posts[/{id}]` casa tanto com `http://example.com/posts` quanto com `http://example.com/posts/42`. O router só preenche o argumento `id` do serviço `CurrentRoute` no segundo caso. Nesse caso, você pode definir o valor padrão:" #. type: Fenced code block (php) #: ../src/guide/runtime/routing.md @@ -854,8 +1135,11 @@ msgid "" "\n" "Route::get('/posts[/{id}]')->defaults(['id' => '1']);\n" msgstr "" +"use \\Yiisoft\\Router\\Route;\n" +"\n" +"Route::get('/posts[/{id}]')->defaults(['id' => '1']);\n" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "Optional parts are only supported in a trailing position, not in the middle of a route." -msgstr "" +msgstr "Partes opcionais só são suportadas no final da rota, não no meio dela." diff --git a/_translations/po/pt-BR/guide_runtime_sessions.md.po b/_translations/po/pt-BR/guide_runtime_sessions.md.po index ebb628d7..6cea8a7a 100644 --- a/_translations/po/pt-BR/guide_runtime_sessions.md.po +++ b/_translations/po/pt-BR/guide_runtime_sessions.md.po @@ -8,51 +8,50 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-09-29 22:50+0000\n" "PO-Revision-Date: 2026-09-29 22:50+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/guide/runtime/sessions.md -#: ../src/guide/tutorial/using-yii-with-swoole.md +#: ../src/guide/runtime/sessions.md ../src/guide/tutorial/using-yii-with-swoole.md #, no-wrap msgid "Sessions" -msgstr "" +msgstr "Sessões" #. type: Plain text #: ../src/guide/runtime/sessions.md msgid "Sessions persist data between requests without passing them to the client and back. Yii has [a session package](https://github.com/yiisoft/session) to work with session data." -msgstr "" +msgstr "As sessões mantêm dados entre requisições sem precisar enviá-los ao cliente e de volta. O Yii tem [um pacote de sessão](https://github.com/yiisoft/session) para trabalhar com os dados da sessão." #. type: Plain text #: ../src/guide/runtime/sessions.md msgid "To add it to your application, use composer:" -msgstr "" +msgstr "Para adicioná-lo à sua aplicação, use o composer:" #. type: Fenced code block (shell) #: ../src/guide/runtime/sessions.md #, no-wrap msgid "composer require yiisoft/session\n" -msgstr "" +msgstr "composer require yiisoft/session\n" #. type: Title ## #: ../src/guide/runtime/sessions.md #, no-wrap msgid "Configuring middleware" -msgstr "" +msgstr "Configurando o middleware" #. type: Plain text #: ../src/guide/runtime/sessions.md msgid "To keep a session between requests, you need to add `SessionMiddleware` to your route group or application middlewares. You should prefer a route group when you have both API with token-based authentication and regular web routes in the same application. Having it this way avoids starting the session for API endpoints." -msgstr "" +msgstr "Para manter a sessão entre requisições, você precisa adicionar o `SessionMiddleware` ao seu grupo de rotas ou aos middlewares da aplicação. Prefira um grupo de rotas quando a mesma aplicação tiver uma API com autenticação por token e rotas web comuns. Assim, a sessão não é iniciada nos endpoints da API." #. type: Plain text #: ../src/guide/runtime/sessions.md msgid "To add a session for a certain group of routes, edit `config/routes.php` like the following:" -msgstr "" +msgstr "Para adicionar a sessão a um grupo específico de rotas, edite `config/routes.php` assim:" #. type: Fenced code block (php) #: ../src/guide/runtime/sessions.md @@ -73,11 +72,25 @@ msgid "" " )\n" "];\n" msgstr "" +"middleware(SessionMiddleware::class)\n" +" ->routes(\n" +" // ...\n" +" )\n" +"];\n" #. type: Plain text #: ../src/guide/runtime/sessions.md msgid "To add a session to the whole application, edit `config/application.php` like the following:" -msgstr "" +msgstr "Para adicionar a sessão à aplicação inteira, edite `config/application.php` assim:" #. type: Fenced code block (php) #: ../src/guide/runtime/sessions.md @@ -101,12 +114,29 @@ msgid "" " ],\n" "];\n" msgstr "" +"return [\n" +" Yiisoft\\Yii\\Web\\Application::class => [\n" +" '__construct()' => [\n" +" 'dispatcher' => DynamicReference::to(static function (Injector $injector) {\n" +" return ($injector->make(MiddlewareDispatcher::class))\n" +" ->withMiddlewares(\n" +" [\n" +" Router::class,\n" +" CsrfTokenMiddleware::class,\n" +" SessionMiddleware::class, // <-- add this\n" +" ErrorCatcher::class,\n" +" ]\n" +" );\n" +" }),\n" +" ],\n" +" ],\n" +"];\n" #. type: Title ## #: ../src/guide/runtime/sessions.md #, no-wrap msgid "Opening and closing session" -msgstr "" +msgstr "Abrindo e fechando a sessão" #. type: Fenced code block (php) #: ../src/guide/runtime/sessions.md @@ -123,6 +153,16 @@ msgid "" " $session->close();\n" "}\n" msgstr "" +"public function actionProfile(\\Yiisoft\\Session\\SessionInterface $session)\n" +"{\n" +" // start a session if it's not yet started\n" +" $session->open();\n" +"\n" +" // work with session\n" +"\n" +" // write session values and then close it\n" +" $session->close();\n" +"}\n" #. type: Plain text #: ../src/guide/runtime/sessions.md @@ -132,11 +172,14 @@ msgid "" "> Closing session as early as possible is a good practice since many session implementations are blocking other\n" "> requests while the session is open.\n" msgstr "" +"> [!NOTE]\n" +"> Fechar a sessão o quanto antes é uma boa prática, já que muitas implementações de sessão bloqueiam outras\n" +"> requisições enquanto a sessão está aberta.\n" #. type: Plain text #: ../src/guide/runtime/sessions.md msgid "There are two more ways to close a session:" -msgstr "" +msgstr "Há mais duas formas de fechar uma sessão:" #. type: Fenced code block (php) #: ../src/guide/runtime/sessions.md @@ -151,17 +194,25 @@ msgid "" " $session->destroy(); \n" "}\n" msgstr "" +"public function actionProfile(\\Yiisoft\\Session\\SessionInterface $session)\n" +"{\n" +" // discard changes and close the session\n" +" $session->discard();\n" +"\n" +" // destroy the session completely\n" +" $session->destroy(); \n" +"}\n" #. type: Title ## #: ../src/guide/runtime/sessions.md #, no-wrap msgid "Working with session data" -msgstr "" +msgstr "Trabalhando com os dados da sessão" #. type: Plain text #: ../src/guide/runtime/sessions.md msgid "Usually you will use the following methods to work with session data:" -msgstr "" +msgstr "Normalmente você vai usar os seguintes métodos para trabalhar com os dados da sessão:" #. type: Fenced code block (php) #: ../src/guide/runtime/sessions.md @@ -193,22 +244,47 @@ msgid "" " $session->clear();\n" "}\n" msgstr "" +"public function actionProfile(\\Yiisoft\\Session\\SessionInterface $session)\n" +"{\n" +" // get a value\n" +" $lastAccessTime = $session->get('lastAccessTime');\n" +"\n" +" // get all values\n" +" $sessionData = $session->all();\n" +" \n" +" // set a value\n" +" $session->set('lastAccessTime', time());\n" +"\n" +" // check if the value exists\n" +" if ($session->has('lastAccessTime')) {\n" +" // ... \n" +" }\n" +" \n" +" // remove value\n" +" $session->remove('lastAccessTime');\n" +"\n" +" // get value and then remove it\n" +" $sessionData = $session->pull('lastAccessTime');\n" +"\n" +" // clear session data from runtime\n" +" $session->clear();\n" +"}\n" #. type: Title ## #: ../src/guide/runtime/sessions.md #, no-wrap msgid "Flash messages" -msgstr "" +msgstr "Mensagens flash" #. type: Plain text #: ../src/guide/runtime/sessions.md msgid "In case you need some data to remain in session until read, such as in case of displaying a message on the next page, \"flash\" messages are what you need. A flash message is a special type of data that's available only in the current request and the next request. After that, it will be deleted automatically." -msgstr "" +msgstr "Quando você precisa que um dado fique na sessão até ser lido, como ao exibir uma mensagem na próxima página, o que você precisa são as mensagens \"flash\". Uma mensagem flash é um tipo especial de dado que só fica disponível na requisição atual e na próxima. Depois disso, ela é apagada automaticamente." #. type: Plain text #: ../src/guide/runtime/sessions.md msgid "`FlashInteface` usage is the following:" -msgstr "" +msgstr "O uso de `FlashInteface` é o seguinte:" #. type: Fenced code block (php) #: ../src/guide/runtime/sessions.md @@ -225,17 +301,27 @@ msgid "" " // do something with it\n" "}\n" msgstr "" +"/** @var Yiisoft\\Session\\Flash\\FlashInterface $flash */\n" +"\n" +"// request 1\n" +"$flash->set('warning', 'Oh no, not again.');\n" +"\n" +"// request 2\n" +"$warning = $flash->get('warning');\n" +"if ($warning !== null) {\n" +" // do something with it\n" +"}\n" #. type: Title ## #: ../src/guide/runtime/sessions.md #, no-wrap msgid "Custom session storage" -msgstr "" +msgstr "Armazenamento de sessão personalizado" #. type: Plain text #: ../src/guide/runtime/sessions.md msgid "When using `Yiisoft\\Session\\Session`, you can use your own storage implementation:" -msgstr "" +msgstr "Ao usar `Yiisoft\\Session\\Session`, você pode usar a sua própria implementação de armazenamento:" #. type: Fenced code block (php) #: ../src/guide/runtime/sessions.md @@ -244,8 +330,10 @@ msgid "" "$handler = new MySessionHandler();\n" "$session = new \\Yiisoft\\Session\\Session([], $handler);\n" msgstr "" +"$handler = new MySessionHandler();\n" +"$session = new \\Yiisoft\\Session\\Session([], $handler);\n" #. type: Plain text #: ../src/guide/runtime/sessions.md msgid "Custom storage must implement `\\SessionHandlerInterface`." -msgstr "" +msgstr "O armazenamento personalizado precisa implementar `\\SessionHandlerInterface`." diff --git a/_translations/po/pt-BR/guide_start_databases.md.po b/_translations/po/pt-BR/guide_start_databases.md.po index 5e705b67..95243bd6 100644 --- a/_translations/po/pt-BR/guide_start_databases.md.po +++ b/_translations/po/pt-BR/guide_start_databases.md.po @@ -48,7 +48,7 @@ msgstr "Trabalhando com bancos de dados" #: ../src/guide/runtime/routing.md ../src/guide/start/databases.md #, no-wrap msgid "Routing" -msgstr "" +msgstr "Roteamento" #. type: Plain text #: ../src/guide/start/databases.md diff --git a/_translations/po/pt-BR/guide_tutorial_using-yii-with-swoole.md.po b/_translations/po/pt-BR/guide_tutorial_using-yii-with-swoole.md.po index 52e3e0f8..fd52dfbd 100644 --- a/_translations/po/pt-BR/guide_tutorial_using-yii-with-swoole.md.po +++ b/_translations/po/pt-BR/guide_tutorial_using-yii-with-swoole.md.po @@ -34,7 +34,7 @@ msgstr "" #: ../src/guide/tutorial/using-yii-with-swoole.md #, no-wrap msgid "Sessions" -msgstr "" +msgstr "Sessões" #. type: Title ## #: ../src/guide/tutorial/using-yii-with-frankenphp.md diff --git a/_translations/po/pt-BR/internals_006-git-commit-messages.md.po b/_translations/po/pt-BR/internals_006-git-commit-messages.md.po index 44fe0852..e003bf1e 100644 --- a/_translations/po/pt-BR/internals_006-git-commit-messages.md.po +++ b/_translations/po/pt-BR/internals_006-git-commit-messages.md.po @@ -20,7 +20,7 @@ msgstr "" #: ../src/en/internals/006-git-commit-messages.md #, no-wrap msgid "Body" -msgstr "" +msgstr "Corpo" #. type: Title # #: ../src/en/internals/006-git-commit-messages.md diff --git a/src/pt-BR/guide/runtime/cookies.md b/src/pt-BR/guide/runtime/cookies.md index 9a8ff8a1..7f76589c 100644 --- a/src/pt-BR/guide/runtime/cookies.md +++ b/src/pt-BR/guide/runtime/cookies.md @@ -1,14 +1,15 @@ # Cookies -Cookies are for persisting data between requests by sending it to the client -browser using HTTP headers. The client sends data back to the server in -request headers. Thus, cookies are handy to store small amounts of data, -such as tokens or flags. +Os cookies servem para manter dados entre requisições, enviando-os ao +navegador do cliente por headers HTTP. O cliente devolve os dados ao +servidor nos headers da requisição. Por isso, os cookies são práticos para +guardar pequenas quantidades de dados, como tokens ou flags. -## Reading cookies +## Lendo cookies -You could obtain Cookie values from server request that's available as route -handler (such as controller action) argument: +Você pode obter os valores dos cookies a partir da requisição do servidor, +que está disponível como argumento do handler da rota (por exemplo, uma +action de controller): ```php private function actionProfile(\Psr\Http\Message\ServerRequestInterface $request) @@ -19,14 +20,14 @@ private function actionProfile(\Psr\Http\Message\ServerRequestInterface $request } ``` -In addition to getting cookie values directly from the server request, you -can also use the -[yiisoft/request-provider](https://github.com/yiisoft/request-provider) -package, which provides a more structured way to handle cookies through the -`\Yiisoft\RequestProvider\RequestCookieProvider`. This approach can -simplify your code and improve readability. +Além de obter os valores dos cookies direto da requisição do servidor, você +também pode usar o pacote +[yiisoft/request-provider](https://github.com/yiisoft/request-provider), que +oferece uma forma mais estruturada de lidar com cookies por meio do +`\Yiisoft\RequestProvider\RequestCookieProvider`. Essa abordagem pode +simplificar o código e melhorar a legibilidade. -Here’s an example of how to work with cookies using the +Veja um exemplo de como trabalhar com cookies usando o `\Yiisoft\RequestProvider\RequestCookieProvider`: ```php @@ -68,20 +69,21 @@ $cookie = (new \Yiisoft\Cookies\Cookie('cookieName', 'value')) return $cookie->addToResponse($response); ``` -After forming a cookie call `addToResponse()` passing an instance of -`\Psr\Http\Message\ResponseInterface` to add corresponding HTTP headers to -it. +Depois de montar o cookie, chame `addToResponse()` passando uma instância de +`\Psr\Http\Message\ResponseInterface` para adicionar os headers HTTP +correspondentes a ela. -## Signing and encrypting cookies +## Assinando e criptografando cookies -To prevent the substitution of the cookie value, the package provides two -implementations: +Para evitar que o valor do cookie seja substituído, o pacote oferece duas +implementações: -`Yiisoft\Cookies\CookieSigner` - signs each cookie with a unique prefix hash -based on the value of the cookie and a secret key. -`Yiisoft\Cookies\CookieEncryptor` - encrypts each cookie with a secret key. +`Yiisoft\Cookies\CookieSigner` - assina cada cookie com um prefixo de hash +único baseado no valor do cookie e em uma chave secreta. +`Yiisoft\Cookies\CookieEncryptor` - criptografa cada cookie com uma chave +secreta. -Encryption is more secure than signing but has lower performance. +A criptografia é mais segura que a assinatura, mas tem desempenho menor. ```php $cookie = new \Yiisoft\Cookies\Cookie('identity', 'identityValue'); @@ -96,18 +98,19 @@ $signedCookie = $signer->sign($cookie); $encryptedCookie = $encryptor->encrypt($cookie); ``` -To validate and get back the pure value, use the `validate()` and -`decrypt()` method. +Para validar e obter de volta o valor puro, use os métodos `validate()` e +`decrypt()`. ```php $cookie = $signer->validate($signedCookie); $cookie = $encryptor->decrypt($encryptedCookie); ``` -If the cookie value is tampered with or hasn't been signed/encrypted before, -a `\RuntimeException` will be thrown. Therefore, if you aren't sure that -the cookie value was signed/encrypted earlier, first use the `isSigned()` -and `isEncrypted()` methods, respectively. +Se o valor do cookie tiver sido adulterado ou não tiver sido +assinado/criptografado antes, uma `\RuntimeException` será lançada. Por +isso, se você não tem certeza de que o valor do cookie foi +assinado/criptografado antes, use primeiro os métodos `isSigned()` e +`isEncrypted()`, respectivamente. ```php if ($signer->isSigned($cookie)) { @@ -119,27 +122,29 @@ if ($encryptor->isEncrypted($cookie)) { } ``` -It makes sense to sign or encrypt the value of a cookie if you store -important data that a user shouldn't change. +Faz sentido assinar ou criptografar o valor de um cookie quando você guarda +dados importantes que o usuário não deve alterar. -### Automating encryption and signing +### Automatizando a criptografia e a assinatura -To automate the encryption/signing and decryption/validation of cookie -values, use an instance of `Yiisoft\Cookies\CookieMiddleware`, which is -[PSR-15](https://www.php-fig.org/psr/psr-15/) middleware. +Para automatizar a criptografia/assinatura e a descriptografia/validação dos +valores dos cookies, use uma instância de +`Yiisoft\Cookies\CookieMiddleware`, que é um middleware +[PSR-15](https://www.php-fig.org/psr/psr-15/). -This middleware provides the following features: +Esse middleware oferece os seguintes recursos: -- Validates and decrypts the cookie parameter values from the request. -- Excludes the cookie parameter from the request if it was tampered with and - logs information about it. -- Encrypts/signs cookie values and replaces their clean values in the - `Set-Cookie` headers in the response. +- Valida e descriptografa os valores dos cookies vindos da requisição. +- Remove o cookie da requisição se ele tiver sido adulterado e registra essa + informação no log. +- Criptografa/assina os valores dos cookies e substitui os valores puros nos + headers `Set-Cookie` da resposta. -In order for the middleware to know which values of which cookies need to be -encrypted/signed, an array of settings must be passed to its -constructor. The array keys are cookie name patterns and values are constant -values of `CookieMiddleware::ENCRYPT` or `CookieMiddleware::SIGN`. +Para o middleware saber quais valores de quais cookies precisam ser +criptografados/assinados, é preciso passar um array de configurações para o +construtor dele. As chaves do array são padrões de nomes de cookies e os +valores são as constantes `CookieMiddleware::ENCRYPT` ou +`CookieMiddleware::SIGN`. ```php use Yiisoft\Cookies\CookieMiddleware; @@ -155,11 +160,10 @@ $cookiesSettings = [ ]; ``` -For more information on using the wildcard pattern, see the -[yiisoft/strings](https://github.com/yiisoft/strings#wildcardpattern-usage) -package. +Para mais informações sobre o uso de padrões com curinga, veja o pacote +[yiisoft/strings](https://github.com/yiisoft/strings#wildcardpattern-usage). -Creating and using middleware: +Criando e usando o middleware: ```php /** @@ -190,22 +194,22 @@ $middleware = new \Yiisoft\Cookies\CookieMiddleware( $response = $middleware->process($request, $handler); ``` -If the `$cookiesSettings` array is empty, no cookies will be encrypted and -signed. - -## Cookies security - -You should configure each cookie to be secure. Important security settings -are: - -- `httpOnly`. Setting it to `true` would prevent JavaScript to access cookie - value. -- `secure`. Setting it to `true` would prevent sending cookie via `HTTP`. It - will be sent via `HTTPS` only. -- `sameSite`, if set to either `SAME_SITE_LAX` or `SAME_SITE_STRICT` would - prevent sending a cookie in cross-site browsing context. `SAME_SITE_LAX` - would prevent cookie sending during CSRF-prone request methods (e.g., - POST, PUT, PATCH, etc.). `SAME_SITE_STRICT` would prevent cookies sending - for all methods. -- Sign or encrypt the value of the cookie to prevent spoofing of values if - the data in the value shouldn't be tampered with. +Se o array `$cookiesSettings` estiver vazio, nenhum cookie será +criptografado ou assinado. + +## Segurança dos cookies + +Você deve configurar cada cookie para ser seguro. As configurações de +segurança importantes são: + +- `httpOnly`. Definir como `true` impede que o JavaScript acesse o valor do + cookie. +- `secure`. Definir como `true` impede o envio do cookie via `HTTP`. Ele só + será enviado via `HTTPS`. +- `sameSite`, se definido como `SAME_SITE_LAX` ou `SAME_SITE_STRICT`, impede + o envio do cookie em contexto de navegação entre sites. `SAME_SITE_LAX` + impede o envio do cookie em métodos de requisição sujeitos a CSRF (por + exemplo, POST, PUT, PATCH etc.). `SAME_SITE_STRICT` impede o envio dos + cookies em todos os métodos. +- Assine ou criptografe o valor do cookie para evitar falsificação quando os + dados não puderem ser adulterados. diff --git a/src/pt-BR/guide/runtime/handling-errors.md b/src/pt-BR/guide/runtime/handling-errors.md index b508d56d..c178a5d7 100644 --- a/src/pt-BR/guide/runtime/handling-errors.md +++ b/src/pt-BR/guide/runtime/handling-errors.md @@ -1,44 +1,46 @@ -# Handling errors - -Yii has a [yiisoft/error-handler](https://github.com/yiisoft/error-handler) -package that makes error handling a much more pleasant experience than -before. In particular, the Yii error handler provides the following: - -- [PSR-15](https://www.php-fig.org/psr/psr-15/) middleware for catching - unhandled errors. -- PSR-15 middleware for mapping certain exceptions to custom responses. -- Production and debug modes. -- Debug mode displays details, stacktrace, has dark and light themes and - handy buttons to search for error without typing. -- Takes PHP settings into account. -- Handles out of memory errors, fatal errors, warnings, notices, and - exceptions. -- Can use any [PSR-3](https://www.php-fig.org/psr/psr-3/) compatible logger - for error logging. -- Detects a response format based on a mime type of the request. -- Supports responding with HTML, plain text, JSON, XML, and headers out of - the box. -- You can implement your own error rendering for extra types. - -This guide describes how to use the error handler in the [Yii -framework](https://www.yiiframework.com/), for information about using it -separate from Yii, see the [package -description](https://github.com/yiisoft/error-handler). - -## Using error handler - -The error handler consists of two parts. One part is -`Yiisoft\ErrorHandler\Middleware\ErrorCatcher` middleware that, when -registered, catches exceptions that may appear during middleware stack -execution and passes them to the handler. Another part is the error handler -itself, `Yiisoft\ErrorHandler\ErrorHandler`, that's catching exceptions -occurring outside the middleware stack and fatal errors. The handler also -converts warnings and notices to exceptions and does more handy things. - -Error handler is registered in the application itself. Usually it happens in -`ApplicationRunner`. By default, the handler configuration comes from the -container. You may configure it in the application configuration, -`config/web.php` like the following: +# Tratamento de erros + +O Yii tem o pacote +[yiisoft/error-handler](https://github.com/yiisoft/error-handler), que torna +o tratamento de erros muito mais agradável do que antes. Em particular, o +error handler do Yii oferece: + +- Middleware [PSR-15](https://www.php-fig.org/psr/psr-15/) para capturar + erros não tratados. +- Middleware PSR-15 para mapear certas exceções para respostas + personalizadas. +- Modos de produção e de debug. +- O modo debug mostra detalhes e o stacktrace, tem temas claro e escuro e + botões práticos para pesquisar o erro sem digitar. +- Leva em conta as configurações do PHP. +- Trata erros de falta de memória, erros fatais, warnings, notices e + exceções. +- Pode usar qualquer logger compatível com a + [PSR-3](https://www.php-fig.org/psr/psr-3/) para registrar os erros. +- Detecta o formato da resposta com base no mime type da requisição. +- Suporta respostas em HTML, texto puro, JSON, XML e headers sem + configuração extra. +- Você pode implementar a sua própria renderização de erros para outros + tipos. + +Este guia descreve como usar o error handler no [framework +Yii](https://www.yiiframework.com/). Para usá-lo separado do Yii, veja a +[descrição do pacote](https://github.com/yiisoft/error-handler). + +## Usando o error handler + +O error handler tem duas partes. Uma é o middleware +`Yiisoft\ErrorHandler\Middleware\ErrorCatcher`, que, quando registrado, +captura as exceções que podem surgir durante a execução da pilha de +middlewares e as passa para o handler. A outra é o próprio error handler, +`Yiisoft\ErrorHandler\ErrorHandler`, que captura as exceções que ocorrem +fora da pilha de middlewares e os erros fatais. O handler também converte +warnings e notices em exceções e faz outras coisas úteis. + +O error handler é registrado na própria aplicação. Normalmente isso acontece +no `ApplicationRunner`. Por padrão, a configuração do handler vem do +container. Você pode configurá-lo na configuração da aplicação, +`config/web.php`, assim: ```php use Psr\Log\LoggerInterface; @@ -71,9 +73,10 @@ return [ ]; ``` -As aforementioned, the error handler turns all non-fatal PHP errors into -catchable exceptions (`Yiisoft\ErrorHandler\Exception\ErrorException`). This -means you can use the following code to deal with PHP errors: +Como dito acima, o error handler transforma todos os erros não fatais do PHP +em exceções que podem ser capturadas +(`Yiisoft\ErrorHandler\Exception\ErrorException`). Isso significa que você +pode usar o código a seguir para lidar com erros do PHP: ```php try { @@ -84,10 +87,10 @@ try { // execution continues... ``` -The package has another middleware, -`Yiisoft\ErrorHandler\Middleware\ExceptionResponder`. This middleware maps -certain exceptions to custom responses. Configure it in the application -configuration as follows: +O pacote tem outro middleware, +`Yiisoft\ErrorHandler\Middleware\ExceptionResponder`. Esse middleware +mapeia certas exceções para respostas personalizadas. Configure-o na +configuração da aplicação assim: ```php use Psr\Http\Message\ResponseFactoryInterface; @@ -110,27 +113,27 @@ return [ ]; ``` -Note that when configuring application middleware stack, you must place -`Yiisoft\ErrorHandler\Middleware\ExceptionResponder` before +Ao configurar a pilha de middlewares da aplicação, você deve colocar +`Yiisoft\ErrorHandler\Middleware\ExceptionResponder` antes de `Yiisoft\ErrorHandler\Middleware\ErrorCatcher`. -## Rendering error data +## Renderizando os dados do erro -One of the renderers could render error data into a certain format. The -following renderers are available out of the box: +Cada renderer converte os dados do erro para um formato específico. Os +seguintes renderers já vêm prontos: -- `Yiisoft\ErrorHandler\Renderer\HeaderRenderer` - Renders error into HTTP - headers. It's used for `HEAD` request. -- `Yiisoft\ErrorHandler\Renderer\HtmlRenderer` - Renders error into HTML. -- `Yiisoft\ErrorHandler\Renderer\JsonRenderer` - Renders error into JSON. -- `Yiisoft\ErrorHandler\Renderer\PlainTextRenderer` - Renders error into - plain text. -- `Yiisoft\ErrorHandler\Renderer\XmlRenderer` - Renders error into XML. +- `Yiisoft\ErrorHandler\Renderer\HeaderRenderer` - Renderiza o erro em + headers HTTP. É usado em requisições `HEAD`. +- `Yiisoft\ErrorHandler\Renderer\HtmlRenderer` - Renderiza o erro em HTML. +- `Yiisoft\ErrorHandler\Renderer\JsonRenderer` - Renderiza o erro em JSON. +- `Yiisoft\ErrorHandler\Renderer\PlainTextRenderer` - Renderiza o erro em + texto puro. +- `Yiisoft\ErrorHandler\Renderer\XmlRenderer` - Renderiza o erro em XML. -The renderer produces detailed error data depending on whether debug mode is -enabled or disabled. +O renderer gera dados de erro mais ou menos detalhados conforme o modo debug +esteja ativado ou não. -An Example of header rendering with a debugging mode turned off: +Exemplo de renderização em headers com o modo debug desativado: ``` ... @@ -138,7 +141,7 @@ X-Error-Message: An internal server error occurred. ... ``` -An Example of header rendering with a debugging mode turned on: +Exemplo de renderização em headers com o modo debug ativado: ``` ... @@ -150,13 +153,13 @@ X-Error-Line: 21 ... ``` -Example of JSON rendering output with a debugging mode turned off: +Exemplo de saída JSON com o modo debug desativado: ```json {"message":"An internal server error occurred."} ``` -An Example of JSON rendering output with debugging mode turned on: +Exemplo de saída JSON com o modo debug ativado: ```json { @@ -183,32 +186,32 @@ An Example of JSON rendering output with debugging mode turned on: } ``` -Example of HTML rendering with debugging mode turned off: +Exemplo de renderização HTML com o modo debug desativado: -![View production](/images/guide/runtime/view-production.png) +![Tela de produção](/images/guide/runtime/view-production.png) -Example of HTML rendering with debugging mode on and a light theme: +Exemplo de renderização HTML com o modo debug ativado e tema claro: -![View development with light -theme](/images/guide/runtime/view-development-light.png) +![Tela de desenvolvimento com tema +claro](/images/guide/runtime/view-development-light.png) -Example of HTML rendering with debugging mode on and a dark theme: +Exemplo de renderização HTML com o modo debug ativado e tema escuro: -![View development with dark -theme](/images/guide/runtime/view-development-dark.png) +![Tela de desenvolvimento com tema +escuro](/images/guide/runtime/view-development-dark.png) -The error catcher chooses how to render an exception based on `accept` HTTP -header. If it's `text/html` or any unknown content type, it will use the -error or exception HTML template to display errors. For other mime types, -the error handler will choose different renderers registered in a renderer -provider. By default, it supports JSON, XML, and plain text. +O error catcher escolhe como renderizar uma exceção com base no header HTTP +`accept`. Se ele for `text/html` ou um tipo de conteúdo desconhecido, usa o +template HTML de erro ou de exceção para exibir os erros. Para outros mime +types, o error handler escolhe entre os renderers registrados em um renderer +provider. Por padrão, ele suporta JSON, XML e texto puro. -### Implementing your own renderer +### Implementando o seu próprio renderer -You may customize the error response format by implementing -`Yiisoft\ErrorHandler\ThrowableRendererInterface`. The renderer converts a -throwable into `Yiisoft\ErrorHandler\ErrorData`, which contains the response -body and headers. +Você pode personalizar o formato da resposta de erro implementando +`Yiisoft\ErrorHandler\ThrowableRendererInterface`. O renderer converte um +throwable em `Yiisoft\ErrorHandler\ErrorData`, que contém o corpo e os +headers da resposta. ```php use Psr\Http\Message\ServerRequestInterface; @@ -245,7 +248,7 @@ final readonly class MyRenderer implements ThrowableRendererInterface } ``` -Register the renderer in `config/common/di/error-handler.php`: +Registre o renderer em `config/common/di/error-handler.php`: ```php use Psr\Container\ContainerInterface; @@ -284,16 +287,17 @@ return [ ]; ``` -The `renderers` array maps `Accept` header content types to renderer class -names. When you provide this array, it replaces the default map, so include -the default renderer classes you still need. +O array `renderers` mapeia os tipos de conteúdo do header `Accept` para +nomes de classes de renderer. Quando você informa esse array, ele substitui +o mapa padrão, então inclua as classes de renderer padrão que ainda +precisar. -## Friendly exceptions +## Exceções amigáveis -Yii error renderer supports [friendly -exceptions](https://github.com/yiisoft/friendly-exception) that make error -handling an even more pleasant experience for your team. The idea is to -offer a readable name and possible solutions to the problem: +O renderer de erros do Yii suporta [exceções +amigáveis](https://github.com/yiisoft/friendly-exception), que deixam o +tratamento de erros ainda mais agradável para o seu time. A ideia é oferecer +um nome legível e possíveis soluções para o problema: ```php use Yiisoft\FriendlyException\FriendlyExceptionInterface; @@ -314,5 +318,5 @@ SOLUTION; } ``` -When the application throws such an exception, the error renderer would -display the name and the solution if the debug mode is on. +Quando a aplicação lança uma exceção desse tipo, o renderer de erros mostra +o nome e a solução se o modo debug estiver ativado. diff --git a/src/pt-BR/guide/runtime/logging.md b/src/pt-BR/guide/runtime/logging.md index b4b27193..d626cb84 100644 --- a/src/pt-BR/guide/runtime/logging.md +++ b/src/pt-BR/guide/runtime/logging.md @@ -1,49 +1,52 @@ -# Logging +# Logs -Yii relies on [PSR-3 interfaces](https://www.php-fig.org/psr/psr-3/) for -logging, so you could configure any PSR-3 compatible logging library to do -the actual job. +O Yii usa as [interfaces PSR-3](https://www.php-fig.org/psr/psr-3/) para +logs, então você pode configurar qualquer biblioteca de log compatível com a +PSR-3 para fazer o trabalho. -Yii provides its own logger that's highly customizable and extensible. -Using it, you can log various types of messages, filter them, and gather -them at different targets, such as files or emails. +O Yii oferece o seu próprio logger, que é bem personalizável e extensível. +Com ele, você pode registrar vários tipos de mensagens, filtrá-las e +reuni-las em destinos diferentes, como arquivos ou e-mails. -Using the Yii logging framework involves the following steps: +Usar o sistema de logs do Yii envolve os seguintes passos: -* Record [log messages](#log-messages) at various places in your code; -* Configure [log targets](#log-targets) in the application configuration to - filter and export log messages; -* Examine the filtered logged messages exported by different targets - (e.g. the Yii debugger). +* Registrar [mensagens de log](#mensagens-de-log) em vários pontos do + código; +* Configurar [destinos de log](#destinos-de-log) na configuração da + aplicação para filtrar e exportar as mensagens; +* Examinar as mensagens filtradas exportadas pelos diferentes destinos (por + exemplo, o debugger do Yii). -In this section, the focus in on the first two steps. +Esta seção foca nos dois primeiros passos. -## Default log destination +## Destino padrão dos logs -Yii3 application templates +Os templates de aplicação do Yii3 ([web](https://github.com/yiisoft/app/blob/master/config/common/di/logger.php) -and +e [API](https://github.com/yiisoft/app-api/blob/master/config/common/di/logger.php)) -configure `Yiisoft\Log\StreamTarget`, which writes to standard output -(`stdout`, or `php://stdout`) by default. They don't create application log -files, such as `runtime/logs/app.log`. `StreamTarget` also supports -standard error (`stderr`, or `php://stderr`), but you must configure it -explicitly. +configuram o `Yiisoft\Log\StreamTarget`, que por padrão escreve na saída +padrão (`stdout`, ou `php://stdout`). Eles não criam arquivos de log da +aplicação, como `runtime/logs/app.log`. O `StreamTarget` também suporta a +saída de erro padrão (`stderr`, ou `php://stderr`), mas você precisa +configurá-la explicitamente. -This works well with Docker, which [collects container output](https://docs.docker.com/engine/logging/). -Use `docker logs ` to read it when the container's logging driver supports that command. +Isso funciona bem com o Docker, que [coleta a saída dos containers](https://docs.docker.com/engine/logging/). +Use `docker logs ` para lê-la quando o driver de log do container suportar esse comando. -Without containers, the destination depends on how you start PHP and capture -its output. For example, PHP-FPM discards worker output by default unless -you enable `catch_workers_output`. See [web server logging -configuration](../../cookbook/configuring-webservers/general.md#application-logs). -To have Yii write application log files directly, configure a [file -target](#logging-to-files). +Sem containers, o destino depende de como você inicia o PHP e captura a +saída dele. Por exemplo, o PHP-FPM descarta a saída dos workers por padrão, +a menos que você ative `catch_workers_output`. Veja a [configuração de logs +do servidor +web](../../cookbook/configuring-webservers/general.md#application-logs). +Para o Yii escrever arquivos de log da aplicação diretamente, configure um +[destino em arquivo](#logs-em-arquivos). -## Log Messages +## Mensagens de log -To record log messages, you need an instance of PSR-3 logger. A class that -writes log messages should receive it as a dependency: +Para registrar mensagens de log, você precisa de uma instância de um logger +PSR-3. Uma classe que escreve mensagens de log deve recebê-lo como +dependência: ```php class MyService @@ -57,30 +60,29 @@ class MyService } ``` -Recording a log message is as simple as calling one of the following logging -methods that correspond to log levels: - -- `emergency` - System is unusable. -- `alert` - Action must be taken immediately. Example: Entire website down, - database unavailable, etc. This should trigger the SMS alerts and wake - you up. -- `critical` - Critical conditions. Example: Application component - unavailable, unexpected exception. -- `error` - Runtime errors that don't require immediate action but should - typically be logged and monitored. -- `warning` - Exceptional occurrences that aren't errors. Example: Use of - deprecated APIs, poor use of an API, undesirable things that aren't - necessarily wrong. -- `notice` - Normal but significant events. -- `info` - Interesting events. Example: User logs in, SQL logs. -- `debug` - Detailed debug information. - -Each method has two arguments. The first is a message. The Second is a -context array that typically has structured data that doesn't fit a message -well but still does offer important information. In case you provide an -exception as context, you should pass the "exception" key. Another special -key is "category." Categories are handy to better organize and filter log -messages. +Registrar uma mensagem de log é tão simples quanto chamar um dos métodos a +seguir, que correspondem aos níveis de log: + +- `emergency` - O sistema está inutilizável. +- `alert` - É preciso agir imediatamente. Exemplo: site inteiro fora do ar, + banco de dados indisponível etc. Isso deve disparar os alertas por SMS e + acordar você. +- `critical` - Condições críticas. Exemplo: componente da aplicação + indisponível, exceção inesperada. +- `error` - Erros em tempo de execução que não exigem ação imediata, mas + normalmente devem ser registrados e monitorados. +- `warning` - Ocorrências excepcionais que não são erros. Exemplo: uso de + APIs obsoletas, uso inadequado de uma API, coisas indesejáveis que não + estão necessariamente erradas. +- `notice` - Eventos normais, mas significativos. +- `info` - Eventos interessantes. Exemplo: login de usuário, logs de SQL. +- `debug` - Informações detalhadas de debug. + +Cada método tem dois argumentos. O primeiro é a mensagem. O segundo é um +array de contexto, que normalmente tem dados estruturados que não cabem bem +na mensagem, mas trazem informações importantes. Se você passar uma exceção +no contexto, use a chave "exception". Outra chave especial é "category". As +categorias ajudam a organizar e filtrar melhor as mensagens de log. ```php use \Psr\Log\LoggerInterface; @@ -100,37 +102,38 @@ final readonly class MyService } ``` -When deciding on a category for a message, you may choose a hierarchical -naming scheme, which will make it easier for [log targets](#log-targets) to -filter messages based on their categories. A simple yet effective naming -scheme is to use the PHP magic constant `__METHOD__` for the category -names. This is also the approach used in the core Yii framework code. +Ao escolher a categoria de uma mensagem, você pode adotar um esquema de +nomes hierárquico, o que facilita para os [destinos de +log](#destinos-de-log) filtrarem as mensagens pela categoria. Um esquema +simples e eficaz é usar a constante mágica do PHP `__METHOD__` como nome da +categoria. Essa também é a abordagem usada no código do core do Yii. -The `__METHOD__` constant evaluates as the name of the method (prefixed with -the fully qualified class name) where the constant appears. For example, -it's equal to the string `'App\\Service\\MyService::serve'` if the above -line of code is called within this method. +A constante `__METHOD__` resulta no nome do método (prefixado com o nome +completo da classe) onde ela aparece. Por exemplo, ela é igual à string +`'App\\Service\\MyService::serve'` se a linha de código acima for chamada +dentro desse método. > [!IMPORTANT] -> The logging methods described above are actually shortcuts to the [[\Psr\Log\LoggerInterface::log()]]. +> Os métodos de log descritos acima são, na verdade, atalhos para [[\Psr\Log\LoggerInterface::log()]]. -Note that PSR-3 package provides `\Psr\Log\NullLogger` class that provides -the same set of methods but doesn't log anything. That means that you don't -have to check if logger is configured with `if ($logger !== null)` and, -instead, can assume that logger is always present. +O pacote PSR-3 tem a classe `\Psr\Log\NullLogger`, que oferece o mesmo +conjunto de métodos, mas não registra nada. Isso significa que você não +precisa verificar se o logger está configurado com `if ($logger !== null)` e +pode assumir que o logger sempre existe. -## Log targets +## Destinos de log -A log target is an instance of a class that extends the -[[\Yiisoft\Log\Target]]. It filters the log messages by their severity -levels and categories and then exports them to some medium. For example, a -[[\Yiisoft\Log\Target\File\FileTarget|file target]]exports the filtered log -messages to a file, while a [[Yiisoft\Log\Target\Email\EmailTarget|email -target]] exports the log messages to specified email addresses. +Um destino de log é uma instância de uma classe que estende +[[\Yiisoft\Log\Target]]. Ele filtra as mensagens de log pelo nível de +severidade e pela categoria e depois as exporta para algum meio. Por +exemplo, um [[\Yiisoft\Log\Target\File\FileTarget|destino em arquivo]] +exporta as mensagens filtradas para um arquivo, enquanto um +[[Yiisoft\Log\Target\Email\EmailTarget|destino por e-mail]] exporta as +mensagens para os endereços de e-mail definidos. -You can register many log targets in an application by configuring them -through the `\Yiisoft\Log\Logger` constructor: +Você pode registrar vários destinos de log em uma aplicação configurando-os +no construtor de `\Yiisoft\Log\Logger`: ```php use \Psr\Log\LogLevel; @@ -148,37 +151,40 @@ $logger = new \Yiisoft\Log\Logger([ ]); ``` -In the above code, two log targets are registered: +No código acima, dois destinos de log são registrados: -* the first target selects error and warning messages and writes them to - `/path/to/app.log` file; -* the second target selects emergency, alert, and critical messages under the categories whose names start with -`Yiisoft\Cache\`, and sends them in an email to both `admin@example.com` and `developer@example.com`. +* o primeiro seleciona as mensagens de erro e de warning e as grava no + arquivo `/path/to/app.log`; +* o segundo seleciona as mensagens de emergency, alert e critical das categorias cujos nomes começam com +`Yiisoft\Cache\` e as envia por e-mail para `admin@example.com` e `developer@example.com`. -Yii comes with the following built-in log targets. Please refer to the API -documentation about these classes to learn how to configure and use them. +O Yii vem com os seguintes destinos de log embutidos. Consulte a +documentação da API dessas classes para saber como configurá-los e usá-los. -* [[\Yiisoft\Log\PsrTarget]]: passes log messages to another PSR-3 - compatible logger. -* [[\Yiisoft\Log\StreamTarget]]: writes log messages into a specified output - stream. -* [[\Yiisoft\Log\Target\Db\DbTarget]]: saves log messages in database. -* [[\Yiisoft\Log\Target\Email\EmailTarget]]: sends log messages to - pre-specified email addresses. -* [[\Yiisoft\Log\Target\File\FileTarget]]: saves log messages in files. -* [[\Yiisoft\Log\Target\Syslog\SyslogTarget]]: saves log messages to syslog - by calling the PHP function `syslog()`. +* [[\Yiisoft\Log\PsrTarget]]: repassa as mensagens de log para outro logger + compatível com a PSR-3. +* [[\Yiisoft\Log\StreamTarget]]: escreve as mensagens de log em um stream de + saída definido. +* [[\Yiisoft\Log\Target\Db\DbTarget]]: salva as mensagens de log no banco de + dados. +* [[\Yiisoft\Log\Target\Email\EmailTarget]]: envia as mensagens de log para + endereços de e-mail definidos. +* [[\Yiisoft\Log\Target\File\FileTarget]]: salva as mensagens de log em + arquivos. +* [[\Yiisoft\Log\Target\Syslog\SyslogTarget]]: salva as mensagens de log no + syslog chamando a função PHP `syslog()`. -### Logging to files +### Logs em arquivos -To write application logs to a file, install the file target package: +Para gravar os logs da aplicação em um arquivo, instale o pacote do destino +em arquivo: ```shell composer require yiisoft/log-target-file ``` -In your application's `config/common/di/logger.php`, replace the -`StreamTarget` reference with `FileTarget`: +No `config/common/di/logger.php` da sua aplicação, troque a referência ao +`StreamTarget` por `FileTarget`: ```php use Psr\Log\LoggerInterface; @@ -198,16 +204,17 @@ return [ ]; ``` -The package's default configuration writes to `@runtime/logs/app.log` and -enables log rotation. To change the path, set -`$params['yiisoft/log-target-file']['fileTarget']['file']` in -`config/common/params.php`. Ensure that the PHP process can write to the -log directory, and keep it outside the web server's document root. +A configuração padrão do pacote grava em `@runtime/logs/app.log` e ativa a +rotação de logs. Para mudar o caminho, defina +`$params['yiisoft/log-target-file']['fileTarget']['file']` em +`config/common/params.php`. Garanta que o processo do PHP consiga escrever +no diretório de logs e mantenha esse diretório fora do document root do +servidor web. -The file target package's default configuration also filters out `alert`, -`critical`, and `notice` messages. The templates' `StreamTarget` accepts -all eight log levels. To keep that behavior, add the following entry to the -array that `config/common/params.php` returns: +A configuração padrão do pacote de destino em arquivo também descarta as +mensagens `alert`, `critical` e `notice`. O `StreamTarget` dos templates +aceita os oito níveis de log. Para manter esse comportamento, adicione a +seguinte entrada ao array retornado por `config/common/params.php`: ```php use Psr\Log\LogLevel; @@ -231,37 +238,37 @@ return [ ]; ``` -In the following, we will describe the features common to all log targets. +A seguir, descrevemos os recursos comuns a todos os destinos de log. -### Message Filtering +### Filtragem de mensagens -For each log target, you can configure its levels and categories to specify -which severity levels and categories of the messages the target should -process. +Para cada destino de log, você pode configurar os níveis e as categorias, +definindo quais níveis de severidade e quais categorias de mensagens o +destino deve processar. -The target `setLevels()` method takes an array consisting of one or several -of `\Psr\Log\LogLevel` constants. +O método `setLevels()` do destino recebe um array com uma ou mais constantes +de `\Psr\Log\LogLevel`. -By default, the target will process messages of *any* severity level. +Por padrão, o destino processa mensagens de *qualquer* nível de severidade. -The target `setCategories()` method takes an array consisting of message -category names or patterns. A target will only process messages whose -category can be found or match one of the patterns in this array. A -category pattern is a category name prefix with an asterisk `*` at its -end. A category name matches a category pattern if it starts with the same -prefix of the pattern. For example, `Yiisoft\Cache\Cache::set` and -`Yiisoft\Cache\Cache::get` both match the pattern `Yiisoft\Cache\*`. +O método `setCategories()` do destino recebe um array com nomes ou padrões +de categorias de mensagens. O destino só processa as mensagens cuja +categoria esteja no array ou case com um dos padrões dele. Um padrão de +categoria é um prefixo de nome de categoria com um asterisco `*` no +final. Um nome de categoria casa com o padrão se começar com o mesmo +prefixo. Por exemplo, `Yiisoft\Cache\Cache::set` e +`Yiisoft\Cache\Cache::get` casam com o padrão `Yiisoft\Cache\*`. -By default, the target will process messages of *any* category. +Por padrão, o destino processa mensagens de *qualquer* categoria. -Besides allowing the categories by the `setCategories()` method, you may -also deny certain categories by the `setExcept()` method. If the category -of a message is found or matches one of the patterns in this property, the -target will NOT process it. +Além de permitir categorias com o método `setCategories()`, você também pode +negar certas categorias com o método `setExcept()`. Se a categoria de uma +mensagem estiver nessa lista ou casar com um dos padrões dela, o destino NÃO +vai processá-la. -The following target configuration specifies that the target should only -process error and warning messages under the categories whose names match -either `Yiisoft\Cache\*` or `App\Exceptions\HttpException:*`, but not +A configuração a seguir define que o destino só deve processar mensagens de +erro e de warning das categorias cujos nomes casem com `Yiisoft\Cache\*` ou +`App\Exceptions\HttpException:*`, mas não com `App\Exceptions\HttpException:404`. ```php @@ -271,12 +278,12 @@ $fileTarget->setCategories(['Yiisoft\Cache\*', 'App\Exceptions\HttpException:*'] $fileTarget->setExcept(['App\Exceptions\HttpException:404']); ``` -### Message Formatting +### Formatação de mensagens -Log targets export the filtered log messages in a certain format. For -example, if you install a log target of the class -[[\Yiisoft\Log\Target\File\FileTarget]], you may find a log message similar -to the following in the log file: +Os destinos de log exportam as mensagens filtradas em um certo formato. Por +exemplo, se você instalar um destino de log da classe +[[\Yiisoft\Log\Target\File\FileTarget]], pode encontrar no arquivo de log +uma mensagem parecida com esta: ``` 2020-12-05 09:27:52.223800 [info][application] Some message @@ -288,15 +295,15 @@ memory: 4398536 category: 'application' ``` -By default, log messages have the following format: +Por padrão, as mensagens de log têm o seguinte formato: ``` Timestamp Prefix[Level][Category] Message Context ``` -You may customize this format by calling -[[\Yiisoft\Log\Target::setFormat()|setFormat()]] method, which takes a PHP -callable returning a custom-formatted message. +Você pode personalizar esse formato chamando o método +[[\Yiisoft\Log\Target::setFormat()|setFormat()]], que recebe um callable PHP +que retorna a mensagem formatada. ```php $fileTarget = new \Yiisoft\Log\Target\File\FileTarget('/path/to/app.log'); @@ -313,13 +320,14 @@ $logger->info('Text message', ['category' => 'app']); // (APP) [info] Text message ``` -In addition, if you're comfortable with the default message format but need -to change the timestamp format or add custom data to the message, you can -call the [[\Yiisoft\Log\Target::setTimestampFormat()|setTimestampFormat()]] -and [[\Yiisoft\Log\Target::setPrefix()|setPrefix()]] methods. For example, -the following code changes the timestamp format and configures a log target -to prefix each log message with the current user ID (IP address and Session -ID are removed for privacy reasons). +Além disso, se o formato padrão da mensagem servir para você, mas for +preciso mudar o formato do timestamp ou adicionar dados à mensagem, você +pode chamar os métodos +[[\Yiisoft\Log\Target::setTimestampFormat()|setTimestampFormat()]] e +[[\Yiisoft\Log\Target::setPrefix()|setPrefix()]]. Por exemplo, o código a +seguir muda o formato do timestamp e configura um destino de log para +prefixar cada mensagem com o ID do usuário atual (o endereço IP e o ID da +sessão foram removidos por questões de privacidade). ```php $fileTarget = new \Yiisoft\Log\Target\File\FileTarget('/path/to/app.log'); @@ -339,20 +347,19 @@ $logger->info('Text', ['category' => 'user']); // Common context: ... ``` -The PHP callable that's passed to the -[[\Yiisoft\Log\Target::setFormat()|setFormat()]] and -[[\Yiisoft\Log\Target::setPrefix()|setPrefix()]] methods has the following -signature: +O callable PHP passado para os métodos +[[\Yiisoft\Log\Target::setFormat()|setFormat()]] e +[[\Yiisoft\Log\Target::setPrefix()|setPrefix()]] tem a seguinte assinatura: ```php function (\Yiisoft\Log\Message $message, array $commonContext): string; ``` -Besides message prefixes, log targets also append some common context information to each of the log messages. -You may adjust this behavior by calling target [[\Yiisoft\Log\Target::setCommonContext()|setCommonContext()]] -method, passing an array of data in the `key => value` format that you want to include. -For example, the following log target configuration specifies that only the -value of the `$_SERVER` variable will be appended to the log messages. +Além dos prefixos, os destinos de log também acrescentam algumas informações de contexto comuns a cada mensagem de log. +Você pode ajustar esse comportamento chamando o método [[\Yiisoft\Log\Target::setCommonContext()|setCommonContext()]] +do destino, passando um array de dados no formato `key => value` com o que você quer incluir. +Por exemplo, a configuração de destino a seguir define que apenas o +valor da variável `$_SERVER` será acrescentado às mensagens de log. ```php $fileTarget = new \Yiisoft\Log\Target\File\FileTarget('/path/to/app.log'); @@ -360,24 +367,22 @@ $fileTarget->setCommonContext(['server' => $_SERVER]); ``` -### Message Trace Level +### Nível de trace das mensagens -During development, it's often desirable to see where each log message is -coming from. You can achieve this by calling the -[[\Yiisoft\Log\Logger::setTraceLevel()|setTraceLevel()]] method like the -following: +Durante o desenvolvimento, muitas vezes é útil ver de onde vem cada mensagem +de log. Você pode fazer isso chamando o método +[[\Yiisoft\Log\Logger::setTraceLevel()|setTraceLevel()]] assim: ```php $logger = new \Yiisoft\Log\Logger($targets); $logger->setTraceLevel(3); ``` -This application configuration sets the trace level to be 3, so each log -message will be appended with at most three levels of the call stack at -which the log message is recorded. You can also set a list of paths to -exclude from the trace by calling the -[[\Yiisoft\Log\Logger::setExcludedTracePaths()|setExcludedTracePaths()]] -method. +Essa configuração define o nível de trace como 3, então cada mensagem de log +recebe no máximo três níveis da pilha de chamadas do ponto em que a mensagem +foi registrada. Você também pode definir uma lista de caminhos a excluir do +trace chamando o método +[[\Yiisoft\Log\Logger::setExcludedTracePaths()|setExcludedTracePaths()]]. ```php $logger = new \Yiisoft\Log\Logger($targets); @@ -385,18 +390,18 @@ $logger->setExcludedTracePaths(['/path/to/file', '/path/to/folder']); ``` > [!IMPORTANT] -> Getting call stack information isn't trivial. Therefore, you should only use this feature during development -or when debugging an application. +> Obter informações da pilha de chamadas não é trivial. Por isso, use esse recurso apenas durante o desenvolvimento +ou ao depurar uma aplicação. -### Message flushing and exporting +### Envio (flush) e exportação de mensagens -As aforementioned, log messages are maintained in an array by -[[\Yiisoft\Log\Logger|logger object]]. To limit the memory consumption by -this array, the logger will flush the recorded messages to the [log -targets](#log-targets) each time the array accumulates a certain number of -log messages. You can customize this number by calling the -[[\Yiisoft\Log\Logger::setFlushInterval()]] method: +Como dito acima, as mensagens de log ficam em um array no +[[\Yiisoft\Log\Logger|objeto logger]]. Para limitar o consumo de memória +desse array, o logger envia as mensagens registradas para os [destinos de +log](#destinos-de-log) sempre que o array acumula um certo número de +mensagens. Você pode personalizar esse número chamando o método +[[\Yiisoft\Log\Logger::setFlushInterval()]]: ```php @@ -405,26 +410,26 @@ $logger->setFlushInterval(100); // default is 1000 ``` > [!IMPORTANT] -> Message flushing also occurs when the application ends, -which ensures log targets can receive complete log messages. +> O envio das mensagens também acontece quando a aplicação termina, +o que garante que os destinos de log recebam as mensagens completas. -When the [[\Yiisoft\Log\Logger|logger object]] flushes log messages to [log targets](#log-targets), -they don't get exported immediately. Instead, the message exporting only occurs when a log target - accumulates a certain number of the filtered messages. You can customize this number by calling the -[[\Yiisoft\Log\Target::setExportInterval()|setExportInterval()]] method of individual -[log targets](#log-targets), like the following: +Quando o [[\Yiisoft\Log\Logger|objeto logger]] envia as mensagens para os [destinos de log](#destinos-de-log), +elas não são exportadas imediatamente. A exportação só acontece quando um destino de log + acumula um certo número de mensagens filtradas. Você pode personalizar esse número chamando o método +[[\Yiisoft\Log\Target::setExportInterval()|setExportInterval()]] de cada +[destino de log](#destinos-de-log), assim: ```php $fileTarget = new \Yiisoft\Log\Target\File\FileTarget('/path/to/app.log'); $fileTarget->setExportInterval(100); // default is 1000 ``` -Because of the flushing and exporting level setting, by default when you -call any logging method, you will NOT see the log message immediately in the -log targets. This could be a problem for some long-running console -applications. To make each log message appear immediately in the log -targets, you should set both flush interval and export interval to be 1, as -shown below: +Por causa dessas configurações de envio e exportação, por padrão, quando +você chama qualquer método de log, NÃO vai ver a mensagem imediatamente nos +destinos de log. Isso pode ser um problema em aplicações de console de longa +duração. Para que cada mensagem apareça imediatamente nos destinos de log, +defina tanto o intervalo de envio quanto o de exportação como 1, como +mostrado abaixo: ```php $fileTarget = new \Yiisoft\Log\Target\File\FileTarget('/path/to/app.log'); @@ -435,15 +440,16 @@ $logger->setFlushInterval(1); ``` > [!NOTE] -> Frequent message flushing and exporting will degrade the performance of your application. +> Enviar e exportar mensagens com frequência piora o desempenho da sua aplicação. -### Toggling log targets +### Ativando e desativando destinos de log -You can enable or disable a log target by calling its -[[\Yiisoft\Log\Target::enable()|enable()] ] and -[[\Yiisoft\Log\Target::disable()|disable()]] methods. You may do so via the -log target configuration or by the following PHP statement in your code: +Você pode ativar ou desativar um destino de log chamando os métodos +[[\Yiisoft\Log\Target::enable()|enable()] ] e +[[\Yiisoft\Log\Target::disable()|disable()]]. Você pode fazer isso na +configuração do destino de log ou com a seguinte instrução PHP no seu +código: ```php $fileTarget = new \Yiisoft\Log\Target\File\FileTarget('/path/to/app.log'); @@ -456,33 +462,36 @@ foreach ($logger->getTargets() as $target) { } ``` -To check whether the log target is enabled, call the `isEnabled()` method. -You also may pass callable to -[[\Yiisoft\Log\Target::setEnabled()|setEnabled()]] to define a dynamic -condition for whether the log target should be enabled or not. +Para verificar se o destino de log está ativado, chame o método +`isEnabled()`. Você também pode passar um callable para +[[\Yiisoft\Log\Target::setEnabled()|setEnabled()]] para definir uma condição +dinâmica que diz se o destino de log deve estar ativado ou não. -### Creating new targets +### Criando novos destinos -Creating a new log target class is straightforward. You mainly need to -implement the [[\Yii\Log\Target::export()]] abstract method that sends all -accumulated log messages to a designated medium. +Criar uma nova classe de destino de log é simples. Basicamente, você precisa +implementar o método abstrato [[\Yii\Log\Target::export()]], que envia todas +as mensagens de log acumuladas para um meio definido. -The following protected methods will also be available for child targets: +Os seguintes métodos protegidos também ficam disponíveis para os destinos +filhos: -- `getMessages` - Get a list of log messages ([[\Yii\Log\Message]] - instances). -- `getFormattedMessages` - Get a list of log messages formatted as strings. -- `formatMessages` - Get all log messages formatted as a string. -- `getCommonContext` - Get an array with common context data in the `key => - value` format. +- `getMessages` - Retorna uma lista de mensagens de log (instâncias de + [[\Yii\Log\Message]]). +- `getFormattedMessages` - Retorna uma lista de mensagens de log formatadas + como strings. +- `formatMessages` - Retorna todas as mensagens de log formatadas como uma + string. +- `getCommonContext` - Retorna um array com os dados de contexto comuns no + formato `key => value`. -For more details, you may refer to any of the log target classes included in -the package. +Para mais detalhes, consulte qualquer uma das classes de destino de log +incluídas no pacote. > [!TIP] -> Instead of creating your own loggers, you may try any PSR-3 compatible logger such -as [Monolog](https://github.com/Seldaek/monolog) by using [[\Yii\Log\PsrTarget]]. +> Em vez de criar os seus próprios loggers, você pode experimentar qualquer logger compatível com a PSR-3, como +o [Monolog](https://github.com/Seldaek/monolog), usando [[\Yii\Log\PsrTarget]]. ```php /** diff --git a/src/pt-BR/guide/runtime/request.md b/src/pt-BR/guide/runtime/request.md index bd8ffae6..da3eeef7 100644 --- a/src/pt-BR/guide/runtime/request.md +++ b/src/pt-BR/guide/runtime/request.md @@ -1,6 +1,7 @@ -# Request +# Requisição -HTTP request has a method, URI, a set of headers and a body: +Uma requisição HTTP tem um método, uma URI, um conjunto de headers e um +corpo: ``` POST /contact HTTP/1.1 @@ -14,13 +15,13 @@ Accept-Encoding: gzip, deflate } ``` -The method is `POST`, URI is `/contact`. Extra headers are specifying host, -preferred language and encoding. The body could be anything. In this case, -it's a JSON payload. +O método é `POST` e a URI é `/contact`. Os headers extras informam o host, +o idioma preferido e a codificação. O corpo pode ser qualquer coisa. Neste +caso, é um payload JSON. -Yii uses [PSR-7 `ServerRequest`](https://www.php-fig.org/psr/psr-7/) as -request representation. The object is available in controller actions and -other types of middleware: +O Yii usa o [`ServerRequest` da PSR-7](https://www.php-fig.org/psr/psr-7/) +para representar a requisição. O objeto está disponível nas actions de +controllers e em outros tipos de middleware: ```php public function view(ServerRequestInterface $request): ResponseInterface @@ -29,15 +30,15 @@ public function view(ServerRequestInterface $request): ResponseInterface } ``` -## Method +## Método -The method could be obtained from a request object: +O método pode ser obtido do objeto de requisição: ```php $method = $request->getMethod(); ``` -Usually it's one of the: +Normalmente ele é um destes: - GET - POST @@ -47,8 +48,8 @@ Usually it's one of the: - PATCH - OPTIONS -In case you want to make sure the request method is of a certain type, there -is a special class with method names: +Se você quiser garantir que o método da requisição é de um tipo específico, +existe uma classe especial com os nomes dos métodos: ```php use Yiisoft\Http\Method; @@ -60,22 +61,22 @@ if ($request->getMethod() === Method::POST) { ## URI -A URI has: +Uma URI tem: -- Scheme (`http`, `https`) +- Esquema (`http`, `https`) - Host (`yiiframework.com`) -- Port (`80`, `443`) -- Path (`/posts/1`) +- Porta (`80`, `443`) +- Caminho (`/posts/1`) - Query string (`page=1&sort=+id`) -- Fragment (`#anchor`) +- Fragmento (`#anchor`) -You can obtain `UriInterface` from request like the following: +Você pode obter a `UriInterface` da requisição assim: ```php $uri = $request->getUri(); ``` -Then you can get various details from its methods: +Depois, pode obter vários detalhes pelos métodos dela: - `getScheme()` - `getAuthority()` @@ -88,8 +89,8 @@ Then you can get various details from its methods: ## Headers -There are various methods to inspect request headers. To get all headers as -an array: +Há vários métodos para inspecionar os headers da requisição. Para obter +todos os headers como array: ```php $headers = $request->getHeaders(); @@ -98,15 +99,15 @@ foreach ($headers as $name => $values) { } ``` -To get a single header: +Para obter um único header: ```php $values = $request->getHeader('Accept-Encoding'); ``` -Also, you could get value as a comma-separated string instead of an array. -That's especially handy if a header has a single value: +Você também pode obter o valor como uma string separada por vírgulas em vez +de um array. Isso é bem prático quando o header tem um único valor: ```php if ($request->getHeaderLine('X-Requested-With') === 'XMLHttpRequest') { @@ -115,7 +116,7 @@ if ($request->getHeaderLine('X-Requested-With') === 'XMLHttpRequest') { } ``` -To check if a header is present in the request: +Para verificar se um header está presente na requisição: ```php if ($request->hasHeader('Accept-Encoding')) { @@ -123,25 +124,25 @@ if ($request->hasHeader('Accept-Encoding')) { } ``` -## Body +## Corpo -There are two methods to get body contents. The first is getting the body as -it is without parsing: +Há dois métodos para obter o conteúdo do corpo. O primeiro retorna o corpo +como está, sem parsing: ```php $body = $request->getBody(); ``` -The `$body` would be an instance of `Psr\Http\Message\StreamInterface`. +`$body` será uma instância de `Psr\Http\Message\StreamInterface`. -Also, you could get a parsed body: +Você também pode obter o corpo já interpretado: ```php $bodyParameters = $request->getParsedBody(); ``` -Parsing depends on PSR-7 implementation and may require middleware for -custom body formats. +O parsing depende da implementação da PSR-7 e pode exigir um middleware para +formatos de corpo personalizados. ```php getUploadedFiles(); @@ -182,19 +184,19 @@ foreach ($files as $file) { } ``` -Always validate the upload before reading the stream or moving the file. The -file may be missing, too large for PHP configuration, only partially -uploaded, rejected by a PHP extension, or not match the file type and size -your application expects. Yii Validator provides the -`Yiisoft\Validator\Rule\File` rule for this. It accepts PSR-7 -`UploadedFileInterface` values and validates upload error codes, extension, -MIME type, and size. Use `Yiisoft\Validator\Rule\Each` when a field contains -several files. +Sempre valide o upload antes de ler o stream ou mover o arquivo. O arquivo +pode estar ausente, ser grande demais para a configuração do PHP, ter sido +enviado só em parte, ter sido rejeitado por uma extensão do PHP ou não +corresponder ao tipo e ao tamanho que a sua aplicação espera. O Yii +Validator oferece a regra `Yiisoft\Validator\Rule\File` para isso. Ela +aceita valores `UploadedFileInterface` da PSR-7 e valida os códigos de erro +do upload, a extensão, o tipo MIME e o tamanho. Use +`Yiisoft\Validator\Rule\Each` quando um campo tiver vários arquivos. -The following example handles a single `avatar` upload. It validates the -uploaded file with Yii Validator, stores the file outside the public -directory, and generates its own file name instead of trusting the -client-provided name. +O exemplo a seguir trata o upload de um único `avatar`. Ele valida o arquivo +enviado com o Yii Validator, guarda o arquivo fora do diretório público e +gera o próprio nome do arquivo em vez de confiar no nome informado pelo +cliente. ```php withStatus(Status::NOT_FOUND); ``` -Majority of status codes are available from `Status` class for convenience -and readability. +A maioria dos códigos de status está disponível na classe `Status`, por +conveniência e legibilidade. -Router may return a response before an action runs. For example, an -`OPTIONS` request to a known route path gets an automatic `204 No Content` -response with an `Allow` header that lists supported methods. See -[Automatic OPTIONS responses](routing.md#automatic-options-responses) for -routing details. +O router pode retornar uma resposta antes de a action rodar. Por exemplo, +uma requisição `OPTIONS` para o caminho de uma rota conhecida recebe +automaticamente uma resposta `204 No Content` com um header `Allow` listando +os métodos suportados. Veja [Respostas OPTIONS +automáticas](routing.md#respostas-options-automaticas) para os detalhes de +roteamento. ## Headers -You can set headers like this: +Você pode definir headers assim: ```php $response = $response->withHeader('Content-type', 'application/json'); ``` -If there is a need to append a header value to the existing header: +Se for preciso acrescentar um valor a um header existente: ```php $response = $response->withAddedHeader('Set-Cookie', 'qwerty=219ffwef9w0f; Domain=somecompany.co.uk; Path=/; Expires=Wed, 30 Aug 2019 00:00:00 GMT'); ``` -And, if needed, headers could be removed: +E, se necessário, os headers podem ser removidos: ```php $response = $response->withoutHeader('Set-Cookie'); ``` -## Body +## Corpo -Response body is an object implementing `Psr\Http\Message\StreamInterface`. +O corpo da resposta é um objeto que implementa +`Psr\Http\Message\StreamInterface`. -You can write to it via the interface itself: +Você pode escrever nele pela própria interface: ```php $body = $response->getBody(); @@ -94,9 +97,9 @@ $body->write('Hello'); ``` -## Examples +## Exemplos -### Redirecting +### Redirecionando ```php use Yiisoft\Http\Status; @@ -106,17 +109,17 @@ return $response ->withHeader('Location', 'https://www.example.com'); ``` -Note that there are different statuses used for redirection: +Existem status diferentes usados para redirecionamento: -| Code | Usage | What is it for | -|------|------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| 301 | `Status::MOVED_PERMANENTLY` | Permanently changed a URL structure. Search engines update their indexes, and browsers cache it. | -| 308 | `Status::PERMANENT_REDIRECT` | Like 301, but guarantees the HTTP method won't change. | -| 302 | `Status::FOUND` | Temporary changes like maintenance pages. Original URL should still be used for future requests. Search engines typically don't update their indexes. | -| 307 | `Status::TEMPORARY_REDIRECT` | Like 302, but guarantees the HTTP method won't change. | -| 303 | `Status::SEE_OTHER` | After form submissions to prevent duplicate submissions if the user refreshes. Explicitly tells to use `GET` for the redirect, even if the original request was `POST`. | +| Código | Constante | Para que serve | +|--------|------------------------------|----------------| +| 301 | `Status::MOVED_PERMANENTLY` | Mudança permanente na estrutura de URLs. Os mecanismos de busca atualizam os índices e os navegadores guardam em cache. | +| 308 | `Status::PERMANENT_REDIRECT` | Como o 301, mas garante que o método HTTP não muda. | +| 302 | `Status::FOUND` | Mudanças temporárias, como páginas de manutenção. A URL original ainda deve ser usada nas próximas requisições. Os mecanismos de busca normalmente não atualizam os índices. | +| 307 | `Status::TEMPORARY_REDIRECT` | Como o 302, mas garante que o método HTTP não muda. | +| 303 | `Status::SEE_OTHER` | Depois do envio de formulários, para evitar envios duplicados se o usuário recarregar a página. Indica explicitamente que o redirecionamento deve usar `GET`, mesmo que a requisição original tenha sido `POST`. | -### Responding with JSON +### Respondendo com JSON ```php use Yiisoft\Http\Status; diff --git a/src/pt-BR/guide/runtime/routing.md b/src/pt-BR/guide/runtime/routing.md index 55940f32..959142eb 100644 --- a/src/pt-BR/guide/runtime/routing.md +++ b/src/pt-BR/guide/runtime/routing.md @@ -1,23 +1,23 @@ -# Routing and URL generation +# Roteamento e geração de URLs -Usually, a Yii application processes certain requests with certain -handlers. It selects a handler based on the request URL. The part of the -application that does the job is a router, and the process of selecting a -handler, instantiating it and running a handler method is *routing*. +Normalmente, uma aplicação Yii processa certas requisições com certos +handlers. Ela escolhe o handler com base na URL da requisição. A parte da +aplicação que faz esse trabalho é o router, e o processo de escolher um +handler, instanciá-lo e executar um método dele é o *roteamento*. -The reverse process of routing is *URL generation*, which creates a URL from -a given named route, route arguments, and query parameters. When you later -request the created URL, the routing process can resolve it back into the -original route arguments and query parameters. +O processo inverso do roteamento é a *geração de URLs*, que cria uma URL a +partir de uma rota nomeada, de argumentos de rota e de parâmetros de query. +Quando você requisita depois a URL criada, o roteamento consegue convertê-la +de volta nos argumentos de rota e parâmetros de query originais. -Routing and URL generation are separate services, but they use a common set -of routes for both URL matching and URL generation. +Roteamento e geração de URLs são serviços separados, mas usam o mesmo +conjunto de rotas tanto para casar URLs quanto para gerá-las. -## Configuring routes +## Configurando rotas -By configuring routes, you can let your application recognize arbitrary URL -formats without modifying your existing application code. You can configure -routes in `/config/routes.php`. The structure of the file is the following: +Configurando rotas, você faz a aplicação reconhecer formatos arbitrários de +URL sem modificar o código existente. Você pode configurar as rotas em +`/config/routes.php`. A estrutura do arquivo é a seguinte: ```php generate( @@ -384,27 +386,28 @@ $url = $urlGenerator->generate( // $url is "/test/submit/42?page=1&utm=newsletter". ``` -If you need absolute URL, use `generateAbsolute()` instead. +Se você precisar de uma URL absoluta, use `generateAbsolute()`. -### Generating URL from the current route +### Gerando a URL a partir da rota atual -Use `generateFromCurrent()` when a link should keep the current route and -most of its arguments. For example, a detail page can link to another page -number while keeping the current route name and `id` argument: +Use `generateFromCurrent()` quando um link deve manter a rota atual e a +maior parte dos seus argumentos. Por exemplo, uma página de detalhes pode +apontar para outro número de página mantendo o nome da rota atual e o +argumento `id`: ```php $url = $urlGenerator->generateFromCurrent(['page' => '2']); ``` -The method also keeps query parameters from the current request. Pass -explicit query parameters when a link should replace or add query string -values. +O método também mantém os parâmetros de query da requisição atual. Passe +parâmetros de query explícitos quando o link precisar substituir ou +adicionar valores na query string. -### Locale-based URLs +### URLs com locale -When the locale is part of the URL path, define it as a route argument. For -a Yii application with routes in `config/common/routes.php`, wrap localized -routes in a group with a locale parameter: +Quando o locale faz parte do caminho da URL, defina-o como um argumento de +rota. Em uma aplicação Yii com as rotas em `config/common/routes.php`, +coloque as rotas localizadas em um grupo com um parâmetro de locale: ```php generate('post/view', ['slug' => 'welcome']); // On a German page, $url is "/de/posts/welcome". ``` -For a language switcher, use `generateFromCurrent()` and replace only the -locale argument: +Para um seletor de idioma, use `generateFromCurrent()` e substitua apenas o +argumento de locale: ```php $url = $urlGenerator->generateFromCurrent( @@ -513,50 +516,49 @@ $url = $urlGenerator->generateFromCurrent( ); ``` -## Route patterns +## Padrões de rota -Route patterns used depend on the underlying implementation used. The -default implementation is +Os padrões de rota dependem da implementação usada por baixo. A +implementação padrão é o [nikic/FastRoute](https://github.com/nikic/FastRoute). -Basic patterns are static like `/test`. That means they must match exactly -in order for a route match. +Os padrões básicos são estáticos, como `/test`. Isso significa que eles +precisam casar exatamente para a rota ser escolhida. -### Named Parameters +### Parâmetros nomeados -A pattern can include one or more named parameters which are specified in -the pattern in the format of `{ParamName:RegExp}`, where `ParamName` -specifies the parameter name and `RegExp` is an optional regular expression -used to match parameter values. If `RegExp` isn't specified, it means the -parameter value should be a string without any slash. +Um padrão pode ter um ou mais parâmetros nomeados, escritos no formato +`{ParamName:RegExp}`, onde `ParamName` é o nome do parâmetro e `RegExp` é +uma expressão regular opcional usada para casar o valor. Se `RegExp` não +for informada, o valor do parâmetro deve ser uma string sem barras. > [!NOTE] -> You can only use regular expressions inside parameters. The rest of the pattern is considered plain text. +> Você só pode usar expressões regulares dentro dos parâmetros. O resto do padrão é tratado como texto puro. -You can't use capturing groups. For example `{lang:(en|de)}` isn't a valid -placeholder, because `()` is a capturing group. Instead, you can use either -`{lang:en|de}` or `{lang:(?:en|de)}`. +Você não pode usar grupos de captura. Por exemplo, `{lang:(en|de)}` não é um +placeholder válido, porque `()` é um grupo de captura. Em vez disso, use +`{lang:en|de}` ou `{lang:(?:en|de)}`. -On a route match router fills `CurrentRoute` arguments with values matching -the corresponding parts of the URL. When you use the rule to create a URL, -it will take the values of the provided parameters and insert them at the -places where the parameters are declared. +Quando uma rota casa, o router preenche os argumentos de `CurrentRoute` com +os valores das partes correspondentes da URL. Quando você usa a regra para +criar uma URL, ela pega os valores dos parâmetros informados e os insere nas +posições onde os parâmetros foram declarados. -Let's use some examples to illustrate how named parameters work. Assume -you've declared the following three patterns: +Vamos usar alguns exemplos para mostrar como os parâmetros nomeados +funcionam. Suponha que você declarou os três padrões a seguir: 1. `'posts/{year:\d{4}}/{category}` 2. `'posts'` 3. `'post/{id:\d+}'` -- `/posts` match the second pattern; -- `/posts/2014/php` match a first pattern. Parameters are the `year` whose - value is 2014 and the `category` whose value is `php`; -- `/post/100` match a third pattern. The `id` parameter value is 100; -- `/posts/php` doesn't match. +- `/posts` casa com o segundo padrão; +- `/posts/2014/php` casa com o primeiro padrão. Os parâmetros são `year`, + com valor 2014, e `category`, com valor `php`; +- `/post/100` casa com o terceiro padrão. O valor do parâmetro `id` é 100; +- `/posts/php` não casa. -When generating URLs, you should use the following parameters: +Ao gerar URLs, você deve usar os seguintes parâmetros: ```php echo $url->generate('first', ['year' => '2020', 'category' => 'Virology']); @@ -564,13 +566,13 @@ echo $url->generate('second'); echo $url->generate('third', ['id' => '42']); ``` -### Optional parts +### Partes opcionais -You should wrap optional pattern parts with `[` and `]`. For example, -`/posts[/{id}]` pattern would match both `http://example.com/posts` and -`http://example.com/posts/42`. Router would fill `id` argument of -`CurrentRoute` service in the second case only. In this case, you could -specify the default value: +Coloque as partes opcionais do padrão entre `[` e `]`. Por exemplo, o +padrão `/posts[/{id}]` casa tanto com `http://example.com/posts` quanto com +`http://example.com/posts/42`. O router só preenche o argumento `id` do +serviço `CurrentRoute` no segundo caso. Nesse caso, você pode definir o +valor padrão: ```php use \Yiisoft\Router\Route; @@ -578,5 +580,4 @@ use \Yiisoft\Router\Route; Route::get('/posts[/{id}]')->defaults(['id' => '1']); ``` -Optional parts are only supported in a trailing position, not in the middle -of a route. +Partes opcionais só são suportadas no final da rota, não no meio dela. diff --git a/src/pt-BR/guide/runtime/sessions.md b/src/pt-BR/guide/runtime/sessions.md index 46c4a053..4c6fb3e4 100644 --- a/src/pt-BR/guide/runtime/sessions.md +++ b/src/pt-BR/guide/runtime/sessions.md @@ -1,25 +1,26 @@ -# Sessions +# Sessões -Sessions persist data between requests without passing them to the client -and back. Yii has [a session package](https://github.com/yiisoft/session) -to work with session data. +As sessões mantêm dados entre requisições sem precisar enviá-los ao cliente +e de volta. O Yii tem [um pacote de +sessão](https://github.com/yiisoft/session) para trabalhar com os dados da +sessão. -To add it to your application, use composer: +Para adicioná-lo à sua aplicação, use o composer: ```shell composer require yiisoft/session ``` -## Configuring middleware +## Configurando o middleware -To keep a session between requests, you need to add `SessionMiddleware` to -your route group or application middlewares. You should prefer a route -group when you have both API with token-based authentication and regular web -routes in the same application. Having it this way avoids starting the -session for API endpoints. +Para manter a sessão entre requisições, você precisa adicionar o +`SessionMiddleware` ao seu grupo de rotas ou aos middlewares da aplicação. +Prefira um grupo de rotas quando a mesma aplicação tiver uma API com +autenticação por token e rotas web comuns. Assim, a sessão não é iniciada +nos endpoints da API. -To add a session for a certain group of routes, edit `config/routes.php` -like the following: +Para adicionar a sessão a um grupo específico de rotas, edite +`config/routes.php` assim: ```php [!NOTE] -> Closing session as early as possible is a good practice since many session implementations are blocking other -> requests while the session is open. +> Fechar a sessão o quanto antes é uma boa prática, já que muitas implementações de sessão bloqueiam outras +> requisições enquanto a sessão está aberta. -There are two more ways to close a session: +Há mais duas formas de fechar uma sessão: ```php public function actionProfile(\Yiisoft\Session\SessionInterface $session) @@ -93,9 +94,10 @@ public function actionProfile(\Yiisoft\Session\SessionInterface $session) } ``` -## Working with session data +## Trabalhando com os dados da sessão -Usually you will use the following methods to work with session data: +Normalmente você vai usar os seguintes métodos para trabalhar com os dados +da sessão: ```php public function actionProfile(\Yiisoft\Session\SessionInterface $session) @@ -125,15 +127,15 @@ public function actionProfile(\Yiisoft\Session\SessionInterface $session) } ``` -## Flash messages +## Mensagens flash -In case you need some data to remain in session until read, such as in case -of displaying a message on the next page, "flash" messages are what you -need. A flash message is a special type of data that's available only in -the current request and the next request. After that, it will be deleted -automatically. +Quando você precisa que um dado fique na sessão até ser lido, como ao exibir +uma mensagem na próxima página, o que você precisa são as mensagens +"flash". Uma mensagem flash é um tipo especial de dado que só fica +disponível na requisição atual e na próxima. Depois disso, ela é apagada +automaticamente. -`FlashInteface` usage is the following: +O uso de `FlashInteface` é o seguinte: ```php /** @var Yiisoft\Session\Flash\FlashInterface $flash */ @@ -148,14 +150,15 @@ if ($warning !== null) { } ``` -## Custom session storage +## Armazenamento de sessão personalizado -When using `Yiisoft\Session\Session`, you can use your own storage -implementation: +Ao usar `Yiisoft\Session\Session`, você pode usar a sua própria +implementação de armazenamento: ```php $handler = new MySessionHandler(); $session = new \Yiisoft\Session\Session([], $handler); ``` -Custom storage must implement `\SessionHandlerInterface`. +O armazenamento personalizado precisa implementar +`\SessionHandlerInterface`. diff --git a/src/pt-BR/guide/start/databases.md b/src/pt-BR/guide/start/databases.md index 667e11e4..3cd8d3bb 100644 --- a/src/pt-BR/guide/start/databases.md +++ b/src/pt-BR/guide/start/databases.md @@ -854,7 +854,7 @@ $htmlForm = Html::form() close() ?> ``` -### Routing +### Roteamento Adjust `config/common/routes.php`: diff --git a/src/pt-BR/guide/tutorial/using-yii-with-swoole.md b/src/pt-BR/guide/tutorial/using-yii-with-swoole.md index 322f6a94..76365322 100644 --- a/src/pt-BR/guide/tutorial/using-yii-with-swoole.md +++ b/src/pt-BR/guide/tutorial/using-yii-with-swoole.md @@ -151,7 +151,7 @@ php server.php A scope is shared, so at each iteration of the event loop every service that depends on state should be reset. -## Sessions +## Sessões Avoid native PHP sessions, including `Yiisoft\Session\Session`, when Swoole coroutines handle overlapping requests within one worker: they share session diff --git a/src/pt-BR/internals/006-git-commit-messages.md b/src/pt-BR/internals/006-git-commit-messages.md index 18a29f3c..ad1bd260 100644 --- a/src/pt-BR/internals/006-git-commit-messages.md +++ b/src/pt-BR/internals/006-git-commit-messages.md @@ -10,7 +10,7 @@ - Start with a capital letter - Limit to 50 characters -## Body +## Corpo Use the message body **if** you need an extra explanation. Explain why, not how. From f2d17e94bee0a8db7ba1aa8049e35faae2c8d488 Mon Sep 17 00:00:00 2001 From: Yuri Neves Date: Fri, 23 Oct 2026 14:18:13 -0300 Subject: [PATCH 03/11] Translate guide introduction and getting started to Brazilian Portuguese --- _translations/po/pt-BR/guide_index.md.po | 8 +- .../pt-BR/guide_intro_upgrade-from-v1.md.po | 580 ++++++++++--- .../pt-BR/guide_intro_upgrade-from-v2.md.po | 690 +++++++++++---- .../po/pt-BR/guide_start_databases.md.po | 816 +++++++++++++++--- src/pt-BR/guide/index.md | 8 +- src/pt-BR/guide/intro/upgrade-from-v1.md | 547 ++++++------ src/pt-BR/guide/intro/upgrade-from-v2.md | 675 ++++++++------- src/pt-BR/guide/start/databases.md | 279 +++--- 8 files changed, 2452 insertions(+), 1151 deletions(-) diff --git a/_translations/po/pt-BR/guide_index.md.po b/_translations/po/pt-BR/guide_index.md.po index bd951fec..a331ab4c 100644 --- a/_translations/po/pt-BR/guide_index.md.po +++ b/_translations/po/pt-BR/guide_index.md.po @@ -52,12 +52,12 @@ msgstr "[Sobre o Yii](intro/what-is-yii.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Upgrading from version 1.1](intro/upgrade-from-v1.md)" -msgstr "[Atualizando a partir da versão 1.1](intro/upgrade-from-v1.md)" +msgstr "[Migrando da versão 1.1](intro/upgrade-from-v1.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Upgrading from version 2.0](intro/upgrade-from-v2.md)" -msgstr "[Atualizando a partir da versão 2.0](intro/upgrade-from-v2.md)" +msgstr "[Migrando da versão 2.0](intro/upgrade-from-v2.md)" #. type: Title ## #: ../src/guide/index.md ../src/guide/tutorial/console-applications.md @@ -355,7 +355,7 @@ msgstr "[Template engines](views/template-engines.md) TODO: verify!" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[View injections](views/view-injections.md)" -msgstr "[Injeções em views](views/view-injections.md)" +msgstr "[Injeções de view](views/view-injections.md)" #. type: Bullet: '- ' #: ../src/guide/index.md @@ -535,7 +535,7 @@ msgstr "[Envio de e-mails](tutorial/mailing.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Performance tuning](tutorial/performance-tuning.md)" -msgstr "[Otimização de desempenho](tutorial/performance-tuning.md)" +msgstr "[Ajuste de desempenho](tutorial/performance-tuning.md)" #. type: Bullet: '- ' #: ../src/guide/index.md diff --git a/_translations/po/pt-BR/guide_intro_upgrade-from-v1.md.po b/_translations/po/pt-BR/guide_intro_upgrade-from-v1.md.po index 37b6f5f2..6280c39a 100644 --- a/_translations/po/pt-BR/guide_intro_upgrade-from-v1.md.po +++ b/_translations/po/pt-BR/guide_intro_upgrade-from-v1.md.po @@ -8,23 +8,21 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-09-25 14:35+0000\n" "PO-Revision-Date: 2026-09-25 14:35+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/cookbook/deployment/angie-docker-proxy.md -#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +#: ../src/cookbook/deployment/angie-docker-proxy.md ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "Project structure" -msgstr "" +msgstr "Estrutura do projeto" #. type: Fenced code block (json) -#: ../src/guide/concept/autoloading.md ../src/guide/intro/upgrade-from-v1.md -#: ../src/guide/intro/upgrade-from-v2.md +#: ../src/guide/concept/autoloading.md ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "" "{\n" @@ -35,12 +33,19 @@ msgid "" " }\n" "}\n" msgstr "" +"{\n" +" \"autoload\": {\n" +" \"psr-4\": {\n" +" \"App\\\\\": \"src/\"\n" +" }\n" +" }\n" +"}\n" #. type: Title # #: ../src/guide/intro/upgrade-from-v1.md #, no-wrap msgid "Upgrading from Version 1.1" -msgstr "" +msgstr "Migrando da versão 1.1" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md @@ -49,93 +54,95 @@ msgid "" "> If you haven't used Yii 1.1, you can skip this section and get directly to\n" "> \"[getting started](../start/prerequisites.md)\" section.\n" msgstr "" +"> Se você não usou o Yii 1.1, pode pular esta seção e ir direto para a seção\n" +"> \"[primeiros passos](../start/prerequisites.md)\".\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Yii3 is not an incremental upgrade from Yii 1.1. Yii 2.0 was a full rewrite, and Yii3 changes the architecture again: Composer packages, namespaces, PHP 8, PSR interfaces, dependency injection, explicit routes, middleware, and separate packages for features that were built into the framework in Yii 1.1." -msgstr "" +msgstr "O Yii3 não é um upgrade incremental do Yii 1.1. O Yii 2.0 foi uma reescrita completa, e o Yii3 muda a arquitetura de novo: pacotes Composer, namespaces, PHP 8, interfaces PSR, injeção de dependência, rotas explícitas, middleware e pacotes separados para funcionalidades que no Yii 1.1 eram embutidas no framework." #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Treat this as building a new Yii3 application with the benefit of Yii 1.1 experience. Reuse the domain knowledge, database schema, user workflows, and selected code after refactoring. Do not try to reproduce the Yii 1.1 application structure in Yii3. A direct search-and-replace conversion is not realistic." -msgstr "" +msgstr "Encare isso como a construção de uma nova aplicação Yii3 aproveitando a experiência com o Yii 1.1. Reaproveite o conhecimento do domínio, o esquema do banco de dados, os fluxos dos usuários e partes selecionadas do código após refatorá-las. Não tente reproduzir a estrutura da aplicação Yii 1.1 no Yii3. Uma conversão direta por busca e substituição não é realista." #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "For additional background, read the Yii 2.0 guide section [Upgrading from Version 1.1](https://www.yiiframework.com/doc/guide/2.0/en/intro-upgrade-from-v1). It explains the first major break from Yii 1.1: Composer, namespaces, object configuration, view changes, controller return values, widgets, assets, helpers, forms, query builder, Active Record, and URL management. Yii3 builds on many of those changes and makes dependencies more explicit." -msgstr "" +msgstr "Para mais contexto, leia a seção do guia do Yii 2.0 [Upgrading from Version 1.1](https://www.yiiframework.com/doc/guide/2.0/en/intro-upgrade-from-v1). Ela explica a primeira grande ruptura com o Yii 1.1: Composer, namespaces, configuração de objetos, mudanças nas views, valores de retorno dos controllers, widgets, assets, helpers, formulários, query builder, Active Record e gerenciamento de URLs. O Yii3 se apoia em muitas dessas mudanças e torna as dependências mais explícitas." #. type: Title ## #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "Recommended approach" -msgstr "" +msgstr "Abordagem recomendada" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Choose one of these paths:" -msgstr "" +msgstr "Escolha um destes caminhos:" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md msgid "Build a new Yii3 application directly when the Yii 1.1 application is small or you are already rewriting request flows." -msgstr "" +msgstr "Construa uma nova aplicação Yii3 diretamente quando a aplicação Yii 1.1 for pequena ou você já estiver reescrevendo os fluxos de requisição." #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md msgid "Move Yii 1.1 concepts to Yii 2.0 first when the team needs a smaller conceptual step." -msgstr "" +msgstr "Migre primeiro os conceitos do Yii 1.1 para o Yii 2.0 quando o time precisar de um passo conceitual menor." #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md msgid "Keep Yii 1.1 running and rebuild critical flows in Yii3 one by one." -msgstr "" +msgstr "Mantenha o Yii 1.1 rodando e reconstrua os fluxos críticos no Yii3 um a um." #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "For most long-lived applications, the third option is the least risky. Create a Yii3 application, connect it to the same database, and build vertical slices: route, action, input validation, persistence, view, assets, and tests. Each slice should be idiomatic Yii3, even when it is based on behavior from the Yii 1.1 application." -msgstr "" +msgstr "Para a maioria das aplicações de longa duração, a terceira opção é a de menor risco. Crie uma aplicação Yii3, conecte-a ao mesmo banco de dados e construa vertical slices: rota, action, validação de entrada, persistência, view, assets e testes. Cada slice deve ser Yii3 idiomático, mesmo quando se baseia no comportamento da aplicação Yii 1.1." #. type: Title ## #: ../src/guide/intro/upgrade-from-v1.md #, no-wrap msgid "Prepare the Yii 1.1 application" -msgstr "" +msgstr "Prepare a aplicação Yii 1.1" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Useful preparation can happen before the Yii3 application is ready. These refactorings make old behavior easier to understand and reduce the amount of Yii 1.1 framework state that crosses into the new code:" -msgstr "" +msgstr "Uma preparação útil pode acontecer antes de a aplicação Yii3 estar pronta. Estas refatorações tornam o comportamento antigo mais fácil de entender e reduzem a quantidade de estado do framework Yii 1.1 que passa para o código novo:" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md msgid "Remove direct `Yii::app()` access from reusable code where practical. If a full refactoring is too large, keep `Yii::app()` calls near controllers, widgets, and commands, then pass values and services to lower-level code explicitly." -msgstr "" +msgstr "Remova o acesso direto a `Yii::app()` do código reutilizável onde for viável. Se uma refatoração completa for grande demais, mantenha as chamadas a `Yii::app()` perto de controllers, widgets e comandos, e passe valores e serviços explicitamente para o código de nível mais baixo." #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md msgid "Introduce repositories or query services for database reads currently spread across controllers, views, `CActiveRecord` methods, and widgets. Yii3 can use Active Record, but it does not require it for every persistence task." -msgstr "" +msgstr "Introduza repositórios ou serviços de consulta para as leituras do banco de dados hoje espalhadas por controllers, views, métodos de `CActiveRecord` e widgets. O Yii3 pode usar Active Record, mas não o exige para toda tarefa de persistência." #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md msgid "Separate business rules from framework infrastructure. Code that does not extend `CComponent`, read global application state, or render views is easier to reuse as a specification for Yii3 code." -msgstr "" +msgstr "Separe as regras de negócio da infraestrutura do framework. Código que não estende `CComponent`, não lê o estado global da aplicação nem renderiza views é mais fácil de reutilizar como especificação para o código Yii3." #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md msgid "Move reusable behavior out of large controllers and Active Record classes into Yii 1.1 application components or plain services. Yii3 services are configured and injected differently, but the responsibility boundary is similar." -msgstr "" +msgstr "Mova o comportamento reutilizável de controllers e classes Active Record grandes para componentes de aplicação do Yii 1.1 ou serviços simples. Os serviços do Yii3 são configurados e injetados de outra forma, mas a fronteira de responsabilidade é parecida." #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md msgid "Add tests or characterization checks around routes and workflows you plan to rebuild first. They become the executable specification for the Yii3 slice." -msgstr "" +msgstr "Adicione testes ou verificações de caracterização em torno das rotas e fluxos que você planeja reconstruir primeiro. Eles se tornam a especificação executável do slice Yii3." #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md msgid "For example, instead of reading post archive data directly from several controllers or widgets, create a small service that describes the application need:" -msgstr "" +msgstr "Por exemplo, em vez de ler os dados do arquivo de posts diretamente em vários controllers ou widgets, crie um pequeno serviço que descreva a necessidade da aplicação:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v1.md @@ -154,68 +161,80 @@ msgid "" " }\n" "}\n" msgstr "" +"class PostRepository extends CComponent\n" +"{\n" +" public function getArchive()\n" +" {\n" +" // ...\n" +" }\n" +"\n" +" public function getTopForFrontPage($limit = 10)\n" +" {\n" +" // ...\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "The Yii3 implementation may use `yiisoft/active-record`, `yiisoft/db`, or another persistence layer. The important point is that controllers and views no longer need to know that detail." -msgstr "" +msgstr "A implementação no Yii3 pode usar `yiisoft/active-record`, `yiisoft/db` ou outra camada de persistência. O importante é que controllers e views não precisem mais conhecer esse detalhe." #. type: Title ## #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "Things to learn before starting" -msgstr "" +msgstr "O que aprender antes de começar" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Some Yii3 application-template choices are likely to be new in a Yii 1.1 codebase:" -msgstr "" +msgstr "Algumas escolhas do template de aplicação do Yii3 provavelmente serão novidade para uma base de código Yii 1.1:" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md msgid "[Composer](https://getcomposer.org/). Yii3 applications and packages are installed through Composer and loaded with PSR-4 autoloading." -msgstr "" +msgstr "[Composer](https://getcomposer.org/). Aplicações e pacotes Yii3 são instalados pelo Composer e carregados com autoloading PSR-4." #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md msgid "[Namespaces](https://www.php.net/manual/en/language.namespaces.php). Yii3 classes are namespaced instead of using Yii 1.1-style class prefixes and path aliases for class loading." -msgstr "" +msgstr "[Namespaces](https://www.php.net/manual/en/language.namespaces.php). As classes do Yii3 usam namespaces em vez dos prefixos de classe e path aliases do Yii 1.1 para o carregamento de classes." #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md msgid "[Docker](https://www.docker.com/get-started/). The default Yii3 application template includes Docker configuration. Using it gives each application its own repeatable environment and reduces differences between local development and production." -msgstr "" +msgstr "[Docker](https://www.docker.com/get-started/). O template de aplicação padrão do Yii3 inclui configuração do Docker. Usá-lo dá a cada aplicação seu próprio ambiente reproduzível e reduz as diferenças entre o desenvolvimento local e a produção." #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md msgid "[Environment variables](https://en.wikipedia.org/wiki/Environment_variable). Yii3 templates commonly use them for environment-specific settings and secrets, especially in Docker-based deployments. This follows the same idea as [12-factor app configuration](https://12factor.net/config)." -msgstr "" +msgstr "[Variáveis de ambiente](https://en.wikipedia.org/wiki/Environment_variable). Os templates do Yii3 costumam usá-las para configurações específicas de ambiente e segredos, especialmente em deploys baseados em Docker. Isso segue a mesma ideia da [configuração de aplicações 12-factor](https://12factor.net/config)." #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md msgid "[Actions](../structure/action.md). Yii3 does not require controller inheritance. A route can point to any callable, and the default template uses invokable action classes." -msgstr "" +msgstr "[Actions](../structure/action.md). O Yii3 não exige herança de controller. Uma rota pode apontar para qualquer callable, e o template padrão usa classes de action invocáveis." #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md msgid "[Application structure](../structure/overview.md). Yii3's default structure is different from Yii 1.1. Start with the Yii3 template and change it only when the application needs it." -msgstr "" +msgstr "[Estrutura da aplicação](../structure/overview.md). A estrutura padrão do Yii3 é diferente da do Yii 1.1. Comece com o template do Yii3 e altere-o apenas quando a aplicação precisar." #. type: Title ## #: ../src/guide/intro/upgrade-from-v1.md #, no-wrap msgid "PHP, Composer, and namespaces" -msgstr "" +msgstr "PHP, Composer e namespaces" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Yii 1.1 applications commonly rely on PHP 5-era code, class prefixes such as `CController`, and autoloading by class name. Yii3 applications require modern PHP and Composer autoloading." -msgstr "" +msgstr "Aplicações Yii 1.1 costumam depender de código da era do PHP 5, prefixos de classe como `CController` e autoloading pelo nome da classe. Aplicações Yii3 exigem PHP moderno e autoloading do Composer." #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Yii 1.1:" -msgstr "" +msgstr "Yii 1.1:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v1.md @@ -225,11 +244,14 @@ msgid "" "{\n" "}\n" msgstr "" +"class SiteController extends CController\n" +"{\n" +"}\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Yii3:" -msgstr "" +msgstr "Yii3:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v1.md @@ -241,32 +263,37 @@ msgid "" "{\n" "}\n" msgstr "" +"namespace App\\Web\\HomePage;\n" +"\n" +"final readonly class Action\n" +"{\n" +"}\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md msgid "Configure your application namespace with PSR-4:" -msgstr "" +msgstr "Configure o namespace da sua aplicação com PSR-4:" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Run:" -msgstr "" +msgstr "Execute:" #. type: Fenced code block (shell) #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "composer dump-autoload\n" -msgstr "" +msgstr "composer dump-autoload\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "When reusing a class, give it a namespace, add strict types, replace Yii 1.1 base classes, and inject dependencies instead of reading them from global application state. If these changes make the class awkward, use the old class as a specification and write a new Yii3 class instead." -msgstr "" +msgstr "Ao reutilizar uma classe, dê a ela um namespace, adicione strict types, substitua as classes base do Yii 1.1 e injete as dependências em vez de lê-las do estado global da aplicação. Se essas mudanças deixarem a classe estranha, use a classe antiga como especificação e escreva uma nova classe Yii3." #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "A Yii 1.1 application often uses:" -msgstr "" +msgstr "Uma aplicação Yii 1.1 frequentemente usa:" #. type: Fenced code block (text) #: ../src/guide/intro/upgrade-from-v1.md @@ -285,11 +312,23 @@ msgid "" "themes/\n" "webroot/\n" msgstr "" +"protected/\n" +" commands/\n" +" components/\n" +" config/\n" +" controllers/\n" +" extensions/\n" +" messages/\n" +" migrations/\n" +" models/\n" +" views/\n" +"themes/\n" +"webroot/\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "The current Yii3 application template uses:" -msgstr "" +msgstr "O template de aplicação atual do Yii3 usa:" #. type: Fenced code block (text) #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md @@ -302,11 +341,17 @@ msgid "" "src/\n" "tests/\n" msgstr "" +"assets/\n" +"config/\n" +"public/\n" +"runtime/\n" +"src/\n" +"tests/\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md msgid "Typical mappings to consider are:" -msgstr "" +msgstr "Mapeamentos típicos a considerar:" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md @@ -325,22 +370,34 @@ msgid "" "| `protected/config` | `config/common`, `config/web`, `config/console`, `config/environments` |\n" "| `webroot` | `public` |\n" msgstr "" +"| Yii 1.1 | Yii3 |\n" +"|---------|------|\n" +"| `protected/controllers` | `src/Web/*/Action.php` ou serviços no estilo controller |\n" +"| `protected/models` | `src/Domain`, `src/Shared`, `src/Db` ou form models, conforme a responsabilidade |\n" +"| `protected/views` | templates perto da funcionalidade, por exemplo `src/Web/HomePage/template.php` |\n" +"| `protected/views/layouts` | templates de layout e assets em `src/Web/Shared/Layout` |\n" +"| `protected/components` | serviços configurados no container de injeção de dependência |\n" +"| `protected/extensions` | pacotes Composer ou pacotes locais |\n" +"| `protected/commands` | `src/Console/*Command.php` |\n" +"| `protected/messages` | arquivos de mensagens do tradutor |\n" +"| `protected/config` | `config/common`, `config/web`, `config/console`, `config/environments` |\n" +"| `webroot` | `public` |\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Do not recreate `protected` in Yii3. Put PHP source under `src`, public files under `public`, generated/runtime files under `runtime`, and configuration under `config`." -msgstr "" +msgstr "Não recrie `protected` no Yii3. Coloque o código PHP em `src`, os arquivos públicos em `public`, os arquivos gerados/de runtime em `runtime` e a configuração em `config`." #. type: Title ## #: ../src/guide/intro/upgrade-from-v1.md #, no-wrap msgid "Configuration and application components" -msgstr "" +msgstr "Configuração e componentes da aplicação" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Yii 1.1 configuration is usually one large array:" -msgstr "" +msgstr "A configuração do Yii 1.1 geralmente é um único array grande:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v1.md @@ -363,52 +420,68 @@ msgid "" " ],\n" "];\n" msgstr "" +"return [\n" +" 'basePath' => dirname(__DIR__),\n" +" 'components' => [\n" +" 'db' => [\n" +" 'connectionString' => 'mysql:host=localhost;dbname=app',\n" +" 'username' => 'root',\n" +" 'password' => '',\n" +" ],\n" +" 'urlManager' => [\n" +" 'urlFormat' => 'path',\n" +" 'rules' => [\n" +" 'post/' => 'post/view',\n" +" ],\n" +" ],\n" +" ],\n" +"];\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "In Yii3, configuration is split by purpose and services are wired through the container:" -msgstr "" +msgstr "No Yii3, a configuração é dividida por finalidade e os serviços são conectados pelo container:" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md msgid "aliases in `config/common/aliases.php`;" -msgstr "" +msgstr "aliases em `config/common/aliases.php`;" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md msgid "parameters in `config/common/params.php` and environment files;" -msgstr "" +msgstr "parâmetros em `config/common/params.php` e nos arquivos de ambiente;" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md msgid "shared service definitions in `config/common/di/*.php`;" -msgstr "" +msgstr "definições de serviços compartilhadas em `config/common/di/*.php`;" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md msgid "web-only service definitions in `config/web/di/*.php`;" -msgstr "" +msgstr "definições de serviços apenas para web em `config/web/di/*.php`;" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md msgid "routes in `config/common/routes.php`;" -msgstr "" +msgstr "rotas em `config/common/routes.php`;" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md msgid "console commands in `config/console/*.php`." -msgstr "" +msgstr "comandos de console em `config/console/*.php`." #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "The default template's console DI group reuses shared definitions from `config/common/di/*.php`. If you need console-only container definitions, add files for them to the `di-console` group in `config/configuration.php` and rebuild the merge plan." -msgstr "" +msgstr "O grupo de DI de console do template padrão reutiliza as definições compartilhadas de `config/common/di/*.php`. Se você precisar de definições de container apenas para o console, adicione arquivos para elas ao grupo `di-console` em `config/configuration.php` e reconstrua o merge plan." #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md #, no-wrap msgid "Replace `Yii::app()->componentName` with constructor-injected services:\n" -msgstr "" +msgstr "Substitua `Yii::app()->componentName` por serviços injetados pelo construtor:\n" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v1.md @@ -426,22 +499,33 @@ msgid "" " }\n" "}\n" msgstr "" +"use Yiisoft\\Db\\Connection\\ConnectionInterface;\n" +"use Yiisoft\\Router\\UrlGeneratorInterface;\n" +"\n" +"final readonly class PostRepository\n" +"{\n" +" public function __construct(\n" +" private ConnectionInterface $db,\n" +" private UrlGeneratorInterface $urlGenerator,\n" +" ) {\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md msgid "See [Configuration](../concept/configuration.md), [Aliases](../concept/aliases.md), and [Dependency injection container](../concept/di-container.md)." -msgstr "" +msgstr "Veja [Configuração](../concept/configuration.md), [Aliases](../concept/aliases.md) e [Container de injeção de dependência](../concept/di-container.md)." #. type: Title ## #: ../src/guide/intro/upgrade-from-v1.md #, no-wrap msgid "Entry script" -msgstr "" +msgstr "Script de entrada" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Yii 1.1 entry scripts commonly load `yii.php` and create a web application:" -msgstr "" +msgstr "Os scripts de entrada do Yii 1.1 geralmente carregam `yii.php` e criam uma aplicação web:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v1.md @@ -451,27 +535,30 @@ msgid "" "\n" "Yii::createWebApplication($config)->run();\n" msgstr "" +"require_once __DIR__ . '/../framework/yii.php';\n" +"\n" +"Yii::createWebApplication($config)->run();\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Yii3 entry scripts load Composer and bootstrap the configured application. Start with the `public/index.php` file from `yiisoft/app` and adjust configuration instead of building the application manually in the entry script." -msgstr "" +msgstr "Os scripts de entrada do Yii3 carregam o Composer e inicializam a aplicação configurada. Comece com o arquivo `public/index.php` do `yiisoft/app` e ajuste a configuração em vez de montar a aplicação manualmente no script de entrada." #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md msgid "See [Entry scripts](../structure/entry-script.md) and [Application workflow](../start/workflow.md)." -msgstr "" +msgstr "Veja [Scripts de entrada](../structure/entry-script.md) e [Fluxo da aplicação](../start/workflow.md)." #. type: Title ## #: ../src/guide/intro/upgrade-from-v1.md #, no-wrap msgid "Controllers, actions, and routes" -msgstr "" +msgstr "Controllers, actions e rotas" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Yii 1.1 controllers extend `CController`, and actions are methods named `actionName`:" -msgstr "" +msgstr "Os controllers do Yii 1.1 estendem `CController`, e as actions são métodos chamados `actionName`:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v1.md @@ -491,11 +578,24 @@ msgid "" " }\n" "}\n" msgstr "" +"class PostController extends CController\n" +"{\n" +" public function actionView($id)\n" +" {\n" +" $post = Post::model()->findByPk($id);\n" +"\n" +" if ($post === null) {\n" +" throw new CHttpException(404);\n" +" }\n" +"\n" +" $this->render('view', ['post' => $post]);\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Yii3 does not require controller inheritance. The current template uses invokable action classes:" -msgstr "" +msgstr "O Yii3 não exige herança de controller. O template atual usa classes de action invocáveis:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v1.md @@ -527,11 +627,36 @@ msgid "" " }\n" "}\n" msgstr "" +"namespace App\\Web\\Post\\View;\n" +"\n" +"use App\\Post\\PostRepository;\n" +"use Psr\\Http\\Message\\ResponseInterface;\n" +"use Yiisoft\\Router\\CurrentRoute;\n" +"use Yiisoft\\Yii\\View\\Renderer\\WebViewRenderer;\n" +"\n" +"final readonly class Action\n" +"{\n" +" public function __construct(\n" +" private CurrentRoute $currentRoute,\n" +" private PostRepository $posts,\n" +" private WebViewRenderer $viewRenderer,\n" +" ) {\n" +" }\n" +"\n" +" public function __invoke(): ResponseInterface\n" +" {\n" +" $post = $this->posts->findById((int) $this->currentRoute->getArgument('id'));\n" +"\n" +" return $this->viewRenderer->render(__DIR__ . '/template', [\n" +" 'post' => $post,\n" +" ]);\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "The route is explicit:" -msgstr "" +msgstr "A rota é explícita:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v1.md @@ -546,27 +671,35 @@ msgid "" " ->name('post/view'),\n" "];\n" msgstr "" +"use App\\Web\\Post\\View;\n" +"use Yiisoft\\Router\\Route;\n" +"\n" +"return [\n" +" Route::get('/post/{id:\\d+}')\n" +" ->action(View\\Action::class)\n" +" ->name('post/view'),\n" +"];\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Define routes before action bodies. It gives you a checklist of request flows you decided to keep in the Yii3 application." -msgstr "" +msgstr "Defina as rotas antes do corpo das actions. Isso dá a você uma checklist dos fluxos de requisição que você decidiu manter na aplicação Yii3." #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md msgid "See [Actions](../structure/action.md), [Middleware](../structure/middleware.md), and [Routing and URL generation](../runtime/routing.md)." -msgstr "" +msgstr "Veja [Actions](../structure/action.md), [Middleware](../structure/middleware.md) e [Roteamento e geração de URLs](../runtime/routing.md)." #. type: Title ## #: ../src/guide/intro/upgrade-from-v1.md #, no-wrap msgid "Requests, responses, redirects, sessions, and cookies" -msgstr "" +msgstr "Requisições, respostas, redirecionamentos, sessões e cookies" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Yii 1.1 code often reads and writes through `Yii::app()`:" -msgstr "" +msgstr "O código Yii 1.1 frequentemente lê e escreve por meio de `Yii::app()`:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v1.md @@ -576,27 +709,30 @@ msgid "" "Yii::app()->user->setFlash('success', 'Saved.');\n" "$this->redirect(['post/view', 'id' => $id]);\n" msgstr "" +"$id = Yii::app()->request->getParam('id');\n" +"Yii::app()->user->setFlash('success', 'Saved.');\n" +"$this->redirect(['post/view', 'id' => $id]);\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Yii3 uses PSR-7 request and response objects and injectable services. Request input is available from `ServerRequestInterface`; redirects, sessions, cookies, and responses are explicit dependencies." -msgstr "" +msgstr "O Yii3 usa objetos de requisição e resposta PSR-7 e serviços injetáveis. A entrada da requisição está disponível em `ServerRequestInterface`; redirecionamentos, sessões, cookies e respostas são dependências explícitas." #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md msgid "See [Request](../runtime/request.md), [Response](../runtime/response.md), [Sessions](../runtime/sessions.md), and [Cookies](../runtime/cookies.md)." -msgstr "" +msgstr "Veja [Requisição](../runtime/request.md), [Resposta](../runtime/response.md), [Sessões](../runtime/sessions.md) e [Cookies](../runtime/cookies.md)." #. type: Title ## #: ../src/guide/intro/upgrade-from-v1.md #, no-wrap msgid "Views and layouts" -msgstr "" +msgstr "Views e layouts" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Yii 1.1 views use `$this` as the controller or widget context. Layouts and partials are rendered through controller methods:" -msgstr "" +msgstr "As views do Yii 1.1 usam `$this` como o contexto do controller ou do widget. Layouts e partials são renderizados por métodos do controller:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v1.md @@ -609,11 +745,17 @@ msgid "" "\n" "

title); ?>

\n" msgstr "" +"\n" +"\n" +"

title); ?>

\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "In Yii3 templates, `$this` is a `Yiisoft\\View\\WebView` instance:" -msgstr "" +msgstr "Nos templates do Yii3, `$this` é uma instância de `Yiisoft\\View\\WebView`:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v1.md @@ -632,27 +774,39 @@ msgid "" "\n" "

getTitle()) ?>

\n" msgstr "" +"use Yiisoft\\Html\\Html;\n" +"use Yiisoft\\View\\WebView;\n" +"\n" +"/**\n" +" * @var WebView $this\n" +" * @var Post $post\n" +" */\n" +"\n" +"$this->setTitle($post->getTitle());\n" +"?>\n" +"\n" +"

getTitle()) ?>

\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Move controller-specific view logic to the action or to a presenter. Pass only the data a template needs." -msgstr "" +msgstr "Mova a lógica de view específica do controller para a action ou para um presenter. Passe apenas os dados de que o template precisa." #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "See [View](../views/view.md), [View injections](../views/view-injections.md), and [Template engines](../views/template-engines.md)." -msgstr "" +msgstr "Veja [View](../views/view.md), [Injeções de view](../views/view-injections.md) e [Template engines](../views/template-engines.md)." #. type: Title ## #: ../src/guide/intro/upgrade-from-v1.md #, no-wrap msgid "Assets and client scripts" -msgstr "" +msgstr "Assets e scripts do cliente" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Yii 1.1 applications often use `CClientScript`, themes, and extension-specific asset publishing:" -msgstr "" +msgstr "Aplicações Yii 1.1 frequentemente usam `CClientScript`, temas e publicação de assets específica de extensões:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v1.md @@ -661,11 +815,13 @@ msgid "" "Yii::app()->clientScript->registerCssFile('/css/site.css');\n" "Yii::app()->clientScript->registerScriptFile('/js/site.js');\n" msgstr "" +"Yii::app()->clientScript->registerCssFile('/css/site.css');\n" +"Yii::app()->clientScript->registerScriptFile('/js/site.js');\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Yii3 uses asset bundles from `yiisoft/assets`:" -msgstr "" +msgstr "O Yii3 usa asset bundles do `yiisoft/assets`:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v1.md @@ -685,62 +841,75 @@ msgid "" " public array $js = ['site.js'];\n" "}\n" msgstr "" +"namespace App\\Web\\Shared\\Layout\\Main;\n" +"\n" +"use Yiisoft\\Assets\\AssetBundle;\n" +"\n" +"final class MainAsset extends AssetBundle\n" +"{\n" +" public ?string $basePath = '@assets/main';\n" +" public ?string $baseUrl = '@assetsUrl/main';\n" +" public ?string $sourcePath = '@assetsSource/main';\n" +"\n" +" public array $css = ['site.css'];\n" +" public array $js = ['site.js'];\n" +"}\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Register bundles through the asset manager in layouts or views." -msgstr "" +msgstr "Registre os bundles pelo gerenciador de assets nos layouts ou views." #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "See [Assets](../views/asset.md) and [Scripts, styles and metatags](../views/script-style-meta.md)." -msgstr "" +msgstr "Veja [Assets](../views/asset.md) e [Scripts, estilos e metatags](../views/script-style-meta.md)." #. type: Title ## #: ../src/guide/intro/upgrade-from-v1.md #, no-wrap msgid "Models, forms, and validation" -msgstr "" +msgstr "Models, formulários e validação" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Yii 1.1 has `CModel`, `CFormModel`, and `CActiveRecord`. It is common for one model class to contain input data, labels, validation rules, database persistence, and business logic." -msgstr "" +msgstr "O Yii 1.1 tem `CModel`, `CFormModel` e `CActiveRecord`. É comum uma única classe de model conter os dados de entrada, rótulos, regras de validação, persistência no banco de dados e lógica de negócio." #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Yii3 works better when these responsibilities are split:" -msgstr "" +msgstr "O Yii3 funciona melhor quando essas responsabilidades são separadas:" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md msgid "form data and labels: `yiisoft/form-model`;" -msgstr "" +msgstr "dados e rótulos do formulário: `yiisoft/form-model`;" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md msgid "validation rules: `yiisoft/validator`;" -msgstr "" +msgstr "regras de validação: `yiisoft/validator`;" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md msgid "form rendering: `yiisoft/form`;" -msgstr "" +msgstr "renderização de formulários: `yiisoft/form`;" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md msgid "persistence: repositories, `yiisoft/db`, or `yiisoft/active-record`;" -msgstr "" +msgstr "persistência: repositórios, `yiisoft/db` ou `yiisoft/active-record`;" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md msgid "business workflows: application services." -msgstr "" +msgstr "fluxos de negócio: serviços da aplicação." #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Yii 1.1 form model:" -msgstr "" +msgstr "Form model no Yii 1.1:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v1.md @@ -760,11 +929,24 @@ msgid "" " }\n" "}\n" msgstr "" +"class ContactForm extends CFormModel\n" +"{\n" +" public $name;\n" +" public $email;\n" +"\n" +" public function rules()\n" +" {\n" +" return [\n" +" ['name, email', 'required'],\n" +" ['email', 'email'],\n" +" ];\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Yii3 form model:" -msgstr "" +msgstr "Form model no Yii3:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md @@ -784,22 +966,35 @@ msgid "" " public ?string $email = null;\n" "}\n" msgstr "" +"use Yiisoft\\FormModel\\FormModel;\n" +"use Yiisoft\\Validator\\Rule\\Email;\n" +"use Yiisoft\\Validator\\Rule\\Required;\n" +"\n" +"final class ContactForm extends FormModel\n" +"{\n" +" #[Required]\n" +" public ?string $name = null;\n" +"\n" +" #[Required]\n" +" #[Email]\n" +" public ?string $email = null;\n" +"}\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md msgid "See [Working with forms](../start/forms.md), [Validating input](https://github.com/yiisoft/validator/blob/master/docs/guide/en/README.md), [yiisoft/form](https://github.com/yiisoft/form), and [yiisoft/form-model](https://github.com/yiisoft/form-model)." -msgstr "" +msgstr "Veja [Trabalhando com formulários](../start/forms.md), [Validando a entrada](https://github.com/yiisoft/validator/blob/master/docs/guide/en/README.md), [yiisoft/form](https://github.com/yiisoft/form) e [yiisoft/form-model](https://github.com/yiisoft/form-model)." #. type: Title ## #: ../src/guide/intro/upgrade-from-v1.md #, no-wrap msgid "Active Record" -msgstr "" +msgstr "Active Record" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Yii 1.1 Active Record uses `CActiveRecord::model()` and dynamic attributes:" -msgstr "" +msgstr "O Active Record do Yii 1.1 usa `CActiveRecord::model()` e atributos dinâmicos:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v1.md @@ -826,11 +1021,31 @@ msgid "" " }\n" "}\n" msgstr "" +"class Post extends CActiveRecord\n" +"{\n" +" public static function model($className = __CLASS__)\n" +" {\n" +" return parent::model($className);\n" +" }\n" +"\n" +" public function tableName()\n" +" {\n" +" return '{{post}}';\n" +" }\n" +"\n" +" public function rules()\n" +" {\n" +" return [\n" +" ['title, body', 'required'],\n" +" ['title', 'length', 'max' => 255],\n" +" ];\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "The incremental Yii3 option is [yiisoft/active-record](https://github.com/yiisoft/active-record):" -msgstr "" +msgstr "A opção incremental no Yii3 é o [yiisoft/active-record](https://github.com/yiisoft/active-record):" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v1.md @@ -860,53 +1075,76 @@ msgid "" " }\n" "}\n" msgstr "" +"use Yiisoft\\ActiveRecord\\ActiveRecord;\n" +"\n" +"final class Post extends ActiveRecord\n" +"{\n" +" protected int $id;\n" +" protected string $title;\n" +" protected string $body;\n" +"\n" +" public function tableName(): string\n" +" {\n" +" return '{{%post}}';\n" +" }\n" +"\n" +" public function getTitle(): ?string\n" +" {\n" +" return $this->title ?? null;\n" +" }\n" +"\n" +" public function setTitle(string $title): void\n" +" {\n" +" $this->title = $title;\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Move Yii 1.1 `rules()` to a form model, validator rules, or a service. Keep Active Record focused on persistence: table mapping, properties, relations, and database operations." -msgstr "" +msgstr "Mova o `rules()` do Yii 1.1 para um form model, regras do validator ou um serviço. Mantenha o Active Record focado em persistência: mapeamento de tabelas, propriedades, relações e operações no banco de dados." #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "For more complex applications, consider replacing Active Record-heavy code with repositories and domain objects. That is more work initially, but it avoids carrying Yii 1.1 form and persistence coupling into the new application." -msgstr "" +msgstr "Em aplicações mais complexas, considere substituir o código muito dependente de Active Record por repositórios e objetos de domínio. Dá mais trabalho no início, mas evita carregar o acoplamento entre formulário e persistência do Yii 1.1 para a nova aplicação." #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md msgid "See [Working with databases](../start/databases.md), [Migrations](../databases/db-migrations.md), and [yiisoft/active-record](https://github.com/yiisoft/active-record)." -msgstr "" +msgstr "Veja [Trabalhando com banco de dados](../start/databases.md), [Migrations](../databases/db-migrations.md) e [yiisoft/active-record](https://github.com/yiisoft/active-record)." #. type: Title ## #: ../src/guide/intro/upgrade-from-v1.md #, no-wrap msgid "Database queries and migrations" -msgstr "" +msgstr "Consultas ao banco de dados e migrations" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Yii 1.1 code may use `CDbCriteria`, `CDbCommand`, `CActiveDataProvider`, and `CGridView` data providers. In Yii3, use `yiisoft/db` for database access and query building, and `yiisoft/data` / `yiisoft/yii-dataview` for data readers and widgets." -msgstr "" +msgstr "O código Yii 1.1 pode usar `CDbCriteria`, `CDbCommand`, `CActiveDataProvider` e data providers do `CGridView`. No Yii3, use `yiisoft/db` para acesso ao banco de dados e construção de consultas, e `yiisoft/data` / `yiisoft/yii-dataview` para data readers e widgets." #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Migrations are not compatible across Yii 1.1 and Yii3. For an existing application, create a baseline from the current schema and use Yii3 migrations for new changes." -msgstr "" +msgstr "As migrations não são compatíveis entre o Yii 1.1 e o Yii3. Para uma aplicação existente, crie uma base a partir do esquema atual e use migrations do Yii3 para as novas mudanças." #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "See [Working with databases](../start/databases.md) and [Migrations](../databases/db-migrations.md)." -msgstr "" +msgstr "Veja [Trabalhando com banco de dados](../start/databases.md) e [Migrations](../databases/db-migrations.md)." #. type: Title ## #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "GridView and data widgets" -msgstr "" +msgstr "GridView e widgets de dados" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Yii 1.1 `CGridView` is often configured with `CActiveDataProvider`:" -msgstr "" +msgstr "O `CGridView` do Yii 1.1 costuma ser configurado com `CActiveDataProvider`:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v1.md @@ -923,11 +1161,21 @@ msgid "" " ],\n" "]);\n" msgstr "" +"$this->widget('zii.widgets.grid.CGridView', [\n" +" 'dataProvider' => $dataProvider,\n" +" 'columns' => [\n" +" 'id',\n" +" 'title',\n" +" [\n" +" 'class' => 'CButtonColumn',\n" +" ],\n" +" ],\n" +"]);\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Yii3 uses [yiisoft/yii-dataview](https://github.com/yiisoft/yii-dataview):" -msgstr "" +msgstr "O Yii3 usa o [yiisoft/yii-dataview](https://github.com/yiisoft/yii-dataview):" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v1.md @@ -950,22 +1198,38 @@ msgid "" " new ActionColumn(),\n" " );\n" msgstr "" +"use Yiisoft\\Data\\Reader\\ReadableDataInterface;\n" +"use Yiisoft\\Yii\\DataView\\Column\\DataColumn;\n" +"use Yiisoft\\Yii\\DataView\\GridView\\Column\\ActionColumn;\n" +"use Yiisoft\\Yii\\DataView\\GridView\\GridView;\n" +"\n" +"/**\n" +" * @var ReadableDataInterface $dataReader\n" +" */\n" +"\n" +"echo GridView::widget()\n" +" ->dataReader($dataReader)\n" +" ->columns(\n" +" new DataColumn('id'),\n" +" new DataColumn('title'),\n" +" new ActionColumn(),\n" +" );\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Replace the old data provider with a query service that returns a data reader. Model filters as validator rules and route or query parameters." -msgstr "" +msgstr "Substitua o antigo data provider por um serviço de consulta que retorne um data reader. Modele os filtros como regras do validator e parâmetros de rota ou de consulta." #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "See [Using htmx for partial reloads](../../cookbook/using-htmx-for-partial-reloads.md) and [yii-dataview GridView docs](https://github.com/yiisoft/yii-dataview/blob/master/docs/en/guide/gridview.md)." -msgstr "" +msgstr "Veja [Usando htmx para recarregamentos parciais](../../cookbook/using-htmx-for-partial-reloads.md) e a [documentação do GridView do yii-dataview](https://github.com/yiisoft/yii-dataview/blob/master/docs/en/guide/gridview.md)." #. type: Title ## #: ../src/guide/intro/upgrade-from-v1.md #, no-wrap msgid "URL management" -msgstr "" +msgstr "Gerenciamento de URLs" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v1.md @@ -974,6 +1238,8 @@ msgid "" "echo CHtml::link('View', ['post/view', 'id' => $post->id]);\n" "$url = Yii::app()->createUrl('post/view', ['id' => $post->id]);\n" msgstr "" +"echo CHtml::link('View', ['post/view', 'id' => $post->id]);\n" +"$url = Yii::app()->createUrl('post/view', ['id' => $post->id]);\n" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v1.md @@ -986,27 +1252,33 @@ msgid "" "\n" "echo Html::a('View', $url)->render();\n" msgstr "" +"use Yiisoft\\Html\\Html;\n" +"use Yiisoft\\Router\\UrlGeneratorInterface;\n" +"\n" +"$url = $urlGenerator->generate('post/view', ['id' => $post->getId()]);\n" +"\n" +"echo Html::a('View', $url)->render();\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Prefer named routes. They make views and GridView action columns easier to design and maintain." -msgstr "" +msgstr "Prefira rotas nomeadas. Elas tornam as views e as colunas de action do GridView mais fáceis de projetar e manter." #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "See [Routing and URL generation](../runtime/routing.md)." -msgstr "" +msgstr "Veja [Roteamento e geração de URLs](../runtime/routing.md)." #. type: Title ## #: ../src/guide/intro/upgrade-from-v1.md #, no-wrap msgid "Filters, access control, and authentication" -msgstr "" +msgstr "Filtros, controle de acesso e autenticação" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Yii 1.1 controller filters are controller methods or filter classes:" -msgstr "" +msgstr "Os filtros de controller do Yii 1.1 são métodos do controller ou classes de filtro:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v1.md @@ -1019,64 +1291,69 @@ msgid "" " ];\n" "}\n" msgstr "" +"public function filters()\n" +"{\n" +" return [\n" +" 'accessControl',\n" +" ];\n" +"}\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Yii3 uses middleware and focused packages. Move authentication, authorization, CSRF, locale detection, and request body parsing out of controllers and into middleware or services." -msgstr "" +msgstr "O Yii3 usa middleware e pacotes focados. Mova autenticação, autorização, CSRF, detecção de idioma e parsing do corpo da requisição para fora dos controllers, em middlewares ou serviços." #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md msgid "See [Middleware](../structure/middleware.md), [Authentication](../security/authentication.md), and [Authorization](../security/authorization.md)." -msgstr "" +msgstr "Veja [Middleware](../structure/middleware.md), [Autenticação](../security/authentication.md) e [Autorização](../security/authorization.md)." #. type: Title ## #: ../src/guide/intro/upgrade-from-v1.md #, no-wrap msgid "Widgets, helpers, and extensions" -msgstr "" +msgstr "Widgets, helpers e extensões" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Yii 1.1 widgets and helpers usually depend on Yii-specific base classes such as `CWidget`, `CHtml`, and extension autoloading. In Yii3:" -msgstr "" +msgstr "Os widgets e helpers do Yii 1.1 geralmente dependem de classes base específicas do Yii, como `CWidget` e `CHtml`, e do autoloading de extensões. No Yii3:" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md msgid "replace helper calls with `yiisoft/html`, `yiisoft/arrays`, `yiisoft/strings`, or application helpers;" -msgstr "" +msgstr "substitua as chamadas a helpers por `yiisoft/html`, `yiisoft/arrays`, `yiisoft/strings` ou helpers da aplicação;" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md msgid "replace extensions with Composer packages;" -msgstr "" +msgstr "substitua as extensões por pacotes Composer;" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md msgid "rebuild custom widgets with `yiisoft/widget` or plain services/templates;" -msgstr "" +msgstr "reconstrua widgets personalizados com `yiisoft/widget` ou com serviços/templates simples;" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md msgid "replace jQuery UI and Bootstrap widgets with current frontend packages or Yii3 widget packages where available." -msgstr "" +msgstr "substitua os widgets do jQuery UI e do Bootstrap por pacotes de frontend atuais ou pacotes de widgets do Yii3, quando disponíveis." #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "See [Widgets](../views/widget.md)." -msgstr "" +msgstr "Veja [Widgets](../views/widget.md)." #. type: Title # -#: ../src/guide/intro/upgrade-from-v1.md -#: ../src/guide/tutorial/console-applications.md +#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/tutorial/console-applications.md #, no-wrap msgid "Console applications" -msgstr "" +msgstr "Aplicações de console" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Yii 1.1 console commands extend `CConsoleCommand`:" -msgstr "" +msgstr "Os comandos de console do Yii 1.1 estendem `CConsoleCommand`:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v1.md @@ -1089,11 +1366,17 @@ msgid "" " }\n" "}\n" msgstr "" +"class ReportCommand extends CConsoleCommand\n" +"{\n" +" public function actionSend()\n" +" {\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Yii3 console commands are Symfony Console commands configured as services:" -msgstr "" +msgstr "Os comandos de console do Yii3 são comandos do Symfony Console configurados como serviços:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v1.md @@ -1115,75 +1398,90 @@ msgid "" " }\n" "}\n" msgstr "" +"namespace App\\Console;\n" +"\n" +"use Symfony\\Component\\Console\\Attribute\\AsCommand;\n" +"use Symfony\\Component\\Console\\Command\\Command;\n" +"use Symfony\\Component\\Console\\Input\\InputInterface;\n" +"use Symfony\\Component\\Console\\Output\\OutputInterface;\n" +"\n" +"#[AsCommand(name: 'report/send')]\n" +"final class SendReportCommand extends Command\n" +"{\n" +" protected function execute(InputInterface $input, OutputInterface $output): int\n" +" {\n" +" return Command::SUCCESS;\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md msgid "See [Console applications](../tutorial/console-applications.md)." -msgstr "" +msgstr "Veja [Aplicações de console](../tutorial/console-applications.md)." #. type: Title # #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/tutorial/i18n.md #, no-wrap msgid "Internationalization" -msgstr "" +msgstr "Internacionalização" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "Yii 1.1 message files under `protected/messages` can usually be kept conceptually, but configuration changes. Yii3 uses translator packages and explicit message sources. Move message files into the structure expected by the selected translator message package and inject translation services where needed." -msgstr "" +msgstr "Os arquivos de mensagens do Yii 1.1 em `protected/messages` geralmente podem ser mantidos conceitualmente, mas a configuração muda. O Yii3 usa pacotes de tradução e fontes de mensagens explícitas. Mova os arquivos de mensagens para a estrutura esperada pelo pacote de mensagens do tradutor escolhido e injete os serviços de tradução onde for necessário." #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "See [Internationalization](../tutorial/i18n.md)." -msgstr "" +msgstr "Veja [Internacionalização](../tutorial/i18n.md)." #. type: Title ## #: ../src/guide/intro/upgrade-from-v1.md #, no-wrap msgid "What to refactor before reusing" -msgstr "" +msgstr "O que refatorar antes de reutilizar" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "These Yii 1.1 refactorings make the old behavior easier to understand and reuse:" -msgstr "" +msgstr "Estas refatorações no Yii 1.1 tornam o comportamento antigo mais fácil de entender e reutilizar:" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md msgid "isolate database queries from controllers;" -msgstr "" +msgstr "isole as consultas ao banco de dados dos controllers;" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md msgid "remove direct `Yii::app()` access from domain code;" -msgstr "" +msgstr "remova o acesso direto a `Yii::app()` do código de domínio;" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md msgid "move validation out of Active Record when it describes request input rather than database invariants;" -msgstr "" +msgstr "tire a validação do Active Record quando ela descreve a entrada da requisição, e não invariantes do banco de dados;" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md msgid "replace large controller actions with services;" -msgstr "" +msgstr "substitua actions grandes de controller por serviços;" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md msgid "document all routes and URL rules;" -msgstr "" +msgstr "documente todas as rotas e regras de URL;" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md msgid "add tests around the flows you plan to rebuild first;" -msgstr "" +msgstr "adicione testes em torno dos fluxos que você planeja reconstruir primeiro;" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md msgid "upgrade PHP syntax gradually if the old runtime allows it." -msgstr "" +msgstr "atualize a sintaxe PHP gradualmente, se o runtime antigo permitir." #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md msgid "The goal is not to make Yii 1.1 look like Yii3. The goal is to reduce hidden coupling before the code crosses the framework boundary." -msgstr "" +msgstr "O objetivo não é fazer o Yii 1.1 parecer com o Yii3. O objetivo é reduzir o acoplamento oculto antes que o código cruze a fronteira do framework." diff --git a/_translations/po/pt-BR/guide_intro_upgrade-from-v2.md.po b/_translations/po/pt-BR/guide_intro_upgrade-from-v2.md.po index e4ede143..cff915a9 100644 --- a/_translations/po/pt-BR/guide_intro_upgrade-from-v2.md.po +++ b/_translations/po/pt-BR/guide_intro_upgrade-from-v2.md.po @@ -8,31 +8,27 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-09-25 14:35+0000\n" "PO-Revision-Date: 2026-09-25 14:35+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/cookbook/deployment/angie-docker-proxy.md -#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +#: ../src/cookbook/deployment/angie-docker-proxy.md ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "Project structure" -msgstr "" +msgstr "Estrutura do projeto" #. type: Title ### -#: ../src/cookbook/making-http-requests.md ../src/guide/index.md -#: ../src/guide/intro/upgrade-from-v2.md ../src/guide/testing/overview.md -#: ../src/guide/tutorial/docker.md +#: ../src/cookbook/making-http-requests.md ../src/guide/index.md ../src/guide/intro/upgrade-from-v2.md ../src/guide/testing/overview.md ../src/guide/tutorial/docker.md #, no-wrap msgid "Testing" msgstr "Testes" #. type: Fenced code block (json) -#: ../src/guide/concept/autoloading.md ../src/guide/intro/upgrade-from-v1.md -#: ../src/guide/intro/upgrade-from-v2.md +#: ../src/guide/concept/autoloading.md ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "" "{\n" @@ -43,6 +39,13 @@ msgid "" " }\n" "}\n" msgstr "" +"{\n" +" \"autoload\": {\n" +" \"psr-4\": {\n" +" \"App\\\\\": \"src/\"\n" +" }\n" +" }\n" +"}\n" #. type: Fenced code block (php) #: ../src/guide/concept/configuration.md ../src/guide/intro/upgrade-from-v2.md @@ -61,6 +64,18 @@ msgid "" " ),\n" "];\n" msgstr "" +"use App\\Web;\n" +"use Yiisoft\\Router\\Group;\n" +"use Yiisoft\\Router\\Route;\n" +"\n" +"return [\n" +" Group::create()\n" +" ->routes(\n" +" Route::get('/')\n" +" ->action(Web\\HomePage\\Action::class)\n" +" ->name('home'),\n" +" ),\n" +"];\n" #. type: Title ## #: ../src/guide/index.md ../src/guide/intro/upgrade-from-v2.md @@ -72,44 +87,44 @@ msgstr "APIs REST" #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "Recommended approach" -msgstr "" +msgstr "Abordagem recomendada" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md msgid "For example, instead of reading post archive data directly from several controllers or widgets, create a small service that describes the application need:" -msgstr "" +msgstr "Por exemplo, em vez de ler os dados do arquivo de posts diretamente em vários controllers ou widgets, crie um pequeno serviço que descreva a necessidade da aplicação:" #. type: Title ## #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "Things to learn before starting" -msgstr "" +msgstr "O que aprender antes de começar" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md msgid "[Docker](https://www.docker.com/get-started/). The default Yii3 application template includes Docker configuration. Using it gives each application its own repeatable environment and reduces differences between local development and production." -msgstr "" +msgstr "[Docker](https://www.docker.com/get-started/). O template de aplicação padrão do Yii3 inclui configuração do Docker. Usá-lo dá a cada aplicação seu próprio ambiente reproduzível e reduz as diferenças entre o desenvolvimento local e a produção." #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md msgid "[Environment variables](https://en.wikipedia.org/wiki/Environment_variable). Yii3 templates commonly use them for environment-specific settings and secrets, especially in Docker-based deployments. This follows the same idea as [12-factor app configuration](https://12factor.net/config)." -msgstr "" +msgstr "[Variáveis de ambiente](https://en.wikipedia.org/wiki/Environment_variable). Os templates do Yii3 costumam usá-las para configurações específicas de ambiente e segredos, especialmente em deploys baseados em Docker. Isso segue a mesma ideia da [configuração de aplicações 12-factor](https://12factor.net/config)." #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md msgid "[Actions](../structure/action.md). Yii3 does not require controller inheritance. A route can point to any callable, and the default template uses invokable action classes." -msgstr "" +msgstr "[Actions](../structure/action.md). O Yii3 não exige herança de controller. Uma rota pode apontar para qualquer callable, e o template padrão usa classes de action invocáveis." #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md msgid "Configure your application namespace with PSR-4:" -msgstr "" +msgstr "Configure o namespace da sua aplicação com PSR-4:" #. type: Fenced code block (shell) #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "composer dump-autoload\n" -msgstr "" +msgstr "composer dump-autoload\n" #. type: Fenced code block (text) #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md @@ -122,31 +137,37 @@ msgid "" "src/\n" "tests/\n" msgstr "" +"assets/\n" +"config/\n" +"public/\n" +"runtime/\n" +"src/\n" +"tests/\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md msgid "Typical mappings to consider are:" -msgstr "" +msgstr "Mapeamentos típicos a considerar:" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md msgid "See [Configuration](../concept/configuration.md), [Aliases](../concept/aliases.md), and [Dependency injection container](../concept/di-container.md)." -msgstr "" +msgstr "Veja [Configuração](../concept/configuration.md), [Aliases](../concept/aliases.md) e [Container de injeção de dependência](../concept/di-container.md)." #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md msgid "See [Entry scripts](../structure/entry-script.md) and [Application workflow](../start/workflow.md)." -msgstr "" +msgstr "Veja [Scripts de entrada](../structure/entry-script.md) e [Fluxo da aplicação](../start/workflow.md)." #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md msgid "See [Actions](../structure/action.md), [Middleware](../structure/middleware.md), and [Routing and URL generation](../runtime/routing.md)." -msgstr "" +msgstr "Veja [Actions](../structure/action.md), [Middleware](../structure/middleware.md) e [Roteamento e geração de URLs](../runtime/routing.md)." #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md msgid "See [Request](../runtime/request.md), [Response](../runtime/response.md), [Sessions](../runtime/sessions.md), and [Cookies](../runtime/cookies.md)." -msgstr "" +msgstr "Veja [Requisição](../runtime/request.md), [Resposta](../runtime/response.md), [Sessões](../runtime/sessions.md) e [Cookies](../runtime/cookies.md)." #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md @@ -166,38 +187,51 @@ msgid "" " public ?string $email = null;\n" "}\n" msgstr "" +"use Yiisoft\\FormModel\\FormModel;\n" +"use Yiisoft\\Validator\\Rule\\Email;\n" +"use Yiisoft\\Validator\\Rule\\Required;\n" +"\n" +"final class ContactForm extends FormModel\n" +"{\n" +" #[Required]\n" +" public ?string $name = null;\n" +"\n" +" #[Required]\n" +" #[Email]\n" +" public ?string $email = null;\n" +"}\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md msgid "See [Working with forms](../start/forms.md), [Validating input](https://github.com/yiisoft/validator/blob/master/docs/guide/en/README.md), [yiisoft/form](https://github.com/yiisoft/form), and [yiisoft/form-model](https://github.com/yiisoft/form-model)." -msgstr "" +msgstr "Veja [Trabalhando com formulários](../start/forms.md), [Validando a entrada](https://github.com/yiisoft/validator/blob/master/docs/guide/en/README.md), [yiisoft/form](https://github.com/yiisoft/form) e [yiisoft/form-model](https://github.com/yiisoft/form-model)." #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md msgid "See [Working with databases](../start/databases.md), [Migrations](../databases/db-migrations.md), and [yiisoft/active-record](https://github.com/yiisoft/active-record)." -msgstr "" +msgstr "Veja [Trabalhando com banco de dados](../start/databases.md), [Migrations](../databases/db-migrations.md) e [yiisoft/active-record](https://github.com/yiisoft/active-record)." #. type: Title ## #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "GridView and data widgets" -msgstr "" +msgstr "GridView e widgets de dados" #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md msgid "See [Middleware](../structure/middleware.md), [Authentication](../security/authentication.md), and [Authorization](../security/authorization.md)." -msgstr "" +msgstr "Veja [Middleware](../structure/middleware.md), [Autenticação](../security/authentication.md) e [Autorização](../security/authorization.md)." #. type: Plain text #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md msgid "See [Console applications](../tutorial/console-applications.md)." -msgstr "" +msgstr "Veja [Aplicações de console](../tutorial/console-applications.md)." #. type: Title # #: ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "Upgrading from Version 2.0" -msgstr "" +msgstr "Migrando da versão 2.0" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md @@ -206,122 +240,124 @@ msgid "" "> If you haven't used Yii 2.0, you can skip this section and get directly to \"[getting started](../start/prerequisites.md)\"\n" "> section.\n" msgstr "" +"> Se você não usou o Yii 2.0, pode pular esta seção e ir direto para a seção \"[primeiros passos](../start/prerequisites.md)\"\n" +"> do guia.\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Yii3 keeps many Yii ideas, but it is not a drop-in replacement for Yii 2.0. It uses PHP 8 features, PSR interfaces, dependency injection, explicit package composition, and a different application template. Use your Yii 2.0 experience to design a new Yii3 application deliberately instead of trying to reproduce the old application structure." -msgstr "" +msgstr "O Yii3 mantém muitas ideias do Yii, mas não é um substituto direto do Yii 2.0. Ele usa recursos do PHP 8, interfaces PSR, injeção de dependência, composição explícita de pacotes e um template de aplicação diferente. Use sua experiência com o Yii 2.0 para projetar uma nova aplicação Yii3 de forma deliberada, em vez de tentar reproduzir a estrutura da aplicação antiga." #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "For source applications, compare against:" -msgstr "" +msgstr "Para as aplicações de origem, compare com:" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "[yiisoft/yii2-app-basic](https://github.com/yiisoft/yii2-app-basic)" -msgstr "" +msgstr "[yiisoft/yii2-app-basic](https://github.com/yiisoft/yii2-app-basic)" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "[yiisoft/yii2-app-advanced](https://github.com/yiisoft/yii2-app-advanced)" -msgstr "" +msgstr "[yiisoft/yii2-app-advanced](https://github.com/yiisoft/yii2-app-advanced)" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "For the target structure, compare against:" -msgstr "" +msgstr "Para a estrutura de destino, compare com:" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "[yiisoft/app](https://github.com/yiisoft/app)" -msgstr "" +msgstr "[yiisoft/app](https://github.com/yiisoft/app)" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "[Yii3 guide](../index.md)" -msgstr "" +msgstr "[Guia do Yii3](../index.md)" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Before starting, [check maintenance policy and end-of-life dates for Yii 2.0](https://www.yiiframework.com/release-cycle). Keeping a mature Yii 2.0 application on Yii 2.0 can be a valid choice. A Yii3 project is most useful when you want the new package ecosystem, stricter typing, PSR middleware, and a more explicit architecture." -msgstr "" +msgstr "Antes de começar, [confira a política de manutenção e as datas de fim de vida do Yii 2.0](https://www.yiiframework.com/release-cycle). Manter uma aplicação Yii 2.0 madura no Yii 2.0 pode ser uma escolha válida. Um projeto Yii3 é mais útil quando você quer o novo ecossistema de pacotes, tipagem mais rigorosa, middleware PSR e uma arquitetura mais explícita." #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Think of the work as building a Yii3 application that is informed by the old one. The old project tells you which routes, forms, database tables, business rules, and user workflows matter. The Yii3 project should decide again where these responsibilities belong." -msgstr "" +msgstr "Pense no trabalho como a construção de uma aplicação Yii3 guiada pela antiga. O projeto antigo diz quais rotas, formulários, tabelas do banco de dados, regras de negócio e fluxos dos usuários importam. O projeto Yii3 deve decidir de novo onde cada uma dessas responsabilidades fica." #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Build it in vertical slices:" -msgstr "" +msgstr "Construa em vertical slices:" #. type: Bullet: '1. ' #: ../src/guide/intro/upgrade-from-v2.md msgid "Create a new Yii3 application with `yiisoft/app`." -msgstr "" +msgstr "Crie uma nova aplicação Yii3 com `yiisoft/app`." #. type: Bullet: '2. ' #: ../src/guide/intro/upgrade-from-v2.md msgid "Configure Composer autoloading and add only the code needed for the slice you are building." -msgstr "" +msgstr "Configure o autoloading do Composer e adicione só o código necessário para o slice que você está construindo." #. type: Bullet: '3. ' #: ../src/guide/intro/upgrade-from-v2.md msgid "Define configuration and routes before writing actions." -msgstr "" +msgstr "Defina a configuração e as rotas antes de escrever as actions." #. type: Bullet: '4. ' #: ../src/guide/intro/upgrade-from-v2.md msgid "Build one request flow at a time: route, action, input model, service, persistence, view, assets, tests." -msgstr "" +msgstr "Construa um fluxo de requisição por vez: rota, action, modelo de entrada, serviço, persistência, view, assets, testes." #. type: Bullet: '5. ' #: ../src/guide/intro/upgrade-from-v2.md msgid "Keep the Yii 2.0 application running until each flow is verified in Yii3." -msgstr "" +msgstr "Mantenha a aplicação Yii 2.0 rodando até cada fluxo ser verificado no Yii3." #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Avoid moving the whole directory tree first. Yii3's defaults are intentionally different, and a mechanical copy tends to preserve Yii 2.0 service-locator assumptions. Prefer small, reviewed decisions over carrying old structure forward because it is familiar." -msgstr "" +msgstr "Evite mover toda a árvore de diretórios primeiro. Os padrões do Yii3 são intencionalmente diferentes, e uma cópia mecânica tende a preservar as suposições de service locator do Yii 2.0. Prefira decisões pequenas e revisadas a carregar a estrutura antiga só porque ela é familiar." #. type: Title ## #: ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "Prepare the Yii 2.0 application" -msgstr "" +msgstr "Prepare a aplicação Yii 2.0" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Useful preparation can happen before the Yii3 application is ready. These refactorings improve the Yii 2.0 project itself and make the later rewrite less dependent on hidden framework state:" -msgstr "" +msgstr "Uma preparação útil pode acontecer antes de a aplicação Yii3 estar pronta. Estas refatorações melhoram o próprio projeto Yii 2.0 e deixam a reescrita posterior menos dependente de estado oculto do framework:" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "Replace `Yii::$app` access in reusable code with constructor arguments where practical. If a full dependency injection refactoring is too large, keep `Yii::$app` calls near controllers and widgets, then pass values and services to lower-level code explicitly." -msgstr "" +msgstr "Substitua o acesso a `Yii::$app` no código reutilizável por argumentos do construtor onde for viável. Se uma refatoração completa para injeção de dependência for grande demais, mantenha as chamadas a `Yii::$app` perto de controllers e widgets, e passe valores e serviços explicitamente para o código de nível mais baixo." #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "Introduce repositories or query services for database reads that are currently scattered across controllers, views, widgets, and Active Record methods. Yii3 does not require Active Record for persistence, so a repository boundary gives you a natural place to change the implementation later." -msgstr "" +msgstr "Introduza repositórios ou serviços de consulta para as leituras do banco de dados hoje espalhadas por controllers, views, widgets e métodos do Active Record. O Yii3 não exige Active Record para persistência, então uma fronteira de repositório dá a você um lugar natural para trocar a implementação depois." #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "Separate business rules from framework infrastructure. Domain code that does not extend Yii classes, read global application state, or render views is much easier to reuse or rewrite." -msgstr "" +msgstr "Separe as regras de negócio da infraestrutura do framework. Código de domínio que não estende classes do Yii, não lê o estado global da aplicação nem renderiza views é muito mais fácil de reutilizar ou reescrever." #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "Move reusable behavior into Yii 2.0 components or services instead of keeping it inside large controllers and Active Record classes. Yii3 services are configured and injected differently, but the responsibility boundary is similar." -msgstr "" +msgstr "Mova o comportamento reutilizável para componentes ou serviços do Yii 2.0 em vez de mantê-lo dentro de controllers e classes Active Record grandes. Os serviços do Yii3 são configurados e injetados de outra forma, mas a fronteira de responsabilidade é parecida." #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "Add tests around routes and workflows you plan to rebuild first. They become the executable specification for the Yii3 slice." -msgstr "" +msgstr "Adicione testes em torno das rotas e fluxos que você planeja reconstruir primeiro. Eles se tornam a especificação executável do slice Yii3." #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v2.md @@ -340,102 +376,114 @@ msgid "" " }\n" "}\n" msgstr "" +"final class PostRepository\n" +"{\n" +" public function getArchive(): array\n" +" {\n" +" // ...\n" +" }\n" +"\n" +" public function getTopForFrontPage(int $limit = 10): array\n" +" {\n" +" // ...\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "The Yii3 implementation may still use Active Record, or it may use `yiisoft/db` queries. The important point is that controllers and views no longer need to know that detail." -msgstr "" +msgstr "A implementação no Yii3 ainda pode usar Active Record, ou pode usar consultas do `yiisoft/db`. O importante é que controllers e views não precisem mais conhecer esse detalhe." #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Some Yii3 application-template choices are worth learning before you start moving features:" -msgstr "" +msgstr "Vale a pena conhecer algumas escolhas do template de aplicação do Yii3 antes de começar a mover funcionalidades:" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "[Application structure](../structure/overview.md). Yii3's default structure is different from Yii 2.0. The structure is flexible, but start with the Yii3 template and change it only when the application needs it." -msgstr "" +msgstr "[Estrutura da aplicação](../structure/overview.md). A estrutura padrão do Yii3 é diferente da do Yii 2.0. Ela é flexível, mas comece com o template do Yii3 e altere-o apenas quando a aplicação precisar." #. type: Title ## #: ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "PHP requirements" -msgstr "" +msgstr "Requisitos de PHP" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Yii3 application templates require PHP 8.2 or above. As a result, application code can use language features that were not common in Yii 2.0 applications:" -msgstr "" +msgstr "Os templates de aplicação do Yii3 exigem PHP 8.2 ou superior. Com isso, o código da aplicação pode usar recursos da linguagem que não eram comuns em aplicações Yii 2.0:" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "[Type declarations](https://www.php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration)" -msgstr "" +msgstr "[Declarações de tipo](https://www.php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration)" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "[Return type declarations](https://www.php.net/manual/en/functions.returning-values.php#functions.returning-values.type-declaration)" -msgstr "" +msgstr "[Declarações de tipo de retorno](https://www.php.net/manual/en/functions.returning-values.php#functions.returning-values.type-declaration)" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "[Class constant visibility](https://www.php.net/manual/en/language.oop5.constants.php)" -msgstr "" +msgstr "[Visibilidade de constantes de classe](https://www.php.net/manual/en/language.oop5.constants.php)" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "[Named arguments](https://www.php.net/manual/en/functions.arguments.php#functions.named-arguments)" -msgstr "" +msgstr "[Argumentos nomeados](https://www.php.net/manual/en/functions.arguments.php#functions.named-arguments)" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "[Anonymous classes](https://www.php.net/manual/en/language.oop5.anonymous.php)" -msgstr "" +msgstr "[Classes anônimas](https://www.php.net/manual/en/language.oop5.anonymous.php)" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "[::class](https://www.php.net/manual/en/language.oop5.basic.php#language.oop5.basic.class.class)" -msgstr "" +msgstr "[::class](https://www.php.net/manual/en/language.oop5.basic.php#language.oop5.basic.class.class)" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "[Generators](https://www.php.net/manual/en/language.generators.php)" -msgstr "" +msgstr "[Generators](https://www.php.net/manual/en/language.generators.php)" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "[Variadic functions](https://www.php.net/manual/en/functions.arguments.php#functions.variable-arg-list)" -msgstr "" +msgstr "[Funções variádicas](https://www.php.net/manual/en/functions.arguments.php#functions.variable-arg-list)" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "[Readonly properties](https://www.php.net/manual/en/language.oop5.properties.php#language.oop5.properties.readonly-properties)" -msgstr "" +msgstr "[Propriedades readonly](https://www.php.net/manual/en/language.oop5.properties.php#language.oop5.properties.readonly-properties)" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "[Readonly classes](https://www.php.net/manual/en/language.oop5.basic.php#language.oop5.basic.class.readonly)" -msgstr "" +msgstr "[Classes readonly](https://www.php.net/manual/en/language.oop5.basic.php#language.oop5.basic.class.readonly)" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "[Constructor property promotion](https://www.php.net/manual/en/language.oop5.decon.php#language.oop5.decon.constructor.promotion)" -msgstr "" +msgstr "[Promoção de propriedades no construtor](https://www.php.net/manual/en/language.oop5.decon.php#language.oop5.decon.constructor.promotion)" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "[Attributes](https://www.php.net/manual/en/language.attributes.php)" -msgstr "" +msgstr "[Atributos](https://www.php.net/manual/en/language.attributes.php)" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Run static analysis and tests on Yii 2.0 before reusing code in Yii3. Code with explicit types, small services, and few implicit `Yii::$app` dependencies is easier to understand and easier to place in the new application." -msgstr "" +msgstr "Rode análise estática e testes no Yii 2.0 antes de reutilizar código no Yii3. Código com tipos explícitos, serviços pequenos e poucas dependências implícitas de `Yii::$app` é mais fácil de entender e de encaixar na nova aplicação." #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Yii 2.0 applications commonly keep framework roles in top-level directories:" -msgstr "" +msgstr "Aplicações Yii 2.0 costumam manter os papéis do framework em diretórios de primeiro nível:" #. type: Fenced code block (text) #: ../src/guide/intro/upgrade-from-v2.md @@ -451,11 +499,20 @@ msgid "" "web/\n" "widgets/\n" msgstr "" +"assets/\n" +"commands/\n" +"config/\n" +"controllers/\n" +"models/\n" +"runtime/\n" +"views/\n" +"web/\n" +"widgets/\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "The Yii 2.0 advanced template splits the same roles by application:" -msgstr "" +msgstr "O template advanced do Yii 2.0 divide os mesmos papéis por aplicação:" #. type: Fenced code block (text) #: ../src/guide/intro/upgrade-from-v2.md @@ -466,11 +523,15 @@ msgid "" "console/\n" "frontend/\n" msgstr "" +"backend/\n" +"common/\n" +"console/\n" +"frontend/\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "The current Yii3 application template is organized around source code, configuration, public files, and runtime files:" -msgstr "" +msgstr "O template de aplicação atual do Yii3 é organizado em torno do código-fonte, da configuração, dos arquivos públicos e dos arquivos de runtime:" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md @@ -487,43 +548,53 @@ msgid "" "| `commands/` | `console/controllers/` | `src/Console/*Command.php` |\n" "| `config/*.php` | app and common config files | `config/common`, `config/web`, `config/console`, `config/environments` |\n" msgstr "" +"| Yii 2.0 basic | Yii 2.0 advanced | Yii3 |\n" +"|---------------|------------------|------|\n" +"| `controllers/` | `frontend/controllers/`, `backend/controllers/` | `src/Web/*/Action.php` ou classes no estilo controller |\n" +"| `models/` | `common/models/`, models específicos de cada app | `src/Domain`, `src/Shared`, `src/Web/*` ou `src/Db`, conforme a responsabilidade |\n" +"| `views/` | `frontend/views/`, `backend/views/` | templates perto da funcionalidade, por exemplo `src/Web/HomePage/template.php` |\n" +"| `views/layouts/` | diretórios de layout de cada app | classes/templates de layout, por exemplo `src/Web/Shared/Layout/Main` |\n" +"| `assets/` | asset bundles de cada app | `assets/` para os arquivos-fonte e `src/Web/.../*Asset.php` para os bundles |\n" +"| `web/` | `frontend/web/`, `backend/web/` | `public/` |\n" +"| `commands/` | `console/controllers/` | `src/Console/*Command.php` |\n" +"| `config/*.php` | arquivos de configuração do app e comuns | `config/common`, `config/web`, `config/console`, `config/environments` |\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "There is no single required layout. The important change is that Yii3 applications should group code by responsibility and make dependencies explicit. If you are coming from the advanced template, treat `frontend` and `backend` as separate web contexts. Shared domain code can live in `src/Shared` or in application-specific packages." -msgstr "" +msgstr "Não existe um layout obrigatório único. A mudança importante é que aplicações Yii3 devem agrupar o código por responsabilidade e tornar as dependências explícitas. Se você vem do template advanced, trate `frontend` e `backend` como contextos web separados. O código de domínio compartilhado pode ficar em `src/Shared` ou em pacotes específicos da aplicação." #. type: Title ## #: ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "Composer and autoloading" -msgstr "" +msgstr "Composer e autoloading" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Yii 2.0 applications usually require `vendor/autoload.php` and `vendor/yiisoft/yii2/Yii.php` in `web/index.php`. Yii3 applications require only Composer's autoloader and application bootstrap code." -msgstr "" +msgstr "Aplicações Yii 2.0 geralmente fazem require de `vendor/autoload.php` e `vendor/yiisoft/yii2/Yii.php` em `web/index.php`. Aplicações Yii3 precisam apenas do autoloader do Composer e do código de bootstrap da aplicação." #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Then rebuild Composer autoload files:" -msgstr "" +msgstr "Depois, reconstrua os arquivos de autoload do Composer:" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Install Yii3 packages intentionally. Yii3 is split into focused packages, so features such as database access, forms, validation, assets, data widgets, authentication, and caching are separate Composer dependencies." -msgstr "" +msgstr "Instale os pacotes Yii3 de forma intencional. O Yii3 é dividido em pacotes focados, então funcionalidades como acesso ao banco de dados, formulários, validação, assets, widgets de dados, autenticação e cache são dependências separadas do Composer." #. type: Title ## #: ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "Configuration and services" -msgstr "" +msgstr "Configuração e serviços" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "In Yii 2.0, many services are configured as application components and accessed through the service locator:" -msgstr "" +msgstr "No Yii 2.0, muitos serviços são configurados como componentes da aplicação e acessados pelo service locator:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v2.md @@ -533,11 +604,14 @@ msgid "" "$db = Yii::$app->db;\n" "$url = Yii::$app->urlManager->createUrl(['post/view', 'id' => $id]);\n" msgstr "" +"$cache = Yii::$app->cache;\n" +"$db = Yii::$app->db;\n" +"$url = Yii::$app->urlManager->createUrl(['post/view', 'id' => $id]);\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "In Yii3, services are configured for the container and injected where they are needed:" -msgstr "" +msgstr "No Yii3, os serviços são configurados no container e injetados onde são necessários:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v2.md @@ -557,62 +631,75 @@ msgid "" " }\n" "}\n" msgstr "" +"use Psr\\SimpleCache\\CacheInterface;\n" +"use Yiisoft\\Db\\Connection\\ConnectionInterface;\n" +"use Yiisoft\\Router\\UrlGeneratorInterface;\n" +"\n" +"final readonly class PostService\n" +"{\n" +" public function __construct(\n" +" private ConnectionInterface $db,\n" +" private CacheInterface $cache,\n" +" private UrlGeneratorInterface $urlGenerator,\n" +" ) {\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Move configuration in groups:" -msgstr "" +msgstr "Mova a configuração por grupos:" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "aliases to `config/common/aliases.php`;" -msgstr "" +msgstr "aliases para `config/common/aliases.php`;" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "route definitions to `config/common/routes.php`;" -msgstr "" +msgstr "definições de rotas para `config/common/routes.php`;" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "shared service definitions to `config/common/di/*.php`;" -msgstr "" +msgstr "definições de serviços compartilhadas para `config/common/di/*.php`;" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "web-only service definitions to `config/web/di/*.php`;" -msgstr "" +msgstr "definições de serviços apenas para web para `config/web/di/*.php`;" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "console parameters and commands to `config/console/*.php`;" -msgstr "" +msgstr "parâmetros e comandos de console para `config/console/*.php`;" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "shared parameters to `config/common/params.php`;" -msgstr "" +msgstr "parâmetros compartilhados para `config/common/params.php`;" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "environment overrides to `config/environments`." -msgstr "" +msgstr "sobrescritas por ambiente para `config/environments`." #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "The default template's `di-console` group reuses shared definitions from `config/common/di/*.php`. If you need console-only container definitions, add the corresponding files to the `di-console` group in `config/configuration.php` and rebuild the merge plan." -msgstr "" +msgstr "O grupo `di-console` do template padrão reutiliza as definições compartilhadas de `config/common/di/*.php`. Se você precisar de definições de container apenas para o console, adicione os arquivos correspondentes ao grupo `di-console` em `config/configuration.php` e reconstrua o merge plan." #. type: Title ## #: ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "Entry script and bootstrap" -msgstr "" +msgstr "Script de entrada e bootstrap" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "A Yii 2.0 basic entry script commonly creates the application directly:" -msgstr "" +msgstr "Um script de entrada do template basic do Yii 2.0 geralmente cria a aplicação diretamente:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v2.md @@ -628,22 +715,31 @@ msgid "" "\n" "(new yii\\web\\Application($config))->run();\n" msgstr "" +"defined('YII_DEBUG') or define('YII_DEBUG', true);\n" +"defined('YII_ENV') or define('YII_ENV', 'dev');\n" +"\n" +"require __DIR__ . '/../vendor/autoload.php';\n" +"require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php';\n" +"\n" +"$config = require __DIR__ . '/../config/web.php';\n" +"\n" +"(new yii\\web\\Application($config))->run();\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "In Yii3, use the application template entry script as the source of truth. It loads Composer and bootstraps the configured application runner. Avoid recreating the old `yii\\web\\Application` pattern in `public/index.php`; put configuration in config files and dependencies in the container." -msgstr "" +msgstr "No Yii3, use o script de entrada do template de aplicação como fonte da verdade. Ele carrega o Composer e inicializa o runner da aplicação configurada. Evite recriar o antigo padrão `yii\\web\\Application` em `public/index.php`; coloque a configuração nos arquivos de configuração e as dependências no container." #. type: Title ## #: ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "Controllers, actions, and routing" -msgstr "" +msgstr "Controllers, actions e roteamento" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Yii 2.0 routes usually point to controller action methods:" -msgstr "" +msgstr "As rotas do Yii 2.0 geralmente apontam para métodos de action de controllers:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v2.md @@ -661,11 +757,22 @@ msgid "" " }\n" "}\n" msgstr "" +"namespace app\\controllers;\n" +"\n" +"use yii\\web\\Controller;\n" +"\n" +"final class SiteController extends Controller\n" +"{\n" +" public function actionIndex(): string\n" +" {\n" +" return $this->render('index');\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Yii3 does not require controller base classes. The current application template uses invokable action classes:" -msgstr "" +msgstr "O Yii3 não exige classes base de controller. O template de aplicação atual usa classes de action invocáveis:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v2.md @@ -689,27 +796,44 @@ msgid "" " }\n" "}\n" msgstr "" +"namespace App\\Web\\HomePage;\n" +"\n" +"use Psr\\Http\\Message\\ResponseInterface;\n" +"use Yiisoft\\Yii\\View\\Renderer\\WebViewRenderer;\n" +"\n" +"final readonly class Action\n" +"{\n" +" public function __construct(\n" +" private WebViewRenderer $viewRenderer,\n" +" ) {\n" +" }\n" +"\n" +" public function __invoke(): ResponseInterface\n" +" {\n" +" return $this->viewRenderer->render(__DIR__ . '/template');\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Routes are explicit:" -msgstr "" +msgstr "As rotas são explícitas:" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "When redesigning a controller flow, list all Yii 2.0 actions and create named routes for the flows you still need. Then implement each flow as an invokable class or a controller-like service. Constructor injection replaces calls to `Yii::$app` and controller properties." -msgstr "" +msgstr "Ao redesenhar o fluxo de um controller, liste todas as actions do Yii 2.0 e crie rotas nomeadas para os fluxos de que você ainda precisa. Depois, implemente cada fluxo como uma classe invocável ou um serviço no estilo controller. A injeção pelo construtor substitui as chamadas a `Yii::$app` e as propriedades do controller." #. type: Title ## #: ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "Requests, responses, sessions, and cookies" -msgstr "" +msgstr "Requisições, respostas, sessões e cookies" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Yii 2.0 actions often read request data and write response data through application components:" -msgstr "" +msgstr "As actions do Yii 2.0 frequentemente leem os dados da requisição e escrevem os dados da resposta por meio de componentes da aplicação:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v2.md @@ -720,11 +844,15 @@ msgid "" "\n" "return $this->redirect(['post/view', 'id' => $id]);\n" msgstr "" +"$id = Yii::$app->request->get('id');\n" +"Yii::$app->session->setFlash('success', 'Saved.');\n" +"\n" +"return $this->redirect(['post/view', 'id' => $id]);\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Yii3 uses PSR-7 request and response objects and injectable services:" -msgstr "" +msgstr "O Yii3 usa objetos de requisição e resposta PSR-7 e serviços injetáveis:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v2.md @@ -755,22 +883,46 @@ msgid "" " }\n" "}\n" msgstr "" +"use Psr\\Http\\Message\\ResponseInterface;\n" +"use Psr\\Http\\Message\\ResponseFactoryInterface;\n" +"use Psr\\Http\\Message\\ServerRequestInterface;\n" +"use Yiisoft\\Http\\Status;\n" +"use Yiisoft\\Router\\UrlGeneratorInterface;\n" +"\n" +"final readonly class SavePostAction\n" +"{\n" +" public function __construct(\n" +" private ResponseFactoryInterface $responseFactory,\n" +" private UrlGeneratorInterface $urlGenerator,\n" +" ) {\n" +" }\n" +"\n" +" public function __invoke(ServerRequestInterface $request): ResponseInterface\n" +" {\n" +" $id = (int) ($request->getQueryParams()['id'] ?? 0);\n" +" $url = $this->urlGenerator->generate('post/view', ['id' => $id]);\n" +"\n" +" return $this->responseFactory\n" +" ->createResponse(Status::SEE_OTHER)\n" +" ->withHeader('Location', $url);\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Design request handling early because it affects forms, filters, REST endpoints, redirects, and tests." -msgstr "" +msgstr "Pense no tratamento de requisições logo no início, porque ele afeta formulários, filtros, endpoints REST, redirecionamentos e testes." #. type: Title ## #: ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "Views, layouts, assets, and URLs" -msgstr "" +msgstr "Views, layouts, assets e URLs" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "In Yii 2.0, controller rendering finds files under `views/{controller}` and layouts under `views/layouts`:" -msgstr "" +msgstr "No Yii 2.0, a renderização do controller procura arquivos em `views/{controller}` e layouts em `views/layouts`:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v2.md @@ -780,11 +932,14 @@ msgid "" " 'model' => $model,\n" "]);\n" msgstr "" +"return $this->render('view', [\n" +" 'model' => $model,\n" +"]);\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "In Yii3, the template path is explicit in the action:" -msgstr "" +msgstr "No Yii3, o caminho do template é explícito na action:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v2.md @@ -794,11 +949,14 @@ msgid "" " 'post' => $post,\n" "]);\n" msgstr "" +"return $this->viewRenderer->render(__DIR__ . '/view', [\n" +" 'post' => $post,\n" +"]);\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "A Yii3 template receives a `Yiisoft\\View\\WebView` instance as `$this`:" -msgstr "" +msgstr "Um template do Yii3 recebe uma instância de `Yiisoft\\View\\WebView` como `$this`:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v2.md @@ -819,11 +977,25 @@ msgid "" "\n" "

\n" msgstr "" +"use App\\Shared\\ApplicationParams;\n" +"use Yiisoft\\Html\\Html;\n" +"use Yiisoft\\View\\WebView;\n" +"\n" +"/**\n" +" * @var WebView $this\n" +" * @var ApplicationParams $applicationParams\n" +" * @var string $title\n" +" */\n" +"\n" +"$this->setTitle($title . ' - ' . $applicationParams->name);\n" +"?>\n" +"\n" +"

\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Asset bundles move from `yii\\web\\AssetBundle` to `Yiisoft\\Assets\\AssetBundle`:" -msgstr "" +msgstr "Os asset bundles passam de `yii\\web\\AssetBundle` para `Yiisoft\\Assets\\AssetBundle`:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v2.md @@ -844,11 +1016,25 @@ msgid "" " ];\n" "}\n" msgstr "" +"namespace App\\Web\\Shared\\Layout\\Main;\n" +"\n" +"use Yiisoft\\Assets\\AssetBundle;\n" +"\n" +"final class MainAsset extends AssetBundle\n" +"{\n" +" public ?string $basePath = '@assets/main';\n" +" public ?string $baseUrl = '@assetsUrl/main';\n" +" public ?string $sourcePath = '@assetsSource/main';\n" +"\n" +" public array $css = [\n" +" 'site.css',\n" +" ];\n" +"}\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Register assets in a layout or view via the asset manager:" -msgstr "" +msgstr "Registre os assets em um layout ou view pelo gerenciador de assets:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v2.md @@ -859,6 +1045,10 @@ msgid "" "$this->addCssFiles($assetManager->getCssFiles());\n" "$this->addJsFiles($assetManager->getJsFiles());\n" msgstr "" +"$assetManager->register(MainAsset::class);\n" +"\n" +"$this->addCssFiles($assetManager->getCssFiles());\n" +"$this->addJsFiles($assetManager->getJsFiles());\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md @@ -867,28 +1057,30 @@ msgid "" "Replace `yii\\helpers\\Url` and `Yii::$app->urlManager` usage with named routes and\n" "`Yiisoft\\Router\\UrlGeneratorInterface`:\n" msgstr "" +"Substitua o uso de `yii\\helpers\\Url` e `Yii::$app->urlManager` por rotas nomeadas e\n" +"`Yiisoft\\Router\\UrlGeneratorInterface`:\n" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "$url = $urlGenerator->generate('post/view', ['id' => $post->getId()]);\n" -msgstr "" +msgstr "$url = $urlGenerator->generate('post/view', ['id' => $post->getId()]);\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "See [View](../views/view.md), [Assets](../views/asset.md), [Scripts, styles and metatags](../views/script-style-meta.md), and [Template engines](../views/template-engines.md)." -msgstr "" +msgstr "Veja [View](../views/view.md), [Assets](../views/asset.md), [Scripts, estilos e metatags](../views/script-style-meta.md) e [Template engines](../views/template-engines.md)." #. type: Title ## #: ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "Forms and validation" -msgstr "" +msgstr "Formulários e validação" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Yii 2.0 frequently combines form data, labels, validation, and sometimes persistence in a `yii\\base\\Model` or `yii\\db\\ActiveRecord` class:" -msgstr "" +msgstr "O Yii 2.0 frequentemente junta dados do formulário, rótulos, validação e às vezes persistência em uma classe `yii\\base\\Model` ou `yii\\db\\ActiveRecord`:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v2.md @@ -908,42 +1100,55 @@ msgid "" " }\n" "}\n" msgstr "" +"final class ContactForm extends \\yii\\base\\Model\n" +"{\n" +" public $name;\n" +" public $email;\n" +"\n" +" public function rules(): array\n" +" {\n" +" return [\n" +" [['name', 'email'], 'required'],\n" +" ['email', 'email'],\n" +" ];\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Yii3 separates these concerns. Use `yiisoft/form-model` for form data and metadata, and `yiisoft/validator` for rules:" -msgstr "" +msgstr "O Yii3 separa essas responsabilidades. Use `yiisoft/form-model` para os dados e metadados do formulário, e `yiisoft/validator` para as regras:" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "For form rendering, replace `yii\\widgets\\ActiveForm` with `yiisoft/form` fields and form model integration. For input hydration, prefer the form-model and hydrator packages instead of mass-assigning arbitrary request data to persistence objects." -msgstr "" +msgstr "Para a renderização de formulários, substitua `yii\\widgets\\ActiveForm` pelos campos do `yiisoft/form` e pela integração com form models. Para a hidratação da entrada, prefira os pacotes de form model e hydrator em vez de atribuir em massa dados arbitrários da requisição a objetos de persistência." #. type: Title ## #: ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "Active Record and persistence" -msgstr "" +msgstr "Active Record e persistência" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "There are two common Yii3 choices for code that used Yii 2.0 Active Record classes." -msgstr "" +msgstr "Existem duas escolhas comuns no Yii3 para código que usava classes Active Record do Yii 2.0." #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "The first path is architectural: move business logic to services and domain objects, then use repositories for persistence. This is recommended when the Yii 2.0 model contains validation, form scenarios, authorization checks, mailing, file uploads, and database access in the same class." -msgstr "" +msgstr "O primeiro caminho é arquitetural: mova a lógica de negócio para serviços e objetos de domínio e use repositórios para a persistência. Ele é recomendado quando o model do Yii 2.0 contém validação, cenários de formulário, verificações de autorização, envio de e-mails, upload de arquivos e acesso ao banco de dados na mesma classe." #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "The second path is incremental: represent the database model with [yiisoft/active-record](https://github.com/yiisoft/active-record). This is closer to Yii 2.0 and can be significantly faster when your Active Record classes mostly describe tables and relations." -msgstr "" +msgstr "O segundo caminho é incremental: represente o modelo do banco de dados com o [yiisoft/active-record](https://github.com/yiisoft/active-record). Ele é mais próximo do Yii 2.0 e pode ser bem mais rápido quando suas classes Active Record descrevem principalmente tabelas e relações." #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Yii 2.0:" -msgstr "" +msgstr "Yii 2.0:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v2.md @@ -965,11 +1170,26 @@ msgid "" " }\n" "}\n" msgstr "" +"final class Post extends \\yii\\db\\ActiveRecord\n" +"{\n" +" public static function tableName(): string\n" +" {\n" +" return '{{%post}}';\n" +" }\n" +"\n" +" public function rules(): array\n" +" {\n" +" return [\n" +" [['title', 'body'], 'required'],\n" +" ['title', 'string', 'max' => 255],\n" +" ];\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Yii3 Active Record:" -msgstr "" +msgstr "Active Record no Yii3:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v2.md @@ -1004,11 +1224,39 @@ msgid "" " }\n" "}\n" msgstr "" +"use Yiisoft\\ActiveRecord\\ActiveRecord;\n" +"\n" +"final class Post extends ActiveRecord\n" +"{\n" +" protected int $id;\n" +" protected string $title;\n" +" protected string $body;\n" +"\n" +" public function tableName(): string\n" +" {\n" +" return '{{%post}}';\n" +" }\n" +"\n" +" public function getId(): ?int\n" +" {\n" +" return $this->id ?? null;\n" +" }\n" +"\n" +" public function getTitle(): ?string\n" +" {\n" +" return $this->title ?? null;\n" +" }\n" +"\n" +" public function setTitle(string $title): void\n" +" {\n" +" $this->title = $title;\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Do not move Yii 2.0 `rules()` directly into the Active Record class. In Yii3, validation belongs to validator rules, form models, command objects, or services:" -msgstr "" +msgstr "Não mova o `rules()` do Yii 2.0 diretamente para a classe Active Record. No Yii3, a validação pertence a regras do validator, form models, objetos de comando ou serviços:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v2.md @@ -1028,11 +1276,24 @@ msgid "" " public ?string $body = null;\n" "}\n" msgstr "" +"use Yiisoft\\FormModel\\FormModel;\n" +"use Yiisoft\\Validator\\Rule\\Length;\n" +"use Yiisoft\\Validator\\Rule\\Required;\n" +"\n" +"final class PostInput extends FormModel\n" +"{\n" +" #[Required]\n" +" #[Length(max: 255)]\n" +" public ?string $title = null;\n" +"\n" +" #[Required]\n" +" public ?string $body = null;\n" +"}\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Then copy validated data into the record or pass it to an application service:" -msgstr "" +msgstr "Depois, copie os dados validados para o registro ou passe-os para um serviço da aplicação:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v2.md @@ -1042,56 +1303,59 @@ msgid "" "$post->setTitle($input->title);\n" "$post->save();\n" msgstr "" +"$post = new Post();\n" +"$post->setTitle($input->title);\n" +"$post->save();\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "When deciding what to reuse, check each Active Record method:" -msgstr "" +msgstr "Ao decidir o que reutilizar, verifique cada método do Active Record:" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "table mapping and relations can usually move to `yiisoft/active-record`;" -msgstr "" +msgstr "o mapeamento de tabelas e as relações geralmente podem ir para o `yiisoft/active-record`;" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "validation should move to `yiisoft/validator`;" -msgstr "" +msgstr "a validação deve ir para o `yiisoft/validator`;" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "form labels and hints should move to `yiisoft/form-model`;" -msgstr "" +msgstr "rótulos e dicas de formulário devem ir para o `yiisoft/form-model`;" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "search models should become query/data-reader services;" -msgstr "" +msgstr "os search models devem virar serviços de consulta/data reader;" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "business workflows should become services;" -msgstr "" +msgstr "os fluxos de negócio devem virar serviços;" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "events should use PSR-14 events or package-specific events;" -msgstr "" +msgstr "os eventos devem usar eventos PSR-14 ou eventos específicos de pacotes;" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "direct `Yii::$app->db` usage should become injected database dependencies." -msgstr "" +msgstr "o uso direto de `Yii::$app->db` deve virar dependências de banco de dados injetadas." #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Yii 2.0 migrations and Yii3 `yiisoft/db-migration` migrations are not compatible. Start a new migration history or create structure dumps for the current schema, then use Yii3 migrations for future schema changes." -msgstr "" +msgstr "As migrations do Yii 2.0 e as migrations do `yiisoft/db-migration` do Yii3 não são compatíveis. Comece um novo histórico de migrations ou crie dumps da estrutura do esquema atual, e use migrations do Yii3 para as mudanças futuras no esquema." #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Yii 2.0 `GridView` is commonly used with `ActiveDataProvider`:" -msgstr "" +msgstr "O `GridView` do Yii 2.0 costuma ser usado com `ActiveDataProvider`:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v2.md @@ -1110,11 +1374,23 @@ msgid "" " ],\n" "]);\n" msgstr "" +"use yii\\grid\\GridView;\n" +"\n" +"echo GridView::widget([\n" +" 'dataProvider' => $dataProvider,\n" +" 'filterModel' => $searchModel,\n" +" 'columns' => [\n" +" 'id',\n" +" 'title',\n" +" 'created_at:datetime',\n" +" ['class' => 'yii\\grid\\ActionColumn'],\n" +" ],\n" +"]);\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Yii3 uses [yiisoft/yii-dataview](https://github.com/yiisoft/yii-dataview). It renders data from a data reader and uses fluent widget configuration:" -msgstr "" +msgstr "O Yii3 usa o [yiisoft/yii-dataview](https://github.com/yiisoft/yii-dataview). Ele renderiza dados a partir de um data reader e usa configuração fluente do widget:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v2.md @@ -1138,11 +1414,28 @@ msgid "" " new ActionColumn(),\n" " );\n" msgstr "" +"use Yiisoft\\Data\\Reader\\ReadableDataInterface;\n" +"use Yiisoft\\Yii\\DataView\\Column\\DataColumn;\n" +"use Yiisoft\\Yii\\DataView\\GridView\\Column\\ActionColumn;\n" +"use Yiisoft\\Yii\\DataView\\GridView\\GridView;\n" +"\n" +"/**\n" +" * @var ReadableDataInterface $dataReader\n" +" */\n" +"\n" +"echo GridView::widget()\n" +" ->dataReader($dataReader)\n" +" ->columns(\n" +" new DataColumn('id'),\n" +" new DataColumn('title', header: 'Title'),\n" +" new DataColumn('created_at', header: 'Created'),\n" +" new ActionColumn(),\n" +" );\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "For sorting, pagination, filtering, and action URLs, wire the widget to Yii Router:" -msgstr "" +msgstr "Para ordenação, paginação, filtragem e URLs de actions, conecte o widget ao Yii Router:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v2.md @@ -1166,47 +1459,64 @@ msgid "" " ),\n" " );\n" msgstr "" +"use Yiisoft\\Yii\\DataView\\YiiRouter\\ActionColumnUrlConfig;\n" +"use Yiisoft\\Yii\\DataView\\YiiRouter\\ActionColumnUrlCreator;\n" +"use Yiisoft\\Yii\\DataView\\YiiRouter\\UrlCreator;\n" +"use Yiisoft\\Yii\\DataView\\YiiRouter\\UrlParameterProvider;\n" +"\n" +"echo GridView::widget()\n" +" ->dataReader($dataReader)\n" +" ->urlParameterProvider(new UrlParameterProvider($currentRoute))\n" +" ->urlCreator(new UrlCreator($urlGenerator))\n" +" ->columns(\n" +" new DataColumn('id'),\n" +" new DataColumn('title'),\n" +" new ActionColumn(\n" +" urlCreator: new ActionColumnUrlCreator($urlGenerator, $currentRoute),\n" +" urlConfig: new ActionColumnUrlConfig(baseRouteName: 'post'),\n" +" ),\n" +" );\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "A Yii 2.0 search model usually becomes a query service that:" -msgstr "" +msgstr "Um search model do Yii 2.0 geralmente vira um serviço de consulta que:" #. type: Bullet: '1. ' #: ../src/guide/intro/upgrade-from-v2.md msgid "reads filter and sort parameters from the request;" -msgstr "" +msgstr "lê os parâmetros de filtro e ordenação da requisição;" #. type: Bullet: '2. ' #: ../src/guide/intro/upgrade-from-v2.md msgid "validates them with `yiisoft/validator`;" -msgstr "" +msgstr "valida esses parâmetros com `yiisoft/validator`;" #. type: Bullet: '3. ' #: ../src/guide/intro/upgrade-from-v2.md msgid "builds a database query or repository query;" -msgstr "" +msgstr "monta uma consulta ao banco de dados ou ao repositório;" #. type: Bullet: '4. ' #: ../src/guide/intro/upgrade-from-v2.md msgid "exposes a data reader to GridView." -msgstr "" +msgstr "expõe um data reader para o GridView." #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "See [Using htmx for partial reloads](../../cookbook/using-htmx-for-partial-reloads.md) for a complete Yii3 GridView workflow and [yii-dataview GridView docs](https://github.com/yiisoft/yii-dataview/blob/master/docs/en/guide/gridview.md)." -msgstr "" +msgstr "Veja [Usando htmx para recarregamentos parciais](../../cookbook/using-htmx-for-partial-reloads.md) para um fluxo completo de GridView no Yii3 e a [documentação do GridView do yii-dataview](https://github.com/yiisoft/yii-dataview/blob/master/docs/en/guide/gridview.md)." #. type: Title ## #: ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "Filters, middleware, and access control" -msgstr "" +msgstr "Filtros, middleware e controle de acesso" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Yii 2.0 controller filters and behaviors usually look like this:" -msgstr "" +msgstr "Os filtros e behaviors de controller do Yii 2.0 geralmente são assim:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v2.md @@ -1224,23 +1534,33 @@ msgid "" " ];\n" "}\n" msgstr "" +"public function behaviors(): array\n" +"{\n" +" return [\n" +" 'access' => [\n" +" 'class' => \\yii\\filters\\AccessControl::class,\n" +" 'rules' => [\n" +" ['allow' => true, 'roles' => ['@']],\n" +" ],\n" +" ],\n" +" ];\n" +"}\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "In Yii3, request processing is middleware-based. Move cross-cutting concerns such as authentication, authorization, body parsing, locale negotiation, CSRF checks, and error handling to middleware or dedicated services. Keep actions focused on the request flow they implement." -msgstr "" +msgstr "No Yii3, o processamento das requisições é baseado em middleware. Mova responsabilidades transversais, como autenticação, autorização, parsing do corpo, negociação de idioma, verificação de CSRF e tratamento de erros, para middlewares ou serviços dedicados. Mantenha as actions focadas no fluxo de requisição que elas implementam." #. type: Title ## -#: ../src/guide/intro/upgrade-from-v2.md -#: ../src/guide/structure/designing-packages.md +#: ../src/guide/intro/upgrade-from-v2.md ../src/guide/structure/designing-packages.md #, no-wrap msgid "Console commands" -msgstr "" +msgstr "Comandos de console" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Yii 2.0 console commands extend `yii\\console\\Controller`:" -msgstr "" +msgstr "Os comandos de console do Yii 2.0 estendem `yii\\console\\Controller`:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v2.md @@ -1255,11 +1575,19 @@ msgid "" " }\n" "}\n" msgstr "" +"final class ReportController extends \\yii\\console\\Controller\n" +"{\n" +" public function actionSend(): int\n" +" {\n" +" // ...\n" +" return self::EXIT_CODE_NORMAL;\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Yii3 console commands are services in `src/Console`:" -msgstr "" +msgstr "Os comandos de console do Yii3 são serviços em `src/Console`:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v2.md @@ -1282,129 +1610,145 @@ msgid "" " }\n" "}\n" msgstr "" +"namespace App\\Console;\n" +"\n" +"use Symfony\\Component\\Console\\Attribute\\AsCommand;\n" +"use Symfony\\Component\\Console\\Command\\Command;\n" +"use Symfony\\Component\\Console\\Input\\InputInterface;\n" +"use Symfony\\Component\\Console\\Output\\OutputInterface;\n" +"\n" +"#[AsCommand(name: 'report/send')]\n" +"final class SendReportCommand extends Command\n" +"{\n" +" protected function execute(InputInterface $input, OutputInterface $output): int\n" +" {\n" +" // ...\n" +" return Command::SUCCESS;\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Move command dependencies to constructor injection and register commands in console configuration." -msgstr "" +msgstr "Passe as dependências dos comandos para injeção pelo construtor e registre os comandos na configuração de console." #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Yii 2.0 REST controllers, serializers, and response formatters do not move directly to Yii3. Start from PSR-7 responses and explicit routing. Build one resource at a time:" -msgstr "" +msgstr "Os controllers REST, serializers e formatadores de resposta do Yii 2.0 não passam diretamente para o Yii3. Comece pelas respostas PSR-7 e pelo roteamento explícito. Construa um recurso por vez:" #. type: Bullet: '1. ' #: ../src/guide/intro/upgrade-from-v2.md msgid "define routes for collection and item operations;" -msgstr "" +msgstr "defina rotas para as operações de coleção e de item;" #. type: Bullet: '2. ' #: ../src/guide/intro/upgrade-from-v2.md msgid "inject request, persistence, serializer, and response factory dependencies;" -msgstr "" +msgstr "injete as dependências de requisição, persistência, serializer e response factory;" #. type: Bullet: '3. ' #: ../src/guide/intro/upgrade-from-v2.md msgid "validate input with `yiisoft/validator`;" -msgstr "" +msgstr "valide a entrada com `yiisoft/validator`;" #. type: Bullet: '4. ' #: ../src/guide/intro/upgrade-from-v2.md msgid "return JSON responses through Yii3 response helpers or PSR-7 factories;" -msgstr "" +msgstr "retorne respostas JSON pelos helpers de resposta do Yii3 ou por factories PSR-7;" #. type: Bullet: '5. ' #: ../src/guide/intro/upgrade-from-v2.md msgid "move authentication and rate limiting to middleware." -msgstr "" +msgstr "mova a autenticação e o rate limiting para middlewares." #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "See [Response](../runtime/response.md), [Authentication](../security/authentication.md), and [Authorization](../security/authorization.md)." -msgstr "" +msgstr "Veja [Resposta](../runtime/response.md), [Autenticação](../security/authentication.md) e [Autorização](../security/authorization.md)." #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Do not postpone tests until the whole Yii3 application is done. For each new request flow, add:" -msgstr "" +msgstr "Não deixe os testes para quando a aplicação Yii3 inteira estiver pronta. Para cada novo fluxo de requisição, adicione:" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "unit tests for services and validators;" -msgstr "" +msgstr "testes unitários para serviços e validadores;" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "functional tests for actions and middleware;" -msgstr "" +msgstr "testes funcionais para actions e middlewares;" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "end-to-end tests for critical browser flows;" -msgstr "" +msgstr "testes end-to-end para os fluxos críticos no navegador;" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "static analysis for stricter type checks." -msgstr "" +msgstr "análise estática para verificações de tipo mais rigorosas." #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Yii3 code is more explicit, so tests should assert services directly instead of constructing large application component arrays." -msgstr "" +msgstr "O código Yii3 é mais explícito, então os testes devem verificar os serviços diretamente, em vez de montar grandes arrays de componentes da aplicação." #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "See [Testing overview](../testing/overview.md), [Unit tests](../testing/unit.md), [Functional tests](../testing/functional.md), and [End-to-end tests](../testing/end-to-end.md)." -msgstr "" +msgstr "Veja [Visão geral dos testes](../testing/overview.md), [Testes unitários](../testing/unit.md), [Testes funcionais](../testing/functional.md) e [Testes end-to-end](../testing/end-to-end.md)." #. type: Title ## #: ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "Refactoring Yii 2.0 code before reusing it" -msgstr "" +msgstr "Refatorando o código Yii 2.0 antes de reutilizá-lo" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "These changes are useful even if the old application stays on Yii 2.0 for a while:" -msgstr "" +msgstr "Estas mudanças são úteis mesmo que a aplicação antiga continue no Yii 2.0 por um tempo:" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "Replace `Yii::$app` access in domain code with constructor arguments." -msgstr "" +msgstr "Substitua o acesso a `Yii::$app` no código de domínio por argumentos do construtor." #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "Move queries out of controllers and views into repositories or query services." -msgstr "" +msgstr "Tire as consultas dos controllers e views e leve-as para repositórios ou serviços de consulta." #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "Move business workflows out of Active Record classes." -msgstr "" +msgstr "Tire os fluxos de negócio das classes Active Record." #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "Separate form models from persistence models." -msgstr "" +msgstr "Separe os form models dos models de persistência." #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "Add return types and parameter types." -msgstr "" +msgstr "Adicione tipos de retorno e tipos de parâmetros." #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "Replace route arrays scattered in views with named route constants or helper methods." -msgstr "" +msgstr "Substitua arrays de rotas espalhados pelas views por constantes de rotas nomeadas ou métodos helper." #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "Add tests around each flow before rebuilding it in Yii3." -msgstr "" +msgstr "Adicione testes em torno de cada fluxo antes de reconstruí-lo no Yii3." #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "The less framework state your Yii 2.0 code assumes, the easier it is to understand what should be reused and what should be redesigned for Yii3." -msgstr "" +msgstr "Quanto menos estado do framework o seu código Yii 2.0 pressupor, mais fácil fica entender o que deve ser reutilizado e o que deve ser redesenhado para o Yii3." diff --git a/_translations/po/pt-BR/guide_start_databases.md.po b/_translations/po/pt-BR/guide_start_databases.md.po index 95243bd6..956731cd 100644 --- a/_translations/po/pt-BR/guide_start_databases.md.po +++ b/_translations/po/pt-BR/guide_start_databases.md.po @@ -8,25 +8,24 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-10-11 10:37+0000\n" "PO-Revision-Date: 2026-10-11 10:37+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/cookbook/organizing-code/domain.md -#: ../src/cookbook/organizing-code/service.md ../src/guide/start/databases.md +#: ../src/cookbook/organizing-code/domain.md ../src/cookbook/organizing-code/service.md ../src/guide/start/databases.md #, no-wrap msgid "Repository" -msgstr "" +msgstr "Repositório" #. type: Fenced code block (sh) #: ../src/guide/databases/db-migrations.md ../src/guide/start/databases.md #, no-wrap msgid "make composer require yiisoft/db-migration\n" -msgstr "" +msgstr "make composer require yiisoft/db-migration\n" #. type: Fenced code block (php) #: ../src/guide/databases/db-migrations.md ../src/guide/start/databases.md @@ -37,6 +36,10 @@ msgid "" " 'sourceNamespaces' => ['App\\\\Migration'],\n" "],\n" msgstr "" +"'yiisoft/db-migration' => [\n" +" 'newMigrationNamespace' => 'App\\\\Migration',\n" +" 'sourceNamespaces' => ['App\\\\Migration'],\n" +"],\n" #. type: Title # #: ../src/guide/index.md ../src/guide/start/databases.md @@ -53,58 +56,58 @@ msgstr "Roteamento" #. type: Plain text #: ../src/guide/start/databases.md msgid "Yii doesn't dictate using a particular database or storage for your application. There are many ways you can work with relational databases:" -msgstr "" +msgstr "O Yii não impõe um banco de dados ou armazenamento específico para a sua aplicação. Há muitas formas de trabalhar com bancos de dados relacionais:" #. type: Bullet: '- ' #: ../src/guide/start/databases.md msgid "[Yii DB](https://github.com/yiisoft/db)" -msgstr "" +msgstr "[Yii DB](https://github.com/yiisoft/db)" #. type: Bullet: '- ' #: ../src/guide/start/databases.md msgid "[Yii Active Record](https://github.com/yiisoft/active-record)" -msgstr "" +msgstr "[Yii Active Record](https://github.com/yiisoft/active-record)" #. type: Bullet: '- ' #: ../src/guide/start/databases.md msgid "[Cycle](https://github.com/cycle) via [Yii Cycle package](https://github.com/yiisoft/yii-cycle)" -msgstr "" +msgstr "[Cycle](https://github.com/cycle) pelo [pacote Yii Cycle](https://github.com/yiisoft/yii-cycle)" #. type: Bullet: '- ' #: ../src/guide/start/databases.md msgid "[Doctrine](https://www.doctrine-project.org/) via [Yii Doctrine package](https://github.com/stargazer-team/yii-doctrine)" -msgstr "" +msgstr "[Doctrine](https://www.doctrine-project.org/) pelo [pacote Yii Doctrine](https://github.com/stargazer-team/yii-doctrine)" #. type: Bullet: '- ' #: ../src/guide/start/databases.md msgid "[PDO](https://www.php.net/manual/en/book.pdo.php)" -msgstr "" +msgstr "[PDO](https://www.php.net/manual/en/book.pdo.php)" #. type: Plain text #: ../src/guide/start/databases.md msgid "For non-relational ones, there are usually official libraries available:" -msgstr "" +msgstr "Para os não relacionais, geralmente existem bibliotecas oficiais:" #. type: Bullet: '- ' #: ../src/guide/start/databases.md msgid "[ElasticSearch](https://github.com/elastic/elasticsearch-php)" -msgstr "" +msgstr "[ElasticSearch](https://github.com/elastic/elasticsearch-php)" #. type: Bullet: '- ' #: ../src/guide/start/databases.md msgid "[Redis](https://redis.io/docs/latest/develop/clients/php/)" -msgstr "" +msgstr "[Redis](https://redis.io/docs/latest/develop/clients/php/)" #. type: Bullet: ' - ' #: ../src/guide/start/databases.md ../src/internals/000-packages.md msgid "..." -msgstr "" +msgstr "..." #. type: Title ## #: ../src/guide/start/databases.md #, no-wrap msgid "Choosing a data access approach" -msgstr "" +msgstr "Escolhendo uma forma de acesso aos dados" #. type: Plain text #: ../src/guide/start/databases.md @@ -113,6 +116,8 @@ msgid "" "Yii3 keeps database access in optional packages. A new application doesn't get a global `Yii::$app->db` component\n" "or a built-in Active Record layer automatically, so choose the package and boundary that fit your application.\n" msgstr "" +"O Yii3 deixa o acesso ao banco de dados em pacotes opcionais. Uma aplicação nova não ganha automaticamente um componente global `Yii::$app->db`\n" +"nem uma camada de Active Record embutida, então escolha o pacote e a fronteira que fazem sentido para a sua aplicação.\n" #. type: Plain text #: ../src/guide/start/databases.md @@ -122,57 +127,60 @@ msgid "" "connections, commands, schema support, and a query builder. Instead of calling `Yii::$app->db`, configure a\n" "connection as a service and inject `ConnectionInterface` where the database is needed.\n" msgstr "" +"Se você usava a camada de acesso ao banco de dados do Yii 2.0, o `yiisoft/db` é o equivalente mais próximo no Yii3. Ele oferece\n" +"conexões, comandos, suporte a esquema e um query builder. Em vez de chamar `Yii::$app->db`, configure uma\n" +"conexão como serviço e injete `ConnectionInterface` onde o banco de dados for necessário.\n" #. type: Plain text #: ../src/guide/start/databases.md msgid "If you used Yii 2.0 Active Record, you can install `yiisoft/active-record`. It is useful when your model classes mostly describe tables and relations. For applications where Yii 2.0 Active Record classes also contain form validation, request scenarios, authorization checks, or business workflows, move those responsibilities to form models, services, and domain objects instead of putting them back into the record class." -msgstr "" +msgstr "Se você usava o Active Record do Yii 2.0, pode instalar o `yiisoft/active-record`. Ele é útil quando suas classes de model descrevem principalmente tabelas e relações. Em aplicações em que as classes Active Record do Yii 2.0 também contêm validação de formulário, cenários de requisição, verificações de autorização ou fluxos de negócio, mova essas responsabilidades para form models, serviços e objetos de domínio em vez de colocá-las de volta na classe do registro." #. type: Plain text #: ../src/guide/start/databases.md msgid "For most application code, put a repository or query service between the action/service layer and storage:" -msgstr "" +msgstr "Na maior parte do código da aplicação, coloque um repositório ou serviço de consulta entre a camada de actions/serviços e o armazenamento:" #. type: Bullet: '- ' #: ../src/guide/start/databases.md msgid "actions and application services depend on repository methods such as `findOneBySlug()`, `findAll()`, `save()`, and `deleteBySlug()`;" -msgstr "" +msgstr "actions e serviços da aplicação dependem de métodos do repositório como `findOneBySlug()`, `findAll()`, `save()` e `deleteBySlug()`;" #. type: Bullet: '- ' #: ../src/guide/start/databases.md msgid "the repository hides whether persistence is implemented with `yiisoft/db`, Active Record, Cycle, Doctrine, or another storage;" -msgstr "" +msgstr "o repositório esconde se a persistência é feita com `yiisoft/db`, Active Record, Cycle, Doctrine ou outro armazenamento;" #. type: Bullet: '- ' #: ../src/guide/start/databases.md msgid "the repository is the place to map raw database rows or records to typed objects used by the rest of the code." -msgstr "" +msgstr "o repositório é o lugar para converter as linhas brutas do banco de dados ou os registros em objetos tipados usados pelo resto do código." #. type: Plain text #: ../src/guide/start/databases.md msgid "Small CRUD applications can start with a concrete repository class. Larger applications usually benefit from a repository interface in the domain or module and an implementation in the infrastructure layer." -msgstr "" +msgstr "Aplicações CRUD pequenas podem começar com uma classe de repositório concreta. Aplicações maiores costumam se beneficiar de uma interface de repositório no domínio ou módulo e de uma implementação na camada de infraestrutura." #. type: Plain text #: ../src/guide/start/databases.md msgid "In this guide, we will focus on working with relational databases using Yii DB. We'll use PostgreSQL to implement a simple CRUD (create read update delete)." -msgstr "" +msgstr "Neste guia, vamos focar no trabalho com bancos de dados relacionais usando o Yii DB. Vamos usar PostgreSQL para implementar um CRUD simples (create, read, update, delete: criar, ler, atualizar e excluir)." #. type: Title ## #: ../src/guide/start/databases.md #, no-wrap msgid "Installing PostgreSQL" -msgstr "" +msgstr "Instalando o PostgreSQL" #. type: Plain text #: ../src/guide/start/databases.md msgid "You need to install PostgreSQL. If you prefer not to use Docker, [get the installer from official website](https://www.postgresql.org/download/), install it and create a database." -msgstr "" +msgstr "Você precisa instalar o PostgreSQL. Se preferir não usar Docker, [baixe o instalador no site oficial](https://www.postgresql.org/download/), instale e crie um banco de dados." #. type: Plain text #: ../src/guide/start/databases.md msgid "If you use Docker, it is a bit simpler. Modify `docker/dev/compose.yml`:" -msgstr "" +msgstr "Se você usa Docker, é um pouco mais simples. Altere `docker/dev/compose.yml`:" #. type: Fenced code block (yaml) #: ../src/guide/start/databases.md @@ -220,11 +228,52 @@ msgid "" " timeout: 5s\n" " retries: 5\n" msgstr "" +"services:\n" +" app:\n" +" build:\n" +" dockerfile: docker/Dockerfile\n" +" context: ..\n" +" target: dev\n" +" args:\n" +" USER_ID: ${UID}\n" +" GROUP_ID: ${GID}\n" +" env_file:\n" +" - path: ./dev/.env\n" +" - path: ./dev/override.env\n" +" required: false\n" +" ports:\n" +" - \"${DEV_PORT:-80}:80\"\n" +" volumes:\n" +" - ../:/app\n" +" - ../runtime:/app/runtime\n" +" - caddy_data:/data\n" +" - caddy_config:/config\n" +" tty: true\n" +" depends_on:\n" +" db:\n" +" condition: service_healthy\n" +"\n" +" db:\n" +" image: postgres:${POSTGRES_VERSION:-18}-alpine\n" +" environment:\n" +" POSTGRES_DB: app\n" +" POSTGRES_PASSWORD: password\n" +" POSTGRES_USER: user\n" +" POSTGRES_INITDB_ARGS: \"--locale-provider=icu --icu-locale=und --encoding=UTF8\"\n" +" volumes:\n" +" - ../runtime/db:/var/lib/postgresql:rw\n" +" ports:\n" +" - \"${DEV_DB_PORT:-5432}:5432\"\n" +" healthcheck:\n" +" test: [ \"CMD-SHELL\", \"pg_isready -U user -d app\" ]\n" +" interval: 5s\n" +" timeout: 5s\n" +" retries: 5\n" #. type: Plain text #: ../src/guide/start/databases.md msgid "Note that we add `depends_on` so application waits for database to be up." -msgstr "" +msgstr "Repare que adicionamos `depends_on` para que a aplicação espere o banco de dados subir." #. type: Plain text #: ../src/guide/start/databases.md @@ -233,11 +282,13 @@ msgid "" "> [!IMPORTANT]\n" "> Also, we'll need a `pdo_pgsql` extension to communicate with PostgreSQL. You can enable it locally in `php.ini`.\n" msgstr "" +"> [!IMPORTANT]\n" +"> Também vamos precisar da extensão `pdo_pgsql` para falar com o PostgreSQL. Você pode habilitá-la localmente no `php.ini`.\n" #. type: Plain text #: ../src/guide/start/databases.md msgid "If you use Docker, check `docker/Dockerfile` and add `pdo_pgsql` in `install-php-extensions` list:" -msgstr "" +msgstr "Se você usa Docker, abra `docker/Dockerfile` e adicione `pdo_pgsql` à lista do `install-php-extensions`:" #. type: Fenced code block (dockerfile) #: ../src/guide/start/databases.md @@ -258,44 +309,58 @@ msgid "" " pdo \\\n" " pdo_pgsql\n" msgstr "" +"RUN install-php-extensions \\\n" +" opcache \\\n" +" mbstring \\\n" +" intl \\\n" +" dom \\\n" +" ctype \\\n" +" curl \\\n" +" phar \\\n" +" openssl \\\n" +" xml \\\n" +" xmlwriter \\\n" +" simplexml \\\n" +" pdo \\\n" +" pdo_pgsql\n" #. type: Plain text #: ../src/guide/start/databases.md msgid "Then rebuild PHP image with" -msgstr "" +msgstr "Depois, reconstrua a imagem do PHP com" #. type: Fenced code block (sh) #: ../src/guide/start/databases.md #, no-wrap msgid "make build && make down && make up\n" -msgstr "" +msgstr "make build && make down && make up\n" #. type: Title ## #: ../src/guide/start/databases.md #, no-wrap msgid "Configuring connection" -msgstr "" +msgstr "Configurando a conexão" #. type: Plain text #: ../src/guide/start/databases.md msgid "Now that we have the database, it's time to define the connection." -msgstr "" +msgstr "Agora que temos o banco de dados, é hora de definir a conexão." #. type: Plain text #: ../src/guide/start/databases.md msgid "First we need a package to be installed:" -msgstr "" +msgstr "Primeiro, precisamos instalar um pacote:" #. type: Fenced code block (sh) #: ../src/guide/start/databases.md #, no-wrap msgid "make composer require yiisoft/db-pgsql:2.*\n" -msgstr "" +msgstr "make composer require yiisoft/db-pgsql:2.*\n" #. type: Plain text #: ../src/guide/start/databases.md msgid "Now create `config/common/di/db-pgsql.php`:" -msgstr "" +msgstr "Agora crie `config/common/di/db-pgsql.php`:" #. type: Fenced code block (php) #: ../src/guide/start/databases.md @@ -322,11 +387,31 @@ msgid "" " ],\n" "];\n" msgstr "" +" [\n" +" 'class' => Connection::class,\n" +" '__construct()' => [\n" +" 'driver' => new Driver(\n" +" $params['yiisoft/db-pgsql']['dsn'],\n" +" $params['yiisoft/db-pgsql']['username'],\n" +" $params['yiisoft/db-pgsql']['password'],\n" +" ),\n" +" ],\n" +" ],\n" +"];\n" #. type: Plain text #: ../src/guide/start/databases.md msgid "And define parameters in `config/common/params.php`. For Docker that would be:" -msgstr "" +msgstr "E defina os parâmetros em `config/common/params.php`. Para o Docker, fica assim:" #. type: Fenced code block (php) #: ../src/guide/start/databases.md @@ -343,27 +428,37 @@ msgid "" " ],\n" "];\n" msgstr "" +"use Yiisoft\\Db\\Pgsql\\Dsn;\n" +"\n" +"return [\n" +" // ...\n" +" 'yiisoft/db-pgsql' => [\n" +" 'dsn' => new Dsn('pgsql', 'db', 'app', '5432'),\n" +" 'username' => 'user',\n" +" 'password' => 'password',\n" +" ],\n" +"];\n" #. type: Plain text #: ../src/guide/start/databases.md msgid "`db` host is resolved automatically within the Docker network." -msgstr "" +msgstr "O host `db` é resolvido automaticamente dentro da rede do Docker." #. type: Plain text #: ../src/guide/start/databases.md msgid "For local installation without Docker the host in Dsn would be `localhost`. You'll have to adjust the rest to match how you configured the database." -msgstr "" +msgstr "Em uma instalação local sem Docker, o host no Dsn seria `localhost`. Ajuste o resto conforme a forma como você configurou o banco de dados." #. type: Title ### #: ../src/guide/start/databases.md #, no-wrap msgid "Multiple database connections" -msgstr "" +msgstr "Várias conexões de banco de dados" #. type: Plain text #: ../src/guide/start/databases.md msgid "When the application works with several databases, keep `ConnectionInterface` for the primary connection and add a class alias for each named connection:" -msgstr "" +msgstr "Quando a aplicação trabalha com vários bancos de dados, mantenha `ConnectionInterface` para a conexão principal e adicione um alias de classe para cada conexão nomeada:" #. type: Fenced code block (php) #: ../src/guide/start/databases.md @@ -408,16 +503,54 @@ msgid "" " ],\n" "];\n" msgstr "" +" MainDatabase::class,\n" +"\n" +" MainDatabase::class => [\n" +" 'class' => Connection::class,\n" +" '__construct()' => [\n" +" 'driver' => new Driver(\n" +" $params['app/db']['main']['dsn'],\n" +" $params['app/db']['main']['username'],\n" +" $params['app/db']['main']['password'],\n" +" ),\n" +" ],\n" +" ],\n" +"\n" +" AnalyticsDatabase::class => [\n" +" 'class' => Connection::class,\n" +" '__construct()' => [\n" +" 'driver' => new Driver(\n" +" $params['app/db']['analytics']['dsn'],\n" +" $params['app/db']['analytics']['username'],\n" +" $params['app/db']['analytics']['password'],\n" +" ),\n" +" ],\n" +" ],\n" +"];\n" #. type: Plain text #: ../src/guide/start/databases.md msgid "The alias class names are used as service IDs and type hints. They don't need PHP files of their own." -msgstr "" +msgstr "Os nomes das classes alias são usados como IDs de serviço e type hints. Eles não precisam de arquivos PHP próprios." #. type: Plain text #: ../src/guide/start/databases.md msgid "Define matching parameters:" -msgstr "" +msgstr "Defina os parâmetros correspondentes:" #. type: Fenced code block (php) #: ../src/guide/start/databases.md @@ -441,11 +574,28 @@ msgid "" " ],\n" "];\n" msgstr "" +"use Yiisoft\\Db\\Pgsql\\Dsn;\n" +"\n" +"return [\n" +" // ...\n" +" 'app/db' => [\n" +" 'main' => [\n" +" 'dsn' => new Dsn('pgsql', 'db', 'app', '5432'),\n" +" 'username' => 'user',\n" +" 'password' => 'password',\n" +" ],\n" +" 'analytics' => [\n" +" 'dsn' => new Dsn('pgsql', 'analytics-db', 'analytics', '5432'),\n" +" 'username' => 'analytics_user',\n" +" 'password' => 'analytics_password',\n" +" ],\n" +" ],\n" +"];\n" #. type: Plain text #: ../src/guide/start/databases.md msgid "Services that need the primary database can still depend on `ConnectionInterface`. Services that need another database should type-hint the corresponding alias:" -msgstr "" +msgstr "Serviços que precisam do banco de dados principal continuam podendo depender de `ConnectionInterface`. Serviços que precisam de outro banco de dados devem usar o alias correspondente como type hint:" #. type: Fenced code block (php) #: ../src/guide/start/databases.md @@ -466,32 +616,46 @@ msgid "" " ) {}\n" "}\n" msgstr "" +"columnBuilder();\n" +"\n" +" $b->createTable('page', [\n" +" 'id' => $column::uuidPrimaryKey(),\n" +" 'title' => $column::string()->notNull(),\n" +" 'slug' => $column::string()->notNull()->unique(),\n" +" 'text' => $column::text()->notNull(),\n" +" 'created_at' => $column::dateTime(),\n" +" 'updated_at' => $column::dateTime(),\n" +" ]);\n" +" }\n" +"\n" +" public function down(MigrationBuilder $b): void\n" +" {\n" +" $b->dropTable('page');\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/start/databases.md msgid "The `M251102141707Page` name of the migration class is generated so replace the `Page` suffix with the actual migration name. The `M251102141707` prefix is needed to find and sort migrations in the order they were added." -msgstr "" +msgstr "O nome `M251102141707Page` da classe da migration é gerado, então substitua o sufixo `Page` pelo nome real da migration. O prefixo `M251102141707` é necessário para encontrar e ordenar as migrations na ordem em que foram adicionadas." #. type: Plain text #: ../src/guide/start/databases.md msgid "Note that we use UUID as the primary key. We are going to generate these IDs ourselves instead of relying on database so we'll need an extra compose package for that." -msgstr "" +msgstr "Repare que usamos UUID como chave primária. Vamos gerar esses IDs nós mesmos, em vez de depender do banco de dados, então precisamos de um pacote extra do Composer para isso." #. type: Fenced code block (shell) #: ../src/guide/start/databases.md #, no-wrap msgid "make composer require ramsey/uuid\n" -msgstr "" +msgstr "make composer require ramsey/uuid\n" #. type: Plain text #: ../src/guide/start/databases.md msgid "While the storage space is a bit bigger than using int, the workflow with such IDs is beneficial. Since you generate the ID yourself so you can define a set of related data and save it in a single transaction. The entities that define this set of data in the code are often called an \"aggregate\"." -msgstr "" +msgstr "O espaço de armazenamento é um pouco maior do que com int, mas o fluxo de trabalho com esse tipo de ID compensa. Como você mesmo gera o ID, pode definir um conjunto de dados relacionados e salvá-lo em uma única transação. As entidades que definem esse conjunto de dados no código costumam ser chamadas de \"agregado\"." #. type: Plain text #: ../src/guide/start/databases.md msgid "Apply the migration with `make yii migrate:up`." -msgstr "" +msgstr "Aplique a migration com `make yii migrate:up`." #. type: Title ## #: ../src/guide/start/databases.md #, no-wrap msgid "An entity" -msgstr "" +msgstr "Uma entidade" #. type: Plain text #: ../src/guide/start/databases.md msgid "Now that you have a table it is time to define an entity in the code. Create `src/Web/Page/Page.php`:" -msgstr "" +msgstr "Agora que você tem uma tabela, é hora de definir uma entidade no código. Crie `src/Web/Page/Page.php`:" #. type: Fenced code block (php) #: ../src/guide/start/databases.md @@ -611,21 +805,61 @@ msgid "" " }\n" "}\n" msgstr "" - -#. type: Plain text -#: ../src/guide/start/databases.md -msgid "Now that we have an entity, we need a place for methods to save it, delete it, and select either a single page or multiple pages. This is the repository boundary described earlier: the rest of the application works with `Page` objects and doesn't need to know how they are stored." -msgstr "" - -#. type: Plain text -#: ../src/guide/start/databases.md -msgid "Create `src/Web/Page/PageRepository.php`:" -msgstr "" - -#. type: Fenced code block (php) -#: ../src/guide/start/databases.md -#, no-wrap -msgid "" +"toSlug($title),\n" +" text: $text,\n" +" createdAt: $createdAt,\n" +" updatedAt: $updatedAt,\n" +" );\n" +" }\n" +"}\n" + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "Now that we have an entity, we need a place for methods to save it, delete it, and select either a single page or multiple pages. This is the repository boundary described earlier: the rest of the application works with `Page` objects and doesn't need to know how they are stored." +msgstr "Agora que temos uma entidade, precisamos de um lugar para os métodos que a salvam, a excluem e selecionam uma única página ou várias. Essa é a fronteira de repositório descrita antes: o resto da aplicação trabalha com objetos `Page` e não precisa saber como eles são armazenados." + +#. type: Plain text +#: ../src/guide/start/databases.md +msgid "Create `src/Web/Page/PageRepository.php`:" +msgstr "Crie `src/Web/Page/PageRepository.php`:" + +#. type: Fenced code block (php) +#: ../src/guide/start/databases.md +#, no-wrap +msgid "" " $page->id,\n" +" 'title' => $page->title,\n" +" 'slug' => $page->slug,\n" +" 'text' => $page->text,\n" +" 'created_at' => $page->createdAt,\n" +" 'updated_at' => $page->updatedAt,\n" +" ];\n" +"\n" +" if ($this->exists($page->id)) {\n" +" $this->connection->createCommand()->update('{{%page}}', $row, ['id' => $page->id])->execute();\n" +" } else {\n" +" $this->connection->createCommand()->insert('{{%page}}', $row)->execute();\n" +" }\n" +" }\n" +"\n" +" public function findOneBySlug(string $slug): ?Page\n" +" {\n" +" $query = $this->connection\n" +" ->select()\n" +" ->from('{{%page}}')\n" +" ->where('slug = :slug', ['slug' => $slug]);\n" +"\n" +" return $this->createPage($query->one());\n" +" }\n" +"\n" +" /**\n" +" * @return iterable\n" +" */\n" +" public function findAll(): iterable\n" +" {\n" +" $rows = $this->connection\n" +" ->select()\n" +" ->from('{{%page}}')\n" +" ->all();\n" +"\n" +" foreach ($rows as $row) {\n" +" yield $this->createPage($row);\n" +" }\n" +" }\n" +"\n" +" private function createPage(?array $row): ?Page\n" +" {\n" +" if ($row === null) {\n" +" return null;\n" +" }\n" +"\n" +" return Page::create(\n" +" id: $row['id'],\n" +" title: $row['title'],\n" +" text: $row['text'],\n" +" slug: $row['slug'],\n" +" createdAt: new DateTimeImmutable($row['created_at']),\n" +" updatedAt: new DateTimeImmutable($row['updated_at']),\n" +" );\n" +" }\n" +"\n" +" public function deleteBySlug(string $slug): void\n" +" {\n" +" $this->connection->createCommand()->delete(\n" +" '{{%page}}',\n" +" ['slug' => $slug],\n" +" )->execute();\n" +" }\n" +"\n" +" public function exists(string $id): bool\n" +" {\n" +" return $this->connection->createQuery()\n" +" ->from('{{%page}}')\n" +" ->where(['id' => $id])\n" +" ->exists();\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/start/databases.md msgid "In this repository there are both methods to get data and `save()` to do insert or update. DB returns raw data as arrays but our repository automatically creates entities from this raw data so later we operate typed data." -msgstr "" +msgstr "Neste repositório há tanto métodos para buscar dados quanto o `save()`, que faz insert ou update. O DB retorna os dados brutos como arrays, mas o nosso repositório cria entidades automaticamente a partir deles, e daí em diante trabalhamos com dados tipados." #. type: Title ## #: ../src/guide/start/databases.md #, no-wrap msgid "Actions and routes" -msgstr "" +msgstr "Actions e rotas" #. type: Plain text #: ../src/guide/start/databases.md msgid "We need some actions to:" -msgstr "" +msgstr "Precisamos de algumas actions para:" #. type: Bullet: '1. ' #: ../src/guide/start/databases.md msgid "List all pages." -msgstr "" +msgstr "Listar todas as páginas." #. type: Bullet: '2. ' #: ../src/guide/start/databases.md msgid "View a page." -msgstr "" +msgstr "Ver uma página." #. type: Bullet: '3. ' #: ../src/guide/start/databases.md msgid "Delete a page." -msgstr "" +msgstr "Excluir uma página." #. type: Bullet: '4. ' #: ../src/guide/start/databases.md msgid "Create a page." -msgstr "" +msgstr "Criar uma página." #. type: Bullet: '5. ' #: ../src/guide/start/databases.md msgid "Update a page." -msgstr "" +msgstr "Atualizar uma página." #. type: Plain text #: ../src/guide/start/databases.md msgid "Then we need routing for all these." -msgstr "" +msgstr "Depois, precisamos do roteamento para tudo isso." #. type: Plain text #: ../src/guide/start/databases.md msgid "Let's tackle these one by one." -msgstr "" +msgstr "Vamos resolver uma coisa de cada vez." #. type: Title ### #: ../src/guide/start/databases.md #, no-wrap msgid "List all pages" -msgstr "" +msgstr "Listar todas as páginas" #. type: Plain text #: ../src/guide/start/databases.md msgid "Create `src/Web/Page/ListAction.php`:" -msgstr "" +msgstr "Crie `src/Web/Page/ListAction.php`:" #. type: Fenced code block (php) #: ../src/guide/start/databases.md @@ -810,11 +1134,36 @@ msgid "" " }\n" "}\n" msgstr "" +"viewRenderer->render(__DIR__ . '/list', [\n" +" 'pages' => $this->pageRepository->findAll(),\n" +" ]);\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/start/databases.md msgid "Define list view in `src/Web/Page/list.php`:" -msgstr "" +msgstr "Defina a view da lista em `src/Web/Page/list.php`:" #. type: Fenced code block (php) #: ../src/guide/start/databases.md @@ -839,17 +1188,35 @@ msgid "" "\n" "generate('page/edit', ['slug' => 'new'])) ?>\n" msgstr "" +" $pages */\n" +"/** @var UrlGeneratorInterface $urlGenerator */\n" +"?>\n" +"\n" +"
    \n" +" \n" +"
  • \n" +" title, $urlGenerator->generate('page/view', ['slug' => $page->slug])) ?>\n" +"
  • \n" +" \n" +"
\n" +"\n" +"generate('page/edit', ['slug' => 'new'])) ?>\n" #. type: Title ### #: ../src/guide/start/databases.md #, no-wrap msgid "View a page" -msgstr "" +msgstr "Ver uma página" #. type: Plain text #: ../src/guide/start/databases.md msgid "Create `src/Web/Page/ViewAction.php`:" -msgstr "" +msgstr "Crie `src/Web/Page/ViewAction.php`:" #. type: Fenced code block (php) #: ../src/guide/start/databases.md @@ -890,11 +1257,45 @@ msgid "" " }\n" "}\n" msgstr "" +"pageRepository->findOneBySlug($slug);\n" +" if ($page === null) {\n" +" return $this->responseFactory->createResponse(Status::NOT_FOUND);\n" +" }\n" +"\n" +" return $this->viewRenderer->render(__DIR__ . '/view', [\n" +" 'page' => $page,\n" +" ]);\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/start/databases.md msgid "Now, a template in `src/Web/Page/view.php`:" -msgstr "" +msgstr "Agora, um template em `src/Web/Page/view.php`:" #. type: Fenced code block (php) #: ../src/guide/start/databases.md @@ -929,22 +1330,50 @@ msgid "" " \n" "close() ?>\n" msgstr "" +"\n" +"\n" +"

generate('page/list')) ?> → title) ?>

\n" +"\n" +"

\n" +" text) ?>\n" +"

\n" +"\n" +"generate('page/edit', ['slug' => $page->slug])) ?> |\n" +"\n" +"\n" +"post($urlGenerator->generate('page/delete', ['slug' => $page->slug]))\n" +" ->csrf($csrf);\n" +"?>\n" +"open() ?>\n" +" \n" +"close() ?>\n" #. type: Plain text #: ../src/guide/start/databases.md msgid "In this view we have a form that submits a request for page deletion. Handing it with `GET` is common as well, but it is very wrong. Since deletion changes data, it needs to be handled by one of the non-idempotent HTTP methods. We use POST and a form in our example, but it could be `DELETE` and async request made with JavaScript. The button could be later styled properly to look similar to the \"Edit\"." -msgstr "" +msgstr "Nesta view há um formulário que envia uma requisição para excluir a página. Tratar isso com `GET` também é comum, mas é muito errado. Como a exclusão altera dados, ela precisa ser tratada por um dos métodos HTTP não idempotentes. No nosso exemplo usamos POST e um formulário, mas poderia ser `DELETE` e uma requisição assíncrona feita com JavaScript. Depois, o botão pode ganhar um estilo adequado para ficar parecido com o \"Edit\"." #. type: Title ### #: ../src/guide/start/databases.md #, no-wrap msgid "Delete a page" -msgstr "" +msgstr "Excluir uma página" #. type: Plain text #: ../src/guide/start/databases.md msgid "Create `src/Web/Page/DeleteAction.php`:" -msgstr "" +msgstr "Crie `src/Web/Page/DeleteAction.php`:" #. type: Fenced code block (php) #: ../src/guide/start/databases.md @@ -983,17 +1412,49 @@ msgid "" " }\n" "}\n" msgstr "" +"pageRepository->deleteBySlug($slug);\n" +"\n" +" return $this->responseFactory\n" +" ->createResponse(Status::SEE_OTHER)\n" +" ->withHeader('Location', $this->urlGenerator->generate('page/list'));\n" +" }\n" +"}\n" #. type: Title ### #: ../src/guide/start/databases.md #, no-wrap msgid "Create or update a page" -msgstr "" +msgstr "Criar ou atualizar uma página" #. type: Plain text #: ../src/guide/start/databases.md msgid "First of all, we need a form at `src/Web/Page/Form.php`:" -msgstr "" +msgstr "Antes de tudo, precisamos de um formulário em `src/Web/Page/Form.php`:" #. type: Fenced code block (php) #: ../src/guide/start/databases.md @@ -1020,11 +1481,31 @@ msgid "" " public string $text = '';\n" "}\n" msgstr "" +"findOneBySlug($slug);\n" +" if ($page === null) {\n" +" return $this->responseFactory->createResponse(Status::NOT_FOUND);\n" +" }\n" +"\n" +" $form->title = $page->title;\n" +" $form->text = $page->text;\n" +" }\n" +"\n" +" $this->formHydrator->populateFromPostAndValidate($form, $request);\n" +"\n" +" if ($form->isValid()) {\n" +" $id = $isNew ? Uuid::uuid7()->toString() : $page->id;\n" +"\n" +" $page = Page::create(\n" +" id: $id,\n" +" title: $form->title,\n" +" text: $form->text,\n" +" );\n" +"\n" +" $pageRepository->save($page);\n" +"\n" +" return $this->responseFactory\n" +" ->createResponse(Status::SEE_OTHER)\n" +" ->withHeader(\n" +" 'Location',\n" +" $this->urlGenerator->generate('page/view', ['slug' => $page->slug]),\n" +" );\n" +" }\n" +"\n" +" return $this->viewRenderer->render(__DIR__ . '/edit', [\n" +" 'form' => $form,\n" +" 'isNew' => $isNew,\n" +" 'slug' => $slug,\n" +" ]);\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/start/databases.md #, no-wrap msgid "Note that `Uuid::uuid7()->toString()` won't work for MySQL and you'll need bytes instead, `Uuid::uuid7()->getBytes()`.\n" -msgstr "" +msgstr "Repare que `Uuid::uuid7()->toString()` não funciona no MySQL; lá você vai precisar dos bytes, com `Uuid::uuid7()->getBytes()`.\n" #. type: Plain text #: ../src/guide/start/databases.md msgid "In the above we use a special slug in the URL for new pages so the URL looks like `http://localhost/pages/new`. If the page isn't new, we pre-fill the form with the data from the database. Similar to how we did in [Working with forms](forms.md), we handle the form submission. After successful save we redirect to the page view." -msgstr "" +msgstr "Acima, usamos um slug especial na URL para páginas novas, então a URL fica como `http://localhost/pages/new`. Se a página não for nova, preenchemos o formulário com os dados do banco de dados. Assim como fizemos em [Trabalhando com formulários](forms.md), tratamos o envio do formulário. Depois de salvar com sucesso, redirecionamos para a view da página." #. type: Plain text #: ../src/guide/start/databases.md msgid "Now, a template in `src/Web/Page/edit.php`:" -msgstr "" +msgstr "Agora, um template em `src/Web/Page/edit.php`:" #. type: Fenced code block (php) #: ../src/guide/start/databases.md @@ -1155,11 +1712,37 @@ msgid "" " \n" "close() ?>\n" msgstr "" +"post($urlGenerator->generate('page/edit', ['slug' => $slug]))\n" +" ->csrf($csrf);\n" +"?>\n" +"\n" +"open() ?>\n" +" required() ?>\n" +" required() ?>\n" +" \n" +"close() ?>\n" #. type: Plain text #: ../src/guide/start/databases.md msgid "Adjust `config/common/routes.php`:" -msgstr "" +msgstr "Ajuste `config/common/routes.php`:" #. type: Fenced code block (php) #: ../src/guide/start/databases.md @@ -1201,11 +1784,46 @@ msgid "" " ),\n" "];\n" msgstr "" +"routes(\n" +" Route::get('/')\n" +" ->action(Web\\HomePage\\Action::class)\n" +" ->name('home'),\n" +" Route::methods([Method::GET, Method::POST], '/say')\n" +" ->action(Web\\Echo\\Action::class)\n" +" ->name('echo/say'),\n" +"\n" +" Group::create('/pages')->routes(\n" +" Route::get('')\n" +" ->action(Web\\Page\\ListAction::class)\n" +" ->name('page/list'),\n" +" Route::get('/{slug}')\n" +" ->action(Web\\Page\\ViewAction::class)\n" +" ->name('page/view'),\n" +" Route::methods([Method::GET, Method::POST], '/{slug}/edit')\n" +" ->action(Web\\Page\\EditAction::class)\n" +" ->name('page/edit'),\n" +" Route::post('/{slug}/delete')\n" +" ->action(Web\\Page\\DeleteAction::class)\n" +" ->name('page/delete'),\n" +" ),\n" +" ),\n" +"];\n" #. type: Plain text #: ../src/guide/start/databases.md msgid "Note that we've grouped all page-related routes with a group under `/pages` prefix. That is a convenient way to both not to repeat yourself and add some extra middleware, such as authentication, to the whole group." -msgstr "" +msgstr "Repare que agrupamos todas as rotas relacionadas a páginas em um grupo com o prefixo `/pages`. É uma forma prática de não se repetir e também de adicionar algum middleware extra, como autenticação, ao grupo inteiro." #. type: Title ## #: ../src/guide/start/databases.md ../src/guide/start/hello.md @@ -1216,4 +1834,4 @@ msgstr "Testando" #. type: Plain text #: ../src/guide/start/databases.md msgid "Now try it out by opening `http://localhost/pages` in your browser." -msgstr "" +msgstr "Agora teste abrindo `http://localhost/pages` no navegador." diff --git a/src/pt-BR/guide/index.md b/src/pt-BR/guide/index.md index 0c17772d..1466c52f 100644 --- a/src/pt-BR/guide/index.md +++ b/src/pt-BR/guide/index.md @@ -6,8 +6,8 @@ Yii](https://www.yiiframework.com/license#docs). ## Introdução - [Sobre o Yii](intro/what-is-yii.md) -- [Atualizando a partir da versão 1.1](intro/upgrade-from-v1.md) -- [Atualizando a partir da versão 2.0](intro/upgrade-from-v2.md) +- [Migrando da versão 1.1](intro/upgrade-from-v1.md) +- [Migrando da versão 2.0](intro/upgrade-from-v2.md) ## Primeiros passos @@ -86,7 +86,7 @@ Yii](https://www.yiiframework.com/license#docs). - [Assets](views/asset.md) TODO: verify! - [Scripts, estilos e meta tags](views/script-style-meta.md) TODO: verify! - [Template engines](views/template-engines.md) TODO: verify! -- [Injeções em views](views/view-injections.md) +- [Injeções de view](views/view-injections.md) - [Widgets](views/widget.md) TODO: verify! ## Recebendo dados dos usuários @@ -137,7 +137,7 @@ Yii](https://www.yiiframework.com/license#docs). - [Aplicações de console](tutorial/console-applications.md) - [Envio de e-mails](tutorial/mailing.md) -- [Otimização de desempenho](tutorial/performance-tuning.md) +- [Ajuste de desempenho](tutorial/performance-tuning.md) - [Usando o Yii com event loop](tutorial/using-with-event-loop.md) - [Usando o Yii com FrankenPHP](tutorial/using-yii-with-frankenphp.md) - [Usando o Yii com Rapira](tutorial/using-yii-with-rapira.md) diff --git a/src/pt-BR/guide/intro/upgrade-from-v1.md b/src/pt-BR/guide/intro/upgrade-from-v1.md index a4ae75a2..1541b296 100644 --- a/src/pt-BR/guide/intro/upgrade-from-v1.md +++ b/src/pt-BR/guide/intro/upgrade-from-v1.md @@ -1,72 +1,74 @@ -# Upgrading from Version 1.1 +# Migrando da versão 1.1 -> If you haven't used Yii 1.1, you can skip this section and get directly to -> "[getting started](../start/prerequisites.md)" section. +> Se você não usou o Yii 1.1, pode pular esta seção e ir direto para a seção +> "[primeiros passos](../start/prerequisites.md)". -Yii3 is not an incremental upgrade from Yii 1.1. Yii 2.0 was a full rewrite, -and Yii3 changes the architecture again: Composer packages, namespaces, PHP -8, PSR interfaces, dependency injection, explicit routes, middleware, and -separate packages for features that were built into the framework in Yii -1.1. +O Yii3 não é um upgrade incremental do Yii 1.1. O Yii 2.0 foi uma reescrita +completa, e o Yii3 muda a arquitetura de novo: pacotes Composer, namespaces, +PHP 8, interfaces PSR, injeção de dependência, rotas explícitas, middleware +e pacotes separados para funcionalidades que no Yii 1.1 eram embutidas no +framework. -Treat this as building a new Yii3 application with the benefit of Yii 1.1 -experience. Reuse the domain knowledge, database schema, user workflows, and -selected code after refactoring. Do not try to reproduce the Yii 1.1 -application structure in Yii3. A direct search-and-replace conversion is not -realistic. +Encare isso como a construção de uma nova aplicação Yii3 aproveitando a +experiência com o Yii 1.1. Reaproveite o conhecimento do domínio, o esquema +do banco de dados, os fluxos dos usuários e partes selecionadas do código +após refatorá-las. Não tente reproduzir a estrutura da aplicação Yii 1.1 no +Yii3. Uma conversão direta por busca e substituição não é realista. -For additional background, read the Yii 2.0 guide section [Upgrading from -Version +Para mais contexto, leia a seção do guia do Yii 2.0 [Upgrading from Version 1.1](https://www.yiiframework.com/doc/guide/2.0/en/intro-upgrade-from-v1). -It explains the first major break from Yii 1.1: Composer, namespaces, object -configuration, view changes, controller return values, widgets, assets, -helpers, forms, query builder, Active Record, and URL management. Yii3 -builds on many of those changes and makes dependencies more explicit. - -## Recommended approach - -Choose one of these paths: - -- Build a new Yii3 application directly when the Yii 1.1 application is - small or you are already rewriting request flows. -- Move Yii 1.1 concepts to Yii 2.0 first when the team needs a smaller - conceptual step. -- Keep Yii 1.1 running and rebuild critical flows in Yii3 one by one. - -For most long-lived applications, the third option is the least -risky. Create a Yii3 application, connect it to the same database, and build -vertical slices: route, action, input validation, persistence, view, assets, -and tests. Each slice should be idiomatic Yii3, even when it is based on -behavior from the Yii 1.1 application. - -## Prepare the Yii 1.1 application - -Useful preparation can happen before the Yii3 application is ready. These -refactorings make old behavior easier to understand and reduce the amount of -Yii 1.1 framework state that crosses into the new code: - -- Remove direct `Yii::app()` access from reusable code where practical. If a - full refactoring is too large, keep `Yii::app()` calls near controllers, - widgets, and commands, then pass values and services to lower-level code - explicitly. -- Introduce repositories or query services for database reads currently - spread across controllers, views, `CActiveRecord` methods, and - widgets. Yii3 can use Active Record, but it does not require it for every - persistence task. -- Separate business rules from framework infrastructure. Code that does not - extend `CComponent`, read global application state, or render views is - easier to reuse as a specification for Yii3 code. -- Move reusable behavior out of large controllers and Active Record classes - into Yii 1.1 application components or plain services. Yii3 services are - configured and injected differently, but the responsibility boundary is - similar. -- Add tests or characterization checks around routes and workflows you plan - to rebuild first. They become the executable specification for the Yii3 - slice. - -For example, instead of reading post archive data directly from several -controllers or widgets, create a small service that describes the -application need: +Ela explica a primeira grande ruptura com o Yii 1.1: Composer, namespaces, +configuração de objetos, mudanças nas views, valores de retorno dos +controllers, widgets, assets, helpers, formulários, query builder, Active +Record e gerenciamento de URLs. O Yii3 se apoia em muitas dessas mudanças e +torna as dependências mais explícitas. + +## Abordagem recomendada + +Escolha um destes caminhos: + +- Construa uma nova aplicação Yii3 diretamente quando a aplicação Yii 1.1 + for pequena ou você já estiver reescrevendo os fluxos de requisição. +- Migre primeiro os conceitos do Yii 1.1 para o Yii 2.0 quando o time + precisar de um passo conceitual menor. +- Mantenha o Yii 1.1 rodando e reconstrua os fluxos críticos no Yii3 um a + um. + +Para a maioria das aplicações de longa duração, a terceira opção é a de +menor risco. Crie uma aplicação Yii3, conecte-a ao mesmo banco de dados e +construa vertical slices: rota, action, validação de entrada, persistência, +view, assets e testes. Cada slice deve ser Yii3 idiomático, mesmo quando se +baseia no comportamento da aplicação Yii 1.1. + +## Prepare a aplicação Yii 1.1 + +Uma preparação útil pode acontecer antes de a aplicação Yii3 estar +pronta. Estas refatorações tornam o comportamento antigo mais fácil de +entender e reduzem a quantidade de estado do framework Yii 1.1 que passa +para o código novo: + +- Remova o acesso direto a `Yii::app()` do código reutilizável onde for + viável. Se uma refatoração completa for grande demais, mantenha as + chamadas a `Yii::app()` perto de controllers, widgets e comandos, e passe + valores e serviços explicitamente para o código de nível mais baixo. +- Introduza repositórios ou serviços de consulta para as leituras do banco + de dados hoje espalhadas por controllers, views, métodos de + `CActiveRecord` e widgets. O Yii3 pode usar Active Record, mas não o exige + para toda tarefa de persistência. +- Separe as regras de negócio da infraestrutura do framework. Código que não + estende `CComponent`, não lê o estado global da aplicação nem renderiza + views é mais fácil de reutilizar como especificação para o código Yii3. +- Mova o comportamento reutilizável de controllers e classes Active Record + grandes para componentes de aplicação do Yii 1.1 ou serviços simples. Os + serviços do Yii3 são configurados e injetados de outra forma, mas a + fronteira de responsabilidade é parecida. +- Adicione testes ou verificações de caracterização em torno das rotas e + fluxos que você planeja reconstruir primeiro. Eles se tornam a + especificação executável do slice Yii3. + +Por exemplo, em vez de ler os dados do arquivo de posts diretamente em +vários controllers ou widgets, crie um pequeno serviço que descreva a +necessidade da aplicação: ```php class PostRepository extends CComponent @@ -83,41 +85,42 @@ class PostRepository extends CComponent } ``` -The Yii3 implementation may use `yiisoft/active-record`, `yiisoft/db`, or -another persistence layer. The important point is that controllers and views -no longer need to know that detail. - -## Things to learn before starting - -Some Yii3 application-template choices are likely to be new in a Yii 1.1 -codebase: - -- [Composer](https://getcomposer.org/). Yii3 applications and packages are - installed through Composer and loaded with PSR-4 autoloading. -- [Namespaces](https://www.php.net/manual/en/language.namespaces.php). Yii3 - classes are namespaced instead of using Yii 1.1-style class prefixes and - path aliases for class loading. -- [Docker](https://www.docker.com/get-started/). The default Yii3 - application template includes Docker configuration. Using it gives each - application its own repeatable environment and reduces differences between - local development and production. -- [Environment - variables](https://en.wikipedia.org/wiki/Environment_variable). Yii3 - templates commonly use them for environment-specific settings and secrets, - especially in Docker-based deployments. This follows the same idea as - [12-factor app configuration](https://12factor.net/config). -- [Actions](../structure/action.md). Yii3 does not require controller - inheritance. A route can point to any callable, and the default template - uses invokable action classes. -- [Application structure](../structure/overview.md). Yii3's default - structure is different from Yii 1.1. Start with the Yii3 template and - change it only when the application needs it. - -## PHP, Composer, and namespaces - -Yii 1.1 applications commonly rely on PHP 5-era code, class prefixes such as -`CController`, and autoloading by class name. Yii3 applications require -modern PHP and Composer autoloading. +A implementação no Yii3 pode usar `yiisoft/active-record`, `yiisoft/db` ou +outra camada de persistência. O importante é que controllers e views não +precisem mais conhecer esse detalhe. + +## O que aprender antes de começar + +Algumas escolhas do template de aplicação do Yii3 provavelmente serão +novidade para uma base de código Yii 1.1: + +- [Composer](https://getcomposer.org/). Aplicações e pacotes Yii3 são + instalados pelo Composer e carregados com autoloading PSR-4. +- [Namespaces](https://www.php.net/manual/en/language.namespaces.php). As + classes do Yii3 usam namespaces em vez dos prefixos de classe e path + aliases do Yii 1.1 para o carregamento de classes. +- [Docker](https://www.docker.com/get-started/). O template de aplicação + padrão do Yii3 inclui configuração do Docker. Usá-lo dá a cada aplicação + seu próprio ambiente reproduzível e reduz as diferenças entre o + desenvolvimento local e a produção. +- [Variáveis de + ambiente](https://en.wikipedia.org/wiki/Environment_variable). Os + templates do Yii3 costumam usá-las para configurações específicas de + ambiente e segredos, especialmente em deploys baseados em Docker. Isso + segue a mesma ideia da [configuração de aplicações + 12-factor](https://12factor.net/config). +- [Actions](../structure/action.md). O Yii3 não exige herança de + controller. Uma rota pode apontar para qualquer callable, e o template + padrão usa classes de action invocáveis. +- [Estrutura da aplicação](../structure/overview.md). A estrutura padrão do + Yii3 é diferente da do Yii 1.1. Comece com o template do Yii3 e altere-o + apenas quando a aplicação precisar. + +## PHP, Composer e namespaces + +Aplicações Yii 1.1 costumam depender de código da era do PHP 5, prefixos de +classe como `CController` e autoloading pelo nome da classe. Aplicações Yii3 +exigem PHP moderno e autoloading do Composer. Yii 1.1: @@ -137,7 +140,7 @@ final readonly class Action } ``` -Configure your application namespace with PSR-4: +Configure o namespace da sua aplicação com PSR-4: ```json { @@ -149,20 +152,21 @@ Configure your application namespace with PSR-4: } ``` -Run: +Execute: ```shell composer dump-autoload ``` -When reusing a class, give it a namespace, add strict types, replace Yii 1.1 -base classes, and inject dependencies instead of reading them from global -application state. If these changes make the class awkward, use the old -class as a specification and write a new Yii3 class instead. +Ao reutilizar uma classe, dê a ela um namespace, adicione strict types, +substitua as classes base do Yii 1.1 e injete as dependências em vez de +lê-las do estado global da aplicação. Se essas mudanças deixarem a classe +estranha, use a classe antiga como especificação e escreva uma nova classe +Yii3. -## Project structure +## Estrutura do projeto -A Yii 1.1 application often uses: +Uma aplicação Yii 1.1 frequentemente usa: ```text protected/ @@ -179,7 +183,7 @@ themes/ webroot/ ``` -The current Yii3 application template uses: +O template de aplicação atual do Yii3 usa: ```text assets/ @@ -190,28 +194,28 @@ src/ tests/ ``` -Typical mappings to consider are: +Mapeamentos típicos a considerar: | Yii 1.1 | Yii3 | |---------|------| -| `protected/controllers` | `src/Web/*/Action.php` or controller-like services | -| `protected/models` | `src/Domain`, `src/Shared`, `src/Db`, or form models by responsibility | -| `protected/views` | templates near the feature, for example `src/Web/HomePage/template.php` | -| `protected/views/layouts` | layout templates and assets under `src/Web/Shared/Layout` | -| `protected/components` | services configured in the dependency injection container | -| `protected/extensions` | Composer packages or local packages | +| `protected/controllers` | `src/Web/*/Action.php` ou serviços no estilo controller | +| `protected/models` | `src/Domain`, `src/Shared`, `src/Db` ou form models, conforme a responsabilidade | +| `protected/views` | templates perto da funcionalidade, por exemplo `src/Web/HomePage/template.php` | +| `protected/views/layouts` | templates de layout e assets em `src/Web/Shared/Layout` | +| `protected/components` | serviços configurados no container de injeção de dependência | +| `protected/extensions` | pacotes Composer ou pacotes locais | | `protected/commands` | `src/Console/*Command.php` | -| `protected/messages` | translator message files | +| `protected/messages` | arquivos de mensagens do tradutor | | `protected/config` | `config/common`, `config/web`, `config/console`, `config/environments` | | `webroot` | `public` | -Do not recreate `protected` in Yii3. Put PHP source under `src`, public -files under `public`, generated/runtime files under `runtime`, and -configuration under `config`. +Não recrie `protected` no Yii3. Coloque o código PHP em `src`, os arquivos +públicos em `public`, os arquivos gerados/de runtime em `runtime` e a +configuração em `config`. -## Configuration and application components +## Configuração e componentes da aplicação -Yii 1.1 configuration is usually one large array: +A configuração do Yii 1.1 geralmente é um único array grande: ```php return [ @@ -232,22 +236,22 @@ return [ ]; ``` -In Yii3, configuration is split by purpose and services are wired through -the container: +No Yii3, a configuração é dividida por finalidade e os serviços são +conectados pelo container: -- aliases in `config/common/aliases.php`; -- parameters in `config/common/params.php` and environment files; -- shared service definitions in `config/common/di/*.php`; -- web-only service definitions in `config/web/di/*.php`; -- routes in `config/common/routes.php`; -- console commands in `config/console/*.php`. +- aliases em `config/common/aliases.php`; +- parâmetros em `config/common/params.php` e nos arquivos de ambiente; +- definições de serviços compartilhadas em `config/common/di/*.php`; +- definições de serviços apenas para web em `config/web/di/*.php`; +- rotas em `config/common/routes.php`; +- comandos de console em `config/console/*.php`. -The default template's console DI group reuses shared definitions from -`config/common/di/*.php`. If you need console-only container definitions, -add files for them to the `di-console` group in `config/configuration.php` -and rebuild the merge plan. +O grupo de DI de console do template padrão reutiliza as definições +compartilhadas de `config/common/di/*.php`. Se você precisar de definições +de container apenas para o console, adicione arquivos para elas ao grupo +`di-console` em `config/configuration.php` e reconstrua o merge plan. -Replace `Yii::app()->componentName` with constructor-injected services: +Substitua `Yii::app()->componentName` por serviços injetados pelo construtor: ```php use Yiisoft\Db\Connection\ConnectionInterface; @@ -263,13 +267,14 @@ final readonly class PostRepository } ``` -See [Configuration](../concept/configuration.md), -[Aliases](../concept/aliases.md), and [Dependency injection -container](../concept/di-container.md). +Veja [Configuração](../concept/configuration.md), +[Aliases](../concept/aliases.md) e [Container de injeção de +dependência](../concept/di-container.md). -## Entry script +## Script de entrada -Yii 1.1 entry scripts commonly load `yii.php` and create a web application: +Os scripts de entrada do Yii 1.1 geralmente carregam `yii.php` e criam uma +aplicação web: ```php require_once __DIR__ . '/../framework/yii.php'; @@ -277,18 +282,18 @@ require_once __DIR__ . '/../framework/yii.php'; Yii::createWebApplication($config)->run(); ``` -Yii3 entry scripts load Composer and bootstrap the configured -application. Start with the `public/index.php` file from `yiisoft/app` and -adjust configuration instead of building the application manually in the -entry script. +Os scripts de entrada do Yii3 carregam o Composer e inicializam a aplicação +configurada. Comece com o arquivo `public/index.php` do `yiisoft/app` e +ajuste a configuração em vez de montar a aplicação manualmente no script de +entrada. -See [Entry scripts](../structure/entry-script.md) and [Application -workflow](../start/workflow.md). +Veja [Scripts de entrada](../structure/entry-script.md) e [Fluxo da +aplicação](../start/workflow.md). -## Controllers, actions, and routes +## Controllers, actions e rotas -Yii 1.1 controllers extend `CController`, and actions are methods named -`actionName`: +Os controllers do Yii 1.1 estendem `CController`, e as actions são métodos +chamados `actionName`: ```php class PostController extends CController @@ -306,8 +311,8 @@ class PostController extends CController } ``` -Yii3 does not require controller inheritance. The current template uses -invokable action classes: +O Yii3 não exige herança de controller. O template atual usa classes de +action invocáveis: ```php namespace App\Web\Post\View; @@ -337,7 +342,7 @@ final readonly class Action } ``` -The route is explicit: +A rota é explícita: ```php use App\Web\Post\View; @@ -350,16 +355,16 @@ return [ ]; ``` -Define routes before action bodies. It gives you a checklist of request -flows you decided to keep in the Yii3 application. +Defina as rotas antes do corpo das actions. Isso dá a você uma checklist dos +fluxos de requisição que você decidiu manter na aplicação Yii3. -See [Actions](../structure/action.md), -[Middleware](../structure/middleware.md), and [Routing and URL -generation](../runtime/routing.md). +Veja [Actions](../structure/action.md), +[Middleware](../structure/middleware.md) e [Roteamento e geração de +URLs](../runtime/routing.md). -## Requests, responses, redirects, sessions, and cookies +## Requisições, respostas, redirecionamentos, sessões e cookies -Yii 1.1 code often reads and writes through `Yii::app()`: +O código Yii 1.1 frequentemente lê e escreve por meio de `Yii::app()`: ```php $id = Yii::app()->request->getParam('id'); @@ -367,17 +372,18 @@ Yii::app()->user->setFlash('success', 'Saved.'); $this->redirect(['post/view', 'id' => $id]); ``` -Yii3 uses PSR-7 request and response objects and injectable -services. Request input is available from `ServerRequestInterface`; -redirects, sessions, cookies, and responses are explicit dependencies. +O Yii3 usa objetos de requisição e resposta PSR-7 e serviços injetáveis. A +entrada da requisição está disponível em `ServerRequestInterface`; +redirecionamentos, sessões, cookies e respostas são dependências explícitas. -See [Request](../runtime/request.md), [Response](../runtime/response.md), -[Sessions](../runtime/sessions.md), and [Cookies](../runtime/cookies.md). +Veja [Requisição](../runtime/request.md), +[Resposta](../runtime/response.md), [Sessões](../runtime/sessions.md) e +[Cookies](../runtime/cookies.md). -## Views and layouts +## Views e layouts -Yii 1.1 views use `$this` as the controller or widget context. Layouts and -partials are rendered through controller methods: +As views do Yii 1.1 usam `$this` como o contexto do controller ou do +widget. Layouts e partials são renderizados por métodos do controller: ```php title); ?> ``` -In Yii3 templates, `$this` is a `Yiisoft\View\WebView` instance: +Nos templates do Yii3, `$this` é uma instância de `Yiisoft\View\WebView`: ```php use Yiisoft\Html\Html; @@ -405,24 +411,24 @@ $this->setTitle($post->getTitle());

getTitle()) ?>

``` -Move controller-specific view logic to the action or to a presenter. Pass -only the data a template needs. +Mova a lógica de view específica do controller para a action ou para um +presenter. Passe apenas os dados de que o template precisa. -See [View](../views/view.md), [View -injections](../views/view-injections.md), and [Template +Veja [View](../views/view.md), [Injeções de +view](../views/view-injections.md) e [Template engines](../views/template-engines.md). -## Assets and client scripts +## Assets e scripts do cliente -Yii 1.1 applications often use `CClientScript`, themes, and -extension-specific asset publishing: +Aplicações Yii 1.1 frequentemente usam `CClientScript`, temas e publicação +de assets específica de extensões: ```php Yii::app()->clientScript->registerCssFile('/css/site.css'); Yii::app()->clientScript->registerScriptFile('/js/site.js'); ``` -Yii3 uses asset bundles from `yiisoft/assets`: +O Yii3 usa asset bundles do `yiisoft/assets`: ```php namespace App\Web\Shared\Layout\Main; @@ -440,26 +446,26 @@ final class MainAsset extends AssetBundle } ``` -Register bundles through the asset manager in layouts or views. +Registre os bundles pelo gerenciador de assets nos layouts ou views. -See [Assets](../views/asset.md) and [Scripts, styles and +Veja [Assets](../views/asset.md) e [Scripts, estilos e metatags](../views/script-style-meta.md). -## Models, forms, and validation +## Models, formulários e validação -Yii 1.1 has `CModel`, `CFormModel`, and `CActiveRecord`. It is common for -one model class to contain input data, labels, validation rules, database -persistence, and business logic. +O Yii 1.1 tem `CModel`, `CFormModel` e `CActiveRecord`. É comum uma única +classe de model conter os dados de entrada, rótulos, regras de validação, +persistência no banco de dados e lógica de negócio. -Yii3 works better when these responsibilities are split: +O Yii3 funciona melhor quando essas responsabilidades são separadas: -- form data and labels: `yiisoft/form-model`; -- validation rules: `yiisoft/validator`; -- form rendering: `yiisoft/form`; -- persistence: repositories, `yiisoft/db`, or `yiisoft/active-record`; -- business workflows: application services. +- dados e rótulos do formulário: `yiisoft/form-model`; +- regras de validação: `yiisoft/validator`; +- renderização de formulários: `yiisoft/form`; +- persistência: repositórios, `yiisoft/db` ou `yiisoft/active-record`; +- fluxos de negócio: serviços da aplicação. -Yii 1.1 form model: +Form model no Yii 1.1: ```php class ContactForm extends CFormModel @@ -477,7 +483,7 @@ class ContactForm extends CFormModel } ``` -Yii3 form model: +Form model no Yii3: ```php use Yiisoft\FormModel\FormModel; @@ -495,14 +501,15 @@ final class ContactForm extends FormModel } ``` -See [Working with forms](../start/forms.md), [Validating -input](https://github.com/yiisoft/validator/blob/master/docs/guide/en/README.md), -[yiisoft/form](https://github.com/yiisoft/form), and +Veja [Trabalhando com formulários](../start/forms.md), [Validando a +entrada](https://github.com/yiisoft/validator/blob/master/docs/guide/en/README.md), +[yiisoft/form](https://github.com/yiisoft/form) e [yiisoft/form-model](https://github.com/yiisoft/form-model). ## Active Record -Yii 1.1 Active Record uses `CActiveRecord::model()` and dynamic attributes: +O Active Record do Yii 1.1 usa `CActiveRecord::model()` e atributos +dinâmicos: ```php class Post extends CActiveRecord @@ -527,7 +534,7 @@ class Post extends CActiveRecord } ``` -The incremental Yii3 option is +A opção incremental no Yii3 é o [yiisoft/active-record](https://github.com/yiisoft/active-record): ```php @@ -556,36 +563,36 @@ final class Post extends ActiveRecord } ``` -Move Yii 1.1 `rules()` to a form model, validator rules, or a service. Keep -Active Record focused on persistence: table mapping, properties, relations, -and database operations. +Mova o `rules()` do Yii 1.1 para um form model, regras do validator ou um +serviço. Mantenha o Active Record focado em persistência: mapeamento de +tabelas, propriedades, relações e operações no banco de dados. -For more complex applications, consider replacing Active Record-heavy code -with repositories and domain objects. That is more work initially, but it -avoids carrying Yii 1.1 form and persistence coupling into the new -application. +Em aplicações mais complexas, considere substituir o código muito dependente +de Active Record por repositórios e objetos de domínio. Dá mais trabalho no +início, mas evita carregar o acoplamento entre formulário e persistência do +Yii 1.1 para a nova aplicação. -See [Working with databases](../start/databases.md), -[Migrations](../databases/db-migrations.md), and +Veja [Trabalhando com banco de dados](../start/databases.md), +[Migrations](../databases/db-migrations.md) e [yiisoft/active-record](https://github.com/yiisoft/active-record). -## Database queries and migrations +## Consultas ao banco de dados e migrations -Yii 1.1 code may use `CDbCriteria`, `CDbCommand`, `CActiveDataProvider`, and -`CGridView` data providers. In Yii3, use `yiisoft/db` for database access -and query building, and `yiisoft/data` / `yiisoft/yii-dataview` for data -readers and widgets. +O código Yii 1.1 pode usar `CDbCriteria`, `CDbCommand`, +`CActiveDataProvider` e data providers do `CGridView`. No Yii3, use +`yiisoft/db` para acesso ao banco de dados e construção de consultas, e +`yiisoft/data` / `yiisoft/yii-dataview` para data readers e widgets. -Migrations are not compatible across Yii 1.1 and Yii3. For an existing -application, create a baseline from the current schema and use Yii3 -migrations for new changes. +As migrations não são compatíveis entre o Yii 1.1 e o Yii3. Para uma +aplicação existente, crie uma base a partir do esquema atual e use +migrations do Yii3 para as novas mudanças. -See [Working with databases](../start/databases.md) and +Veja [Trabalhando com banco de dados](../start/databases.md) e [Migrations](../databases/db-migrations.md). -## GridView and data widgets +## GridView e widgets de dados -Yii 1.1 `CGridView` is often configured with `CActiveDataProvider`: +O `CGridView` do Yii 1.1 costuma ser configurado com `CActiveDataProvider`: ```php $this->widget('zii.widgets.grid.CGridView', [ @@ -600,7 +607,8 @@ $this->widget('zii.widgets.grid.CGridView', [ ]); ``` -Yii3 uses [yiisoft/yii-dataview](https://github.com/yiisoft/yii-dataview): +O Yii3 usa o +[yiisoft/yii-dataview](https://github.com/yiisoft/yii-dataview): ```php use Yiisoft\Data\Reader\ReadableDataInterface; @@ -621,15 +629,16 @@ echo GridView::widget() ); ``` -Replace the old data provider with a query service that returns a data -reader. Model filters as validator rules and route or query parameters. +Substitua o antigo data provider por um serviço de consulta que retorne um +data reader. Modele os filtros como regras do validator e parâmetros de rota +ou de consulta. -See [Using htmx for partial -reloads](../../cookbook/using-htmx-for-partial-reloads.md) and [yii-dataview -GridView -docs](https://github.com/yiisoft/yii-dataview/blob/master/docs/en/guide/gridview.md). +Veja [Usando htmx para recarregamentos +parciais](../../cookbook/using-htmx-for-partial-reloads.md) e a +[documentação do GridView do +yii-dataview](https://github.com/yiisoft/yii-dataview/blob/master/docs/en/guide/gridview.md). -## URL management +## Gerenciamento de URLs Yii 1.1: @@ -649,14 +658,15 @@ $url = $urlGenerator->generate('post/view', ['id' => $post->getId()]); echo Html::a('View', $url)->render(); ``` -Prefer named routes. They make views and GridView action columns easier to -design and maintain. +Prefira rotas nomeadas. Elas tornam as views e as colunas de action do +GridView mais fáceis de projetar e manter. -See [Routing and URL generation](../runtime/routing.md). +Veja [Roteamento e geração de URLs](../runtime/routing.md). -## Filters, access control, and authentication +## Filtros, controle de acesso e autenticação -Yii 1.1 controller filters are controller methods or filter classes: +Os filtros de controller do Yii 1.1 são métodos do controller ou classes de +filtro: ```php public function filters() @@ -667,31 +677,33 @@ public function filters() } ``` -Yii3 uses middleware and focused packages. Move authentication, -authorization, CSRF, locale detection, and request body parsing out of -controllers and into middleware or services. +O Yii3 usa middleware e pacotes focados. Mova autenticação, autorização, +CSRF, detecção de idioma e parsing do corpo da requisição para fora dos +controllers, em middlewares ou serviços. -See [Middleware](../structure/middleware.md), -[Authentication](../security/authentication.md), and -[Authorization](../security/authorization.md). +Veja [Middleware](../structure/middleware.md), +[Autenticação](../security/authentication.md) e +[Autorização](../security/authorization.md). -## Widgets, helpers, and extensions +## Widgets, helpers e extensões -Yii 1.1 widgets and helpers usually depend on Yii-specific base classes such -as `CWidget`, `CHtml`, and extension autoloading. In Yii3: +Os widgets e helpers do Yii 1.1 geralmente dependem de classes base +específicas do Yii, como `CWidget` e `CHtml`, e do autoloading de +extensões. No Yii3: -- replace helper calls with `yiisoft/html`, `yiisoft/arrays`, - `yiisoft/strings`, or application helpers; -- replace extensions with Composer packages; -- rebuild custom widgets with `yiisoft/widget` or plain services/templates; -- replace jQuery UI and Bootstrap widgets with current frontend packages or - Yii3 widget packages where available. +- substitua as chamadas a helpers por `yiisoft/html`, `yiisoft/arrays`, + `yiisoft/strings` ou helpers da aplicação; +- substitua as extensões por pacotes Composer; +- reconstrua widgets personalizados com `yiisoft/widget` ou com + serviços/templates simples; +- substitua os widgets do jQuery UI e do Bootstrap por pacotes de frontend + atuais ou pacotes de widgets do Yii3, quando disponíveis. -See [Widgets](../views/widget.md). +Veja [Widgets](../views/widget.md). -## Console applications +## Aplicações de console -Yii 1.1 console commands extend `CConsoleCommand`: +Os comandos de console do Yii 1.1 estendem `CConsoleCommand`: ```php class ReportCommand extends CConsoleCommand @@ -702,7 +714,8 @@ class ReportCommand extends CConsoleCommand } ``` -Yii3 console commands are Symfony Console commands configured as services: +Os comandos de console do Yii3 são comandos do Symfony Console configurados +como serviços: ```php namespace App\Console; @@ -722,31 +735,31 @@ final class SendReportCommand extends Command } ``` -See [Console applications](../tutorial/console-applications.md). +Veja [Aplicações de console](../tutorial/console-applications.md). -## Internationalization +## Internacionalização -Yii 1.1 message files under `protected/messages` can usually be kept -conceptually, but configuration changes. Yii3 uses translator packages and -explicit message sources. Move message files into the structure expected by -the selected translator message package and inject translation services -where needed. +Os arquivos de mensagens do Yii 1.1 em `protected/messages` geralmente podem +ser mantidos conceitualmente, mas a configuração muda. O Yii3 usa pacotes de +tradução e fontes de mensagens explícitas. Mova os arquivos de mensagens +para a estrutura esperada pelo pacote de mensagens do tradutor escolhido e +injete os serviços de tradução onde for necessário. -See [Internationalization](../tutorial/i18n.md). +Veja [Internacionalização](../tutorial/i18n.md). -## What to refactor before reusing +## O que refatorar antes de reutilizar -These Yii 1.1 refactorings make the old behavior easier to understand and -reuse: +Estas refatorações no Yii 1.1 tornam o comportamento antigo mais fácil de +entender e reutilizar: -- isolate database queries from controllers; -- remove direct `Yii::app()` access from domain code; -- move validation out of Active Record when it describes request input - rather than database invariants; -- replace large controller actions with services; -- document all routes and URL rules; -- add tests around the flows you plan to rebuild first; -- upgrade PHP syntax gradually if the old runtime allows it. +- isole as consultas ao banco de dados dos controllers; +- remova o acesso direto a `Yii::app()` do código de domínio; +- tire a validação do Active Record quando ela descreve a entrada da + requisição, e não invariantes do banco de dados; +- substitua actions grandes de controller por serviços; +- documente todas as rotas e regras de URL; +- adicione testes em torno dos fluxos que você planeja reconstruir primeiro; +- atualize a sintaxe PHP gradualmente, se o runtime antigo permitir. -The goal is not to make Yii 1.1 look like Yii3. The goal is to reduce hidden -coupling before the code crosses the framework boundary. +O objetivo não é fazer o Yii 1.1 parecer com o Yii3. O objetivo é reduzir o +acoplamento oculto antes que o código cruze a fronteira do framework. diff --git a/src/pt-BR/guide/intro/upgrade-from-v2.md b/src/pt-BR/guide/intro/upgrade-from-v2.md index daf46bb5..f80fa548 100644 --- a/src/pt-BR/guide/intro/upgrade-from-v2.md +++ b/src/pt-BR/guide/intro/upgrade-from-v2.md @@ -1,80 +1,83 @@ -# Upgrading from Version 2.0 +# Migrando da versão 2.0 -> If you haven't used Yii 2.0, you can skip this section and get directly to "[getting started](../start/prerequisites.md)" -> section. +> Se você não usou o Yii 2.0, pode pular esta seção e ir direto para a seção "[primeiros passos](../start/prerequisites.md)" +> do guia. -Yii3 keeps many Yii ideas, but it is not a drop-in replacement for Yii -2.0. It uses PHP 8 features, PSR interfaces, dependency injection, explicit -package composition, and a different application template. Use your Yii 2.0 -experience to design a new Yii3 application deliberately instead of trying -to reproduce the old application structure. +O Yii3 mantém muitas ideias do Yii, mas não é um substituto direto do Yii +2.0. Ele usa recursos do PHP 8, interfaces PSR, injeção de dependência, +composição explícita de pacotes e um template de aplicação diferente. Use +sua experiência com o Yii 2.0 para projetar uma nova aplicação Yii3 de forma +deliberada, em vez de tentar reproduzir a estrutura da aplicação antiga. -For source applications, compare against: +Para as aplicações de origem, compare com: - [yiisoft/yii2-app-basic](https://github.com/yiisoft/yii2-app-basic) - [yiisoft/yii2-app-advanced](https://github.com/yiisoft/yii2-app-advanced) -For the target structure, compare against: +Para a estrutura de destino, compare com: - [yiisoft/app](https://github.com/yiisoft/app) -- [Yii3 guide](../index.md) - -Before starting, [check maintenance policy and end-of-life dates for Yii -2.0](https://www.yiiframework.com/release-cycle). Keeping a mature Yii 2.0 -application on Yii 2.0 can be a valid choice. A Yii3 project is most useful -when you want the new package ecosystem, stricter typing, PSR middleware, -and a more explicit architecture. - -## Recommended approach - -Think of the work as building a Yii3 application that is informed by the old -one. The old project tells you which routes, forms, database tables, -business rules, and user workflows matter. The Yii3 project should decide -again where these responsibilities belong. - -Build it in vertical slices: - -1. Create a new Yii3 application with `yiisoft/app`. -2. Configure Composer autoloading and add only the code needed for the slice - you are building. -3. Define configuration and routes before writing actions. -4. Build one request flow at a time: route, action, input model, service, - persistence, view, assets, tests. -5. Keep the Yii 2.0 application running until each flow is verified in Yii3. - -Avoid moving the whole directory tree first. Yii3's defaults are -intentionally different, and a mechanical copy tends to preserve Yii 2.0 -service-locator assumptions. Prefer small, reviewed decisions over carrying -old structure forward because it is familiar. - -## Prepare the Yii 2.0 application - -Useful preparation can happen before the Yii3 application is ready. These -refactorings improve the Yii 2.0 project itself and make the later rewrite -less dependent on hidden framework state: - -- Replace `Yii::$app` access in reusable code with constructor arguments - where practical. If a full dependency injection refactoring is too large, - keep `Yii::$app` calls near controllers and widgets, then pass values and - services to lower-level code explicitly. -- Introduce repositories or query services for database reads that are - currently scattered across controllers, views, widgets, and Active Record - methods. Yii3 does not require Active Record for persistence, so a - repository boundary gives you a natural place to change the implementation - later. -- Separate business rules from framework infrastructure. Domain code that - does not extend Yii classes, read global application state, or render - views is much easier to reuse or rewrite. -- Move reusable behavior into Yii 2.0 components or services instead of - keeping it inside large controllers and Active Record classes. Yii3 - services are configured and injected differently, but the responsibility - boundary is similar. -- Add tests around routes and workflows you plan to rebuild first. They - become the executable specification for the Yii3 slice. - -For example, instead of reading post archive data directly from several -controllers or widgets, create a small service that describes the -application need: +- [Guia do Yii3](../index.md) + +Antes de começar, [confira a política de manutenção e as datas de fim de +vida do Yii 2.0](https://www.yiiframework.com/release-cycle). Manter uma +aplicação Yii 2.0 madura no Yii 2.0 pode ser uma escolha válida. Um projeto +Yii3 é mais útil quando você quer o novo ecossistema de pacotes, tipagem +mais rigorosa, middleware PSR e uma arquitetura mais explícita. + +## Abordagem recomendada + +Pense no trabalho como a construção de uma aplicação Yii3 guiada pela +antiga. O projeto antigo diz quais rotas, formulários, tabelas do banco de +dados, regras de negócio e fluxos dos usuários importam. O projeto Yii3 deve +decidir de novo onde cada uma dessas responsabilidades fica. + +Construa em vertical slices: + +1. Crie uma nova aplicação Yii3 com `yiisoft/app`. +2. Configure o autoloading do Composer e adicione só o código necessário + para o slice que você está construindo. +3. Defina a configuração e as rotas antes de escrever as actions. +4. Construa um fluxo de requisição por vez: rota, action, modelo de entrada, + serviço, persistência, view, assets, testes. +5. Mantenha a aplicação Yii 2.0 rodando até cada fluxo ser verificado no + Yii3. + +Evite mover toda a árvore de diretórios primeiro. Os padrões do Yii3 são +intencionalmente diferentes, e uma cópia mecânica tende a preservar as +suposições de service locator do Yii 2.0. Prefira decisões pequenas e +revisadas a carregar a estrutura antiga só porque ela é familiar. + +## Prepare a aplicação Yii 2.0 + +Uma preparação útil pode acontecer antes de a aplicação Yii3 estar +pronta. Estas refatorações melhoram o próprio projeto Yii 2.0 e deixam a +reescrita posterior menos dependente de estado oculto do framework: + +- Substitua o acesso a `Yii::$app` no código reutilizável por argumentos do + construtor onde for viável. Se uma refatoração completa para injeção de + dependência for grande demais, mantenha as chamadas a `Yii::$app` perto de + controllers e widgets, e passe valores e serviços explicitamente para o + código de nível mais baixo. +- Introduza repositórios ou serviços de consulta para as leituras do banco + de dados hoje espalhadas por controllers, views, widgets e métodos do + Active Record. O Yii3 não exige Active Record para persistência, então uma + fronteira de repositório dá a você um lugar natural para trocar a + implementação depois. +- Separe as regras de negócio da infraestrutura do framework. Código de + domínio que não estende classes do Yii, não lê o estado global da + aplicação nem renderiza views é muito mais fácil de reutilizar ou + reescrever. +- Mova o comportamento reutilizável para componentes ou serviços do Yii 2.0 + em vez de mantê-lo dentro de controllers e classes Active Record + grandes. Os serviços do Yii3 são configurados e injetados de outra forma, + mas a fronteira de responsabilidade é parecida. +- Adicione testes em torno das rotas e fluxos que você planeja reconstruir + primeiro. Eles se tornam a especificação executável do slice Yii3. + +Por exemplo, em vez de ler os dados do arquivo de posts diretamente em +vários controllers ou widgets, crie um pequeno serviço que descreva a +necessidade da aplicação: ```php final class PostRepository @@ -91,67 +94,69 @@ final class PostRepository } ``` -The Yii3 implementation may still use Active Record, or it may use -`yiisoft/db` queries. The important point is that controllers and views no -longer need to know that detail. - -## Things to learn before starting - -Some Yii3 application-template choices are worth learning before you start -moving features: - -- [Docker](https://www.docker.com/get-started/). The default Yii3 - application template includes Docker configuration. Using it gives each - application its own repeatable environment and reduces differences between - local development and production. -- [Environment - variables](https://en.wikipedia.org/wiki/Environment_variable). Yii3 - templates commonly use them for environment-specific settings and secrets, - especially in Docker-based deployments. This follows the same idea as - [12-factor app configuration](https://12factor.net/config). -- [Actions](../structure/action.md). Yii3 does not require controller - inheritance. A route can point to any callable, and the default template - uses invokable action classes. -- [Application structure](../structure/overview.md). Yii3's default - structure is different from Yii 2.0. The structure is flexible, but start - with the Yii3 template and change it only when the application needs it. - -## PHP requirements - -Yii3 application templates require PHP 8.2 or above. As a result, -application code can use language features that were not common in Yii 2.0 -applications: - -- [Type - declarations](https://www.php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration) -- [Return type - declarations](https://www.php.net/manual/en/functions.returning-values.php#functions.returning-values.type-declaration) -- [Class constant - visibility](https://www.php.net/manual/en/language.oop5.constants.php) -- [Named - arguments](https://www.php.net/manual/en/functions.arguments.php#functions.named-arguments) -- [Anonymous - classes](https://www.php.net/manual/en/language.oop5.anonymous.php) +A implementação no Yii3 ainda pode usar Active Record, ou pode usar +consultas do `yiisoft/db`. O importante é que controllers e views não +precisem mais conhecer esse detalhe. + +## O que aprender antes de começar + +Vale a pena conhecer algumas escolhas do template de aplicação do Yii3 antes +de começar a mover funcionalidades: + +- [Docker](https://www.docker.com/get-started/). O template de aplicação + padrão do Yii3 inclui configuração do Docker. Usá-lo dá a cada aplicação + seu próprio ambiente reproduzível e reduz as diferenças entre o + desenvolvimento local e a produção. +- [Variáveis de + ambiente](https://en.wikipedia.org/wiki/Environment_variable). Os + templates do Yii3 costumam usá-las para configurações específicas de + ambiente e segredos, especialmente em deploys baseados em Docker. Isso + segue a mesma ideia da [configuração de aplicações + 12-factor](https://12factor.net/config). +- [Actions](../structure/action.md). O Yii3 não exige herança de + controller. Uma rota pode apontar para qualquer callable, e o template + padrão usa classes de action invocáveis. +- [Estrutura da aplicação](../structure/overview.md). A estrutura padrão do + Yii3 é diferente da do Yii 2.0. Ela é flexível, mas comece com o template + do Yii3 e altere-o apenas quando a aplicação precisar. + +## Requisitos de PHP + +Os templates de aplicação do Yii3 exigem PHP 8.2 ou superior. Com isso, o +código da aplicação pode usar recursos da linguagem que não eram comuns em +aplicações Yii 2.0: + +- [Declarações de + tipo](https://www.php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration) +- [Declarações de tipo de + retorno](https://www.php.net/manual/en/functions.returning-values.php#functions.returning-values.type-declaration) +- [Visibilidade de constantes de + classe](https://www.php.net/manual/en/language.oop5.constants.php) +- [Argumentos + nomeados](https://www.php.net/manual/en/functions.arguments.php#functions.named-arguments) +- [Classes + anônimas](https://www.php.net/manual/en/language.oop5.anonymous.php) - [::class](https://www.php.net/manual/en/language.oop5.basic.php#language.oop5.basic.class.class) - [Generators](https://www.php.net/manual/en/language.generators.php) -- [Variadic - functions](https://www.php.net/manual/en/functions.arguments.php#functions.variable-arg-list) -- [Readonly - properties](https://www.php.net/manual/en/language.oop5.properties.php#language.oop5.properties.readonly-properties) -- [Readonly - classes](https://www.php.net/manual/en/language.oop5.basic.php#language.oop5.basic.class.readonly) -- [Constructor property - promotion](https://www.php.net/manual/en/language.oop5.decon.php#language.oop5.decon.constructor.promotion) -- [Attributes](https://www.php.net/manual/en/language.attributes.php) - -Run static analysis and tests on Yii 2.0 before reusing code in Yii3. Code -with explicit types, small services, and few implicit `Yii::$app` -dependencies is easier to understand and easier to place in the new -application. - -## Project structure - -Yii 2.0 applications commonly keep framework roles in top-level directories: +- [Funções + variádicas](https://www.php.net/manual/en/functions.arguments.php#functions.variable-arg-list) +- [Propriedades + readonly](https://www.php.net/manual/en/language.oop5.properties.php#language.oop5.properties.readonly-properties) +- [Classes + readonly](https://www.php.net/manual/en/language.oop5.basic.php#language.oop5.basic.class.readonly) +- [Promoção de propriedades no + construtor](https://www.php.net/manual/en/language.oop5.decon.php#language.oop5.decon.constructor.promotion) +- [Atributos](https://www.php.net/manual/en/language.attributes.php) + +Rode análise estática e testes no Yii 2.0 antes de reutilizar código no +Yii3. Código com tipos explícitos, serviços pequenos e poucas dependências +implícitas de `Yii::$app` é mais fácil de entender e de encaixar na nova +aplicação. + +## Estrutura do projeto + +Aplicações Yii 2.0 costumam manter os papéis do framework em diretórios de +primeiro nível: ```text assets/ @@ -165,7 +170,7 @@ web/ widgets/ ``` -The Yii 2.0 advanced template splits the same roles by application: +O template advanced do Yii 2.0 divide os mesmos papéis por aplicação: ```text backend/ @@ -174,8 +179,8 @@ console/ frontend/ ``` -The current Yii3 application template is organized around source code, -configuration, public files, and runtime files: +O template de aplicação atual do Yii3 é organizado em torno do código-fonte, +da configuração, dos arquivos públicos e dos arquivos de runtime: ```text assets/ @@ -186,32 +191,32 @@ src/ tests/ ``` -Typical mappings to consider are: +Mapeamentos típicos a considerar: | Yii 2.0 basic | Yii 2.0 advanced | Yii3 | |---------------|------------------|------| -| `controllers/` | `frontend/controllers/`, `backend/controllers/` | `src/Web/*/Action.php` or controller-like classes | -| `models/` | `common/models/`, app-specific models | `src/Domain`, `src/Shared`, `src/Web/*`, or `src/Db` by responsibility | -| `views/` | `frontend/views/`, `backend/views/` | templates near the feature, for example `src/Web/HomePage/template.php` | -| `views/layouts/` | app layout directories | layout classes/templates, for example `src/Web/Shared/Layout/Main` | -| `assets/` | app asset bundles | `assets/` for source files and `src/Web/.../*Asset.php` for bundles | +| `controllers/` | `frontend/controllers/`, `backend/controllers/` | `src/Web/*/Action.php` ou classes no estilo controller | +| `models/` | `common/models/`, models específicos de cada app | `src/Domain`, `src/Shared`, `src/Web/*` ou `src/Db`, conforme a responsabilidade | +| `views/` | `frontend/views/`, `backend/views/` | templates perto da funcionalidade, por exemplo `src/Web/HomePage/template.php` | +| `views/layouts/` | diretórios de layout de cada app | classes/templates de layout, por exemplo `src/Web/Shared/Layout/Main` | +| `assets/` | asset bundles de cada app | `assets/` para os arquivos-fonte e `src/Web/.../*Asset.php` para os bundles | | `web/` | `frontend/web/`, `backend/web/` | `public/` | | `commands/` | `console/controllers/` | `src/Console/*Command.php` | -| `config/*.php` | app and common config files | `config/common`, `config/web`, `config/console`, `config/environments` | +| `config/*.php` | arquivos de configuração do app e comuns | `config/common`, `config/web`, `config/console`, `config/environments` | -There is no single required layout. The important change is that Yii3 -applications should group code by responsibility and make dependencies -explicit. If you are coming from the advanced template, treat `frontend` and -`backend` as separate web contexts. Shared domain code can live in -`src/Shared` or in application-specific packages. +Não existe um layout obrigatório único. A mudança importante é que +aplicações Yii3 devem agrupar o código por responsabilidade e tornar as +dependências explícitas. Se você vem do template advanced, trate `frontend` +e `backend` como contextos web separados. O código de domínio compartilhado +pode ficar em `src/Shared` ou em pacotes específicos da aplicação. -## Composer and autoloading +## Composer e autoloading -Yii 2.0 applications usually require `vendor/autoload.php` and -`vendor/yiisoft/yii2/Yii.php` in `web/index.php`. Yii3 applications require -only Composer's autoloader and application bootstrap code. +Aplicações Yii 2.0 geralmente fazem require de `vendor/autoload.php` e +`vendor/yiisoft/yii2/Yii.php` em `web/index.php`. Aplicações Yii3 precisam +apenas do autoloader do Composer e do código de bootstrap da aplicação. -Configure your application namespace with PSR-4: +Configure o namespace da sua aplicação com PSR-4: ```json { @@ -223,20 +228,21 @@ Configure your application namespace with PSR-4: } ``` -Then rebuild Composer autoload files: +Depois, reconstrua os arquivos de autoload do Composer: ```shell composer dump-autoload ``` -Install Yii3 packages intentionally. Yii3 is split into focused packages, so -features such as database access, forms, validation, assets, data widgets, -authentication, and caching are separate Composer dependencies. +Instale os pacotes Yii3 de forma intencional. O Yii3 é dividido em pacotes +focados, então funcionalidades como acesso ao banco de dados, formulários, +validação, assets, widgets de dados, autenticação e cache são dependências +separadas do Composer. -## Configuration and services +## Configuração e serviços -In Yii 2.0, many services are configured as application components and -accessed through the service locator: +No Yii 2.0, muitos serviços são configurados como componentes da aplicação e +acessados pelo service locator: ```php $cache = Yii::$app->cache; @@ -244,8 +250,8 @@ $db = Yii::$app->db; $url = Yii::$app->urlManager->createUrl(['post/view', 'id' => $id]); ``` -In Yii3, services are configured for the container and injected where they -are needed: +No Yii3, os serviços são configurados no container e injetados onde são +necessários: ```php use Psr\SimpleCache\CacheInterface; @@ -263,28 +269,29 @@ final readonly class PostService } ``` -Move configuration in groups: +Mova a configuração por grupos: -- aliases to `config/common/aliases.php`; -- route definitions to `config/common/routes.php`; -- shared service definitions to `config/common/di/*.php`; -- web-only service definitions to `config/web/di/*.php`; -- console parameters and commands to `config/console/*.php`; -- shared parameters to `config/common/params.php`; -- environment overrides to `config/environments`. +- aliases para `config/common/aliases.php`; +- definições de rotas para `config/common/routes.php`; +- definições de serviços compartilhadas para `config/common/di/*.php`; +- definições de serviços apenas para web para `config/web/di/*.php`; +- parâmetros e comandos de console para `config/console/*.php`; +- parâmetros compartilhados para `config/common/params.php`; +- sobrescritas por ambiente para `config/environments`. -The default template's `di-console` group reuses shared definitions from -`config/common/di/*.php`. If you need console-only container definitions, -add the corresponding files to the `di-console` group in -`config/configuration.php` and rebuild the merge plan. +O grupo `di-console` do template padrão reutiliza as definições +compartilhadas de `config/common/di/*.php`. Se você precisar de definições +de container apenas para o console, adicione os arquivos correspondentes ao +grupo `di-console` em `config/configuration.php` e reconstrua o merge plan. -See [Configuration](../concept/configuration.md), -[Aliases](../concept/aliases.md), and [Dependency injection -container](../concept/di-container.md). +Veja [Configuração](../concept/configuration.md), +[Aliases](../concept/aliases.md) e [Container de injeção de +dependência](../concept/di-container.md). -## Entry script and bootstrap +## Script de entrada e bootstrap -A Yii 2.0 basic entry script commonly creates the application directly: +Um script de entrada do template basic do Yii 2.0 geralmente cria a +aplicação diretamente: ```php defined('YII_DEBUG') or define('YII_DEBUG', true); @@ -298,18 +305,19 @@ $config = require __DIR__ . '/../config/web.php'; (new yii\web\Application($config))->run(); ``` -In Yii3, use the application template entry script as the source of -truth. It loads Composer and bootstraps the configured application -runner. Avoid recreating the old `yii\web\Application` pattern in -`public/index.php`; put configuration in config files and dependencies in -the container. +No Yii3, use o script de entrada do template de aplicação como fonte da +verdade. Ele carrega o Composer e inicializa o runner da aplicação +configurada. Evite recriar o antigo padrão `yii\web\Application` em +`public/index.php`; coloque a configuração nos arquivos de configuração e as +dependências no container. -See [Entry scripts](../structure/entry-script.md) and [Application -workflow](../start/workflow.md). +Veja [Scripts de entrada](../structure/entry-script.md) e [Fluxo da +aplicação](../start/workflow.md). -## Controllers, actions, and routing +## Controllers, actions e roteamento -Yii 2.0 routes usually point to controller action methods: +As rotas do Yii 2.0 geralmente apontam para métodos de action de +controllers: ```php namespace app\controllers; @@ -325,8 +333,8 @@ final class SiteController extends Controller } ``` -Yii3 does not require controller base classes. The current application -template uses invokable action classes: +O Yii3 não exige classes base de controller. O template de aplicação atual +usa classes de action invocáveis: ```php namespace App\Web\HomePage; @@ -348,7 +356,7 @@ final readonly class Action } ``` -Routes are explicit: +As rotas são explícitas: ```php use App\Web; @@ -365,19 +373,20 @@ return [ ]; ``` -When redesigning a controller flow, list all Yii 2.0 actions and create -named routes for the flows you still need. Then implement each flow as an -invokable class or a controller-like service. Constructor injection replaces -calls to `Yii::$app` and controller properties. +Ao redesenhar o fluxo de um controller, liste todas as actions do Yii 2.0 e +crie rotas nomeadas para os fluxos de que você ainda precisa. Depois, +implemente cada fluxo como uma classe invocável ou um serviço no estilo +controller. A injeção pelo construtor substitui as chamadas a `Yii::$app` e +as propriedades do controller. -See [Actions](../structure/action.md), -[Middleware](../structure/middleware.md), and [Routing and URL -generation](../runtime/routing.md). +Veja [Actions](../structure/action.md), +[Middleware](../structure/middleware.md) e [Roteamento e geração de +URLs](../runtime/routing.md). -## Requests, responses, sessions, and cookies +## Requisições, respostas, sessões e cookies -Yii 2.0 actions often read request data and write response data through -application components: +As actions do Yii 2.0 frequentemente leem os dados da requisição e escrevem +os dados da resposta por meio de componentes da aplicação: ```php $id = Yii::$app->request->get('id'); @@ -386,7 +395,7 @@ Yii::$app->session->setFlash('success', 'Saved.'); return $this->redirect(['post/view', 'id' => $id]); ``` -Yii3 uses PSR-7 request and response objects and injectable services: +O Yii3 usa objetos de requisição e resposta PSR-7 e serviços injetáveis: ```php use Psr\Http\Message\ResponseInterface; @@ -415,16 +424,17 @@ final readonly class SavePostAction } ``` -Design request handling early because it affects forms, filters, REST -endpoints, redirects, and tests. +Pense no tratamento de requisições logo no início, porque ele afeta +formulários, filtros, endpoints REST, redirecionamentos e testes. -See [Request](../runtime/request.md), [Response](../runtime/response.md), -[Sessions](../runtime/sessions.md), and [Cookies](../runtime/cookies.md). +Veja [Requisição](../runtime/request.md), +[Resposta](../runtime/response.md), [Sessões](../runtime/sessions.md) e +[Cookies](../runtime/cookies.md). -## Views, layouts, assets, and URLs +## Views, layouts, assets e URLs -In Yii 2.0, controller rendering finds files under `views/{controller}` and -layouts under `views/layouts`: +No Yii 2.0, a renderização do controller procura arquivos em +`views/{controller}` e layouts em `views/layouts`: ```php return $this->render('view', [ @@ -432,7 +442,7 @@ return $this->render('view', [ ]); ``` -In Yii3, the template path is explicit in the action: +No Yii3, o caminho do template é explícito na action: ```php return $this->viewRenderer->render(__DIR__ . '/view', [ @@ -440,7 +450,8 @@ return $this->viewRenderer->render(__DIR__ . '/view', [ ]); ``` -A Yii3 template receives a `Yiisoft\View\WebView` instance as `$this`: +Um template do Yii3 recebe uma instância de `Yiisoft\View\WebView` como +`$this`: ```php use App\Shared\ApplicationParams; @@ -459,7 +470,7 @@ $this->setTitle($title . ' - ' . $applicationParams->name);

``` -Asset bundles move from `yii\web\AssetBundle` to +Os asset bundles passam de `yii\web\AssetBundle` para `Yiisoft\Assets\AssetBundle`: ```php @@ -479,7 +490,7 @@ final class MainAsset extends AssetBundle } ``` -Register assets in a layout or view via the asset manager: +Registre os assets em um layout ou view pelo gerenciador de assets: ```php $assetManager->register(MainAsset::class); @@ -488,21 +499,21 @@ $this->addCssFiles($assetManager->getCssFiles()); $this->addJsFiles($assetManager->getJsFiles()); ``` -Replace `yii\helpers\Url` and `Yii::$app->urlManager` usage with named routes and +Substitua o uso de `yii\helpers\Url` e `Yii::$app->urlManager` por rotas nomeadas e `Yiisoft\Router\UrlGeneratorInterface`: ```php $url = $urlGenerator->generate('post/view', ['id' => $post->getId()]); ``` -See [View](../views/view.md), [Assets](../views/asset.md), [Scripts, styles -and metatags](../views/script-style-meta.md), and [Template +Veja [View](../views/view.md), [Assets](../views/asset.md), [Scripts, +estilos e metatags](../views/script-style-meta.md) e [Template engines](../views/template-engines.md). -## Forms and validation +## Formulários e validação -Yii 2.0 frequently combines form data, labels, validation, and sometimes -persistence in a `yii\base\Model` or `yii\db\ActiveRecord` class: +O Yii 2.0 frequentemente junta dados do formulário, rótulos, validação e às +vezes persistência em uma classe `yii\base\Model` ou `yii\db\ActiveRecord`: ```php final class ContactForm extends \yii\base\Model @@ -520,8 +531,8 @@ final class ContactForm extends \yii\base\Model } ``` -Yii3 separates these concerns. Use `yiisoft/form-model` for form data and -metadata, and `yiisoft/validator` for rules: +O Yii3 separa essas responsabilidades. Use `yiisoft/form-model` para os +dados e metadados do formulário, e `yiisoft/validator` para as regras: ```php use Yiisoft\FormModel\FormModel; @@ -539,30 +550,31 @@ final class ContactForm extends FormModel } ``` -For form rendering, replace `yii\widgets\ActiveForm` with `yiisoft/form` -fields and form model integration. For input hydration, prefer the -form-model and hydrator packages instead of mass-assigning arbitrary request -data to persistence objects. +Para a renderização de formulários, substitua `yii\widgets\ActiveForm` pelos +campos do `yiisoft/form` e pela integração com form models. Para a +hidratação da entrada, prefira os pacotes de form model e hydrator em vez de +atribuir em massa dados arbitrários da requisição a objetos de persistência. -See [Working with forms](../start/forms.md), [Validating -input](https://github.com/yiisoft/validator/blob/master/docs/guide/en/README.md), -[yiisoft/form](https://github.com/yiisoft/form), and +Veja [Trabalhando com formulários](../start/forms.md), [Validando a +entrada](https://github.com/yiisoft/validator/blob/master/docs/guide/en/README.md), +[yiisoft/form](https://github.com/yiisoft/form) e [yiisoft/form-model](https://github.com/yiisoft/form-model). -## Active Record and persistence +## Active Record e persistência -There are two common Yii3 choices for code that used Yii 2.0 Active Record -classes. +Existem duas escolhas comuns no Yii3 para código que usava classes Active +Record do Yii 2.0. -The first path is architectural: move business logic to services and domain -objects, then use repositories for persistence. This is recommended when the -Yii 2.0 model contains validation, form scenarios, authorization checks, -mailing, file uploads, and database access in the same class. +O primeiro caminho é arquitetural: mova a lógica de negócio para serviços e +objetos de domínio e use repositórios para a persistência. Ele é recomendado +quando o model do Yii 2.0 contém validação, cenários de formulário, +verificações de autorização, envio de e-mails, upload de arquivos e acesso +ao banco de dados na mesma classe. -The second path is incremental: represent the database model with -[yiisoft/active-record](https://github.com/yiisoft/active-record). This is -closer to Yii 2.0 and can be significantly faster when your Active Record -classes mostly describe tables and relations. +O segundo caminho é incremental: represente o modelo do banco de dados com o +[yiisoft/active-record](https://github.com/yiisoft/active-record). Ele é +mais próximo do Yii 2.0 e pode ser bem mais rápido quando suas classes +Active Record descrevem principalmente tabelas e relações. Yii 2.0: @@ -584,7 +596,7 @@ final class Post extends \yii\db\ActiveRecord } ``` -Yii3 Active Record: +Active Record no Yii3: ```php use Yiisoft\ActiveRecord\ActiveRecord; @@ -617,9 +629,9 @@ final class Post extends ActiveRecord } ``` -Do not move Yii 2.0 `rules()` directly into the Active Record class. In -Yii3, validation belongs to validator rules, form models, command objects, -or services: +Não mova o `rules()` do Yii 2.0 diretamente para a classe Active Record. No +Yii3, a validação pertence a regras do validator, form models, objetos de +comando ou serviços: ```php use Yiisoft\FormModel\FormModel; @@ -637,8 +649,8 @@ final class PostInput extends FormModel } ``` -Then copy validated data into the record or pass it to an application -service: +Depois, copie os dados validados para o registro ou passe-os para um serviço +da aplicação: ```php $post = new Post(); @@ -646,27 +658,30 @@ $post->setTitle($input->title); $post->save(); ``` -When deciding what to reuse, check each Active Record method: +Ao decidir o que reutilizar, verifique cada método do Active Record: -- table mapping and relations can usually move to `yiisoft/active-record`; -- validation should move to `yiisoft/validator`; -- form labels and hints should move to `yiisoft/form-model`; -- search models should become query/data-reader services; -- business workflows should become services; -- events should use PSR-14 events or package-specific events; -- direct `Yii::$app->db` usage should become injected database dependencies. +- o mapeamento de tabelas e as relações geralmente podem ir para o + `yiisoft/active-record`; +- a validação deve ir para o `yiisoft/validator`; +- rótulos e dicas de formulário devem ir para o `yiisoft/form-model`; +- os search models devem virar serviços de consulta/data reader; +- os fluxos de negócio devem virar serviços; +- os eventos devem usar eventos PSR-14 ou eventos específicos de pacotes; +- o uso direto de `Yii::$app->db` deve virar dependências de banco de dados + injetadas. -Yii 2.0 migrations and Yii3 `yiisoft/db-migration` migrations are not -compatible. Start a new migration history or create structure dumps for the -current schema, then use Yii3 migrations for future schema changes. +As migrations do Yii 2.0 e as migrations do `yiisoft/db-migration` do Yii3 +não são compatíveis. Comece um novo histórico de migrations ou crie dumps da +estrutura do esquema atual, e use migrations do Yii3 para as mudanças +futuras no esquema. -See [Working with databases](../start/databases.md), -[Migrations](../databases/db-migrations.md), and +Veja [Trabalhando com banco de dados](../start/databases.md), +[Migrations](../databases/db-migrations.md) e [yiisoft/active-record](https://github.com/yiisoft/active-record). -## GridView and data widgets +## GridView e widgets de dados -Yii 2.0 `GridView` is commonly used with `ActiveDataProvider`: +O `GridView` do Yii 2.0 costuma ser usado com `ActiveDataProvider`: ```php use yii\grid\GridView; @@ -683,9 +698,10 @@ echo GridView::widget([ ]); ``` -Yii3 uses -[yiisoft/yii-dataview](https://github.com/yiisoft/yii-dataview). It renders -data from a data reader and uses fluent widget configuration: +O Yii3 usa o +[yiisoft/yii-dataview](https://github.com/yiisoft/yii-dataview). Ele +renderiza dados a partir de um data reader e usa configuração fluente do +widget: ```php use Yiisoft\Data\Reader\ReadableDataInterface; @@ -707,8 +723,8 @@ echo GridView::widget() ); ``` -For sorting, pagination, filtering, and action URLs, wire the widget to Yii -Router: +Para ordenação, paginação, filtragem e URLs de actions, conecte o widget ao +Yii Router: ```php use Yiisoft\Yii\DataView\YiiRouter\ActionColumnUrlConfig; @@ -730,21 +746,21 @@ echo GridView::widget() ); ``` -A Yii 2.0 search model usually becomes a query service that: +Um search model do Yii 2.0 geralmente vira um serviço de consulta que: -1. reads filter and sort parameters from the request; -2. validates them with `yiisoft/validator`; -3. builds a database query or repository query; -4. exposes a data reader to GridView. +1. lê os parâmetros de filtro e ordenação da requisição; +2. valida esses parâmetros com `yiisoft/validator`; +3. monta uma consulta ao banco de dados ou ao repositório; +4. expõe um data reader para o GridView. -See [Using htmx for partial -reloads](../../cookbook/using-htmx-for-partial-reloads.md) for a complete -Yii3 GridView workflow and [yii-dataview GridView -docs](https://github.com/yiisoft/yii-dataview/blob/master/docs/en/guide/gridview.md). +Veja [Usando htmx para recarregamentos +parciais](../../cookbook/using-htmx-for-partial-reloads.md) para um fluxo +completo de GridView no Yii3 e a [documentação do GridView do +yii-dataview](https://github.com/yiisoft/yii-dataview/blob/master/docs/en/guide/gridview.md). -## Filters, middleware, and access control +## Filtros, middleware e controle de acesso -Yii 2.0 controller filters and behaviors usually look like this: +Os filtros e behaviors de controller do Yii 2.0 geralmente são assim: ```php public function behaviors(): array @@ -760,18 +776,19 @@ public function behaviors(): array } ``` -In Yii3, request processing is middleware-based. Move cross-cutting concerns -such as authentication, authorization, body parsing, locale negotiation, -CSRF checks, and error handling to middleware or dedicated services. Keep -actions focused on the request flow they implement. +No Yii3, o processamento das requisições é baseado em middleware. Mova +responsabilidades transversais, como autenticação, autorização, parsing do +corpo, negociação de idioma, verificação de CSRF e tratamento de erros, para +middlewares ou serviços dedicados. Mantenha as actions focadas no fluxo de +requisição que elas implementam. -See [Middleware](../structure/middleware.md), -[Authentication](../security/authentication.md), and -[Authorization](../security/authorization.md). +Veja [Middleware](../structure/middleware.md), +[Autenticação](../security/authentication.md) e +[Autorização](../security/authorization.md). -## Console commands +## Comandos de console -Yii 2.0 console commands extend `yii\console\Controller`: +Os comandos de console do Yii 2.0 estendem `yii\console\Controller`: ```php final class ReportController extends \yii\console\Controller @@ -784,7 +801,7 @@ final class ReportController extends \yii\console\Controller } ``` -Yii3 console commands are services in `src/Console`: +Os comandos de console do Yii3 são serviços em `src/Console`: ```php namespace App\Console; @@ -805,59 +822,63 @@ final class SendReportCommand extends Command } ``` -Move command dependencies to constructor injection and register commands in -console configuration. +Passe as dependências dos comandos para injeção pelo construtor e registre +os comandos na configuração de console. -See [Console applications](../tutorial/console-applications.md). +Veja [Aplicações de console](../tutorial/console-applications.md). ## APIs REST -Yii 2.0 REST controllers, serializers, and response formatters do not move -directly to Yii3. Start from PSR-7 responses and explicit routing. Build one -resource at a time: +Os controllers REST, serializers e formatadores de resposta do Yii 2.0 não +passam diretamente para o Yii3. Comece pelas respostas PSR-7 e pelo +roteamento explícito. Construa um recurso por vez: -1. define routes for collection and item operations; -2. inject request, persistence, serializer, and response factory - dependencies; -3. validate input with `yiisoft/validator`; -4. return JSON responses through Yii3 response helpers or PSR-7 factories; -5. move authentication and rate limiting to middleware. +1. defina rotas para as operações de coleção e de item; +2. injete as dependências de requisição, persistência, serializer e response + factory; +3. valide a entrada com `yiisoft/validator`; +4. retorne respostas JSON pelos helpers de resposta do Yii3 ou por factories + PSR-7; +5. mova a autenticação e o rate limiting para middlewares. -See [Response](../runtime/response.md), -[Authentication](../security/authentication.md), and -[Authorization](../security/authorization.md). +Veja [Resposta](../runtime/response.md), +[Autenticação](../security/authentication.md) e +[Autorização](../security/authorization.md). ## Testes -Do not postpone tests until the whole Yii3 application is done. For each new -request flow, add: - -- unit tests for services and validators; -- functional tests for actions and middleware; -- end-to-end tests for critical browser flows; -- static analysis for stricter type checks. - -Yii3 code is more explicit, so tests should assert services directly instead -of constructing large application component arrays. - -See [Testing overview](../testing/overview.md), [Unit -tests](../testing/unit.md), [Functional tests](../testing/functional.md), -and [End-to-end tests](../testing/end-to-end.md). - -## Refactoring Yii 2.0 code before reusing it - -These changes are useful even if the old application stays on Yii 2.0 for a -while: - -- Replace `Yii::$app` access in domain code with constructor arguments. -- Move queries out of controllers and views into repositories or query - services. -- Move business workflows out of Active Record classes. -- Separate form models from persistence models. -- Add return types and parameter types. -- Replace route arrays scattered in views with named route constants or - helper methods. -- Add tests around each flow before rebuilding it in Yii3. - -The less framework state your Yii 2.0 code assumes, the easier it is to -understand what should be reused and what should be redesigned for Yii3. +Não deixe os testes para quando a aplicação Yii3 inteira estiver +pronta. Para cada novo fluxo de requisição, adicione: + +- testes unitários para serviços e validadores; +- testes funcionais para actions e middlewares; +- testes end-to-end para os fluxos críticos no navegador; +- análise estática para verificações de tipo mais rigorosas. + +O código Yii3 é mais explícito, então os testes devem verificar os serviços +diretamente, em vez de montar grandes arrays de componentes da aplicação. + +Veja [Visão geral dos testes](../testing/overview.md), [Testes +unitários](../testing/unit.md), [Testes +funcionais](../testing/functional.md) e [Testes +end-to-end](../testing/end-to-end.md). + +## Refatorando o código Yii 2.0 antes de reutilizá-lo + +Estas mudanças são úteis mesmo que a aplicação antiga continue no Yii 2.0 +por um tempo: + +- Substitua o acesso a `Yii::$app` no código de domínio por argumentos do + construtor. +- Tire as consultas dos controllers e views e leve-as para repositórios ou + serviços de consulta. +- Tire os fluxos de negócio das classes Active Record. +- Separe os form models dos models de persistência. +- Adicione tipos de retorno e tipos de parâmetros. +- Substitua arrays de rotas espalhados pelas views por constantes de rotas + nomeadas ou métodos helper. +- Adicione testes em torno de cada fluxo antes de reconstruí-lo no Yii3. + +Quanto menos estado do framework o seu código Yii 2.0 pressupor, mais fácil +fica entender o que deve ser reutilizado e o que deve ser redesenhado para o +Yii3. diff --git a/src/pt-BR/guide/start/databases.md b/src/pt-BR/guide/start/databases.md index 3cd8d3bb..b83a4d5d 100644 --- a/src/pt-BR/guide/start/databases.md +++ b/src/pt-BR/guide/start/databases.md @@ -1,64 +1,66 @@ # Trabalhando com bancos de dados -Yii doesn't dictate using a particular database or storage for your -application. There are many ways you can work with relational databases: +O Yii não impõe um banco de dados ou armazenamento específico para a sua +aplicação. Há muitas formas de trabalhar com bancos de dados relacionais: - [Yii DB](https://github.com/yiisoft/db) - [Yii Active Record](https://github.com/yiisoft/active-record) -- [Cycle](https://github.com/cycle) via [Yii Cycle - package](https://github.com/yiisoft/yii-cycle) -- [Doctrine](https://www.doctrine-project.org/) via [Yii Doctrine - package](https://github.com/stargazer-team/yii-doctrine) +- [Cycle](https://github.com/cycle) pelo [pacote Yii + Cycle](https://github.com/yiisoft/yii-cycle) +- [Doctrine](https://www.doctrine-project.org/) pelo [pacote Yii + Doctrine](https://github.com/stargazer-team/yii-doctrine) - [PDO](https://www.php.net/manual/en/book.pdo.php) -For non-relational ones, there are usually official libraries available: +Para os não relacionais, geralmente existem bibliotecas oficiais: - [ElasticSearch](https://github.com/elastic/elasticsearch-php) - [Redis](https://redis.io/docs/latest/develop/clients/php/) - ... -## Choosing a data access approach +## Escolhendo uma forma de acesso aos dados -Yii3 keeps database access in optional packages. A new application doesn't get a global `Yii::$app->db` component -or a built-in Active Record layer automatically, so choose the package and boundary that fit your application. +O Yii3 deixa o acesso ao banco de dados em pacotes opcionais. Uma aplicação nova não ganha automaticamente um componente global `Yii::$app->db` +nem uma camada de Active Record embutida, então escolha o pacote e a fronteira que fazem sentido para a sua aplicação. -If you used Yii 2.0 database access layer, `yiisoft/db` is the closest Yii3 equivalent. It provides database -connections, commands, schema support, and a query builder. Instead of calling `Yii::$app->db`, configure a -connection as a service and inject `ConnectionInterface` where the database is needed. +Se você usava a camada de acesso ao banco de dados do Yii 2.0, o `yiisoft/db` é o equivalente mais próximo no Yii3. Ele oferece +conexões, comandos, suporte a esquema e um query builder. Em vez de chamar `Yii::$app->db`, configure uma +conexão como serviço e injete `ConnectionInterface` onde o banco de dados for necessário. -If you used Yii 2.0 Active Record, you can install -`yiisoft/active-record`. It is useful when your model classes mostly -describe tables and relations. For applications where Yii 2.0 Active Record -classes also contain form validation, request scenarios, authorization -checks, or business workflows, move those responsibilities to form models, -services, and domain objects instead of putting them back into the record -class. +Se você usava o Active Record do Yii 2.0, pode instalar o +`yiisoft/active-record`. Ele é útil quando suas classes de model descrevem +principalmente tabelas e relações. Em aplicações em que as classes Active +Record do Yii 2.0 também contêm validação de formulário, cenários de +requisição, verificações de autorização ou fluxos de negócio, mova essas +responsabilidades para form models, serviços e objetos de domínio em vez de +colocá-las de volta na classe do registro. -For most application code, put a repository or query service between the -action/service layer and storage: +Na maior parte do código da aplicação, coloque um repositório ou serviço de +consulta entre a camada de actions/serviços e o armazenamento: -- actions and application services depend on repository methods such as - `findOneBySlug()`, `findAll()`, `save()`, and `deleteBySlug()`; -- the repository hides whether persistence is implemented with `yiisoft/db`, - Active Record, Cycle, Doctrine, or another storage; -- the repository is the place to map raw database rows or records to typed - objects used by the rest of the code. +- actions e serviços da aplicação dependem de métodos do repositório como + `findOneBySlug()`, `findAll()`, `save()` e `deleteBySlug()`; +- o repositório esconde se a persistência é feita com `yiisoft/db`, Active + Record, Cycle, Doctrine ou outro armazenamento; +- o repositório é o lugar para converter as linhas brutas do banco de dados + ou os registros em objetos tipados usados pelo resto do código. -Small CRUD applications can start with a concrete repository class. Larger -applications usually benefit from a repository interface in the domain or -module and an implementation in the infrastructure layer. +Aplicações CRUD pequenas podem começar com uma classe de repositório +concreta. Aplicações maiores costumam se beneficiar de uma interface de +repositório no domínio ou módulo e de uma implementação na camada de +infraestrutura. -In this guide, we will focus on working with relational databases using Yii -DB. We'll use PostgreSQL to implement a simple CRUD (create read update -delete). +Neste guia, vamos focar no trabalho com bancos de dados relacionais usando o +Yii DB. Vamos usar PostgreSQL para implementar um CRUD simples (create, +read, update, delete: criar, ler, atualizar e excluir). -## Installing PostgreSQL +## Instalando o PostgreSQL -You need to install PostgreSQL. If you prefer not to use Docker, [get the -installer from official website](https://www.postgresql.org/download/), -install it and create a database. +Você precisa instalar o PostgreSQL. Se preferir não usar Docker, [baixe o +instalador no site oficial](https://www.postgresql.org/download/), instale e +crie um banco de dados. -If you use Docker, it is a bit simpler. Modify `docker/dev/compose.yml`: +Se você usa Docker, é um pouco mais simples. Altere +`docker/dev/compose.yml`: ```yaml services: @@ -104,13 +106,14 @@ services: retries: 5 ``` -Note that we add `depends_on` so application waits for database to be up. +Repare que adicionamos `depends_on` para que a aplicação espere o banco de +dados subir. > [!IMPORTANT] -> Also, we'll need a `pdo_pgsql` extension to communicate with PostgreSQL. You can enable it locally in `php.ini`. +> Também vamos precisar da extensão `pdo_pgsql` para falar com o PostgreSQL. Você pode habilitá-la localmente no `php.ini`. -If you use Docker, check `docker/Dockerfile` and add `pdo_pgsql` in -`install-php-extensions` list: +Se você usa Docker, abra `docker/Dockerfile` e adicione `pdo_pgsql` à lista +do `install-php-extensions`: ```dockerfile RUN install-php-extensions \ @@ -129,23 +132,23 @@ RUN install-php-extensions \ pdo_pgsql ``` -Then rebuild PHP image with +Depois, reconstrua a imagem do PHP com ```sh make build && make down && make up ``` -## Configuring connection +## Configurando a conexão -Now that we have the database, it's time to define the connection. +Agora que temos o banco de dados, é hora de definir a conexão. -First we need a package to be installed: +Primeiro, precisamos instalar um pacote: ```sh make composer require yiisoft/db-pgsql:2.* ``` -Now create `config/common/di/db-pgsql.php`: +Agora crie `config/common/di/db-pgsql.php`: ```php [ @@ -308,8 +311,9 @@ root. Add the following configuration to `config/common/params.php`: ], ``` -Now you can use `make yii migrate:create page` to create a new -migration. For our example we need a `page` table with some columns: +Agora você pode usar `make yii migrate:create page` para criar uma nova +migration. No nosso exemplo, precisamos de uma tabela `page` com algumas +colunas: ```php generate('page/edit', ['slug' => 'new'])) ?> ``` -### View a page +### Ver uma página -Create `src/Web/Page/ViewAction.php`: +Crie `src/Web/Page/ViewAction.php`: ```php close() ?> ``` -In this view we have a form that submits a request for page -deletion. Handing it with `GET` is common as well, but it is very -wrong. Since deletion changes data, it needs to be handled by one of the -non-idempotent HTTP methods. We use POST and a form in our example, but it -could be `DELETE` and async request made with JavaScript. The button could -be later styled properly to look similar to the "Edit". +Nesta view há um formulário que envia uma requisição para excluir a +página. Tratar isso com `GET` também é comum, mas é muito errado. Como a +exclusão altera dados, ela precisa ser tratada por um dos métodos HTTP não +idempotentes. No nosso exemplo usamos POST e um formulário, mas poderia ser +`DELETE` e uma requisição assíncrona feita com JavaScript. Depois, o botão +pode ganhar um estilo adequado para ficar parecido com o "Edit". -### Delete a page +### Excluir uma página -Create `src/Web/Page/DeleteAction.php`: +Crie `src/Web/Page/DeleteAction.php`: ```php toString()` won't work for MySQL and you'll need bytes instead, `Uuid::uuid7()->getBytes()`. +Repare que `Uuid::uuid7()->toString()` não funciona no MySQL; lá você vai precisar dos bytes, com `Uuid::uuid7()->getBytes()`. -In the above we use a special slug in the URL for new pages so the URL looks -like `http://localhost/pages/new`. If the page isn't new, we pre-fill the -form with the data from the database. Similar to how we did in [Working with -forms](forms.md), we handle the form submission. After successful save we -redirect to the page view. +Acima, usamos um slug especial na URL para páginas novas, então a URL fica +como `http://localhost/pages/new`. Se a página não for nova, preenchemos o +formulário com os dados do banco de dados. Assim como fizemos em +[Trabalhando com formulários](forms.md), tratamos o envio do +formulário. Depois de salvar com sucesso, redirecionamos para a view da +página. -Now, a template in `src/Web/Page/edit.php`: +Agora, um template em `src/Web/Page/edit.php`: ```php Date: Fri, 23 Oct 2026 14:18:13 -0300 Subject: [PATCH 04/11] Translate guide key concepts and application structure to Brazilian Portuguese --- .../po/pt-BR/guide_concept_aliases.md.po | 124 +++-- .../po/pt-BR/guide_concept_autoloading.md.po | 34 +- .../pt-BR/guide_concept_configuration.md.po | 389 ++++++++++++---- .../po/pt-BR/guide_concept_di-container.md.po | 261 ++++++++--- .../po/pt-BR/guide_concept_events.md.po | 153 ++++-- .../po/pt-BR/guide_concept_immutability.md.po | 143 +++++- .../po/pt-BR/guide_structure_action.md.po | 99 +++- .../pt-BR/guide_structure_application.md.po | 16 +- .../guide_structure_designing-packages.md.po | 437 ++++++++++++++---- .../pt-BR/guide_structure_entry-script.md.po | 111 ++++- .../po/pt-BR/guide_structure_middleware.md.po | 151 ++++-- .../po/pt-BR/guide_structure_module.md.po | 231 ++++++--- .../po/pt-BR/guide_structure_overview.md.po | 71 +-- .../po/pt-BR/guide_structure_package.md.po | 94 ++-- src/pt-BR/guide/concept/aliases.md | 103 ++--- src/pt-BR/guide/concept/autoloading.md | 42 +- src/pt-BR/guide/concept/configuration.md | 311 +++++++------ src/pt-BR/guide/concept/di-container.md | 219 ++++----- src/pt-BR/guide/concept/events.md | 132 +++--- src/pt-BR/guide/concept/immutability.md | 83 ++-- src/pt-BR/guide/structure/action.md | 62 +-- src/pt-BR/guide/structure/application.md | 31 +- .../guide/structure/designing-packages.md | 291 ++++++------ src/pt-BR/guide/structure/entry-script.md | 73 +-- src/pt-BR/guide/structure/middleware.md | 103 +++-- src/pt-BR/guide/structure/module.md | 189 ++++---- src/pt-BR/guide/structure/overview.md | 88 ++-- src/pt-BR/guide/structure/package.md | 111 ++--- 28 files changed, 2712 insertions(+), 1440 deletions(-) diff --git a/_translations/po/pt-BR/guide_concept_aliases.md.po b/_translations/po/pt-BR/guide_concept_aliases.md.po index 22f6e2cc..e01f360d 100644 --- a/_translations/po/pt-BR/guide_concept_aliases.md.po +++ b/_translations/po/pt-BR/guide_concept_aliases.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-06-05 20:33+0000\n" "PO-Revision-Date: 2026-06-05 20:33+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,28 +19,28 @@ msgstr "" #: ../src/guide/concept/aliases.md #, no-wrap msgid "Aliases" -msgstr "" +msgstr "Aliases" #. type: Plain text #: ../src/guide/concept/aliases.md msgid "You can use aliases to represent file paths or URLs so that you don't have to hard-code absolute paths or URLs in your project. An alias must start with the `@` character to be differentiated from normal file paths and URLs. Alias defined without leading `@` will be prefixed with `@` character." -msgstr "" +msgstr "Você pode usar aliases para representar caminhos de arquivos ou URLs, evitando escrever caminhos absolutos ou URLs fixos no seu projeto. Um alias deve começar com o caractere `@` para se diferenciar de caminhos de arquivos e URLs normais. Um alias definido sem o `@` inicial receberá o prefixo `@`." #. type: Plain text #: ../src/guide/concept/aliases.md msgid "Default Yii application has some aliases pre-defined in `config/params.php`. For example, the alias `@public` represents the web root path; `@baseUrl` represents the base URL for the currently running Web application." -msgstr "" +msgstr "A aplicação Yii padrão tem alguns aliases predefinidos em `config/params.php`. Por exemplo, o alias `@public` representa o caminho da raiz web; `@baseUrl` representa a URL base da aplicação web em execução." #. type: Title ## #: ../src/guide/concept/aliases.md #, no-wrap msgid "Defining aliases" -msgstr "" +msgstr "Definindo aliases" #. type: Plain text #: ../src/guide/concept/aliases.md msgid "You can define an alias via application's `config/params.php`:" -msgstr "" +msgstr "Você pode definir um alias no `config/params.php` da aplicação:" #. type: Fenced code block (php) #: ../src/guide/concept/aliases.md @@ -65,6 +65,24 @@ msgid "" " ],\n" "];\n" msgstr "" +"return [\n" +" // ...\n" +" \n" +" 'yiisoft/aliases' => [\n" +" 'aliases' => [\n" +" // ...\n" +" \n" +" // um alias de um caminho de arquivo\n" +" '@foo' => '/path/to/foo',\n" +" \n" +" // um alias de uma URL\n" +" '@bar' => 'https://www.example.com',\n" +" \n" +" // um alias de um arquivo concreto que contém a classe \\foo\\Bar \n" +" '@foo/Bar.php' => '/definitely/not/foo/Bar.php',\n" +" ],\n" +" ],\n" +"];\n" #. type: Plain text #: ../src/guide/concept/aliases.md @@ -73,27 +91,29 @@ msgid "" "> [!NOTE]\n" "> The file path or URL being aliased may *not* necessarily refer to an existing file or resource.\n" msgstr "" +"> [!NOTE]\n" +"> O caminho de arquivo ou URL representado pelo alias *não* precisa necessariamente se referir a um arquivo ou recurso existente.\n" #. type: Plain text #: ../src/guide/concept/aliases.md msgid "Given a defined alias, you may derive a new alias by appending a slash `/` followed with one or more path segments. For example, `@foo` is a root alias, while `@foo/bar/file.php` is a derived alias." -msgstr "" +msgstr "A partir de um alias definido, você pode derivar um novo alias acrescentando uma barra `/` seguida de um ou mais segmentos de caminho. Por exemplo, `@foo` é um alias raiz, enquanto `@foo/bar/file.php` é um alias derivado." #. type: Plain text #: ../src/guide/concept/aliases.md msgid "You can define an alias using another alias (either root or derived):" -msgstr "" +msgstr "Você pode definir um alias usando outro alias (raiz ou derivado):" #. type: Fenced code block (php) #: ../src/guide/concept/aliases.md #, no-wrap msgid "'@foobar' => '@foo/bar', \n" -msgstr "" +msgstr "'@foobar' => '@foo/bar', \n" #. type: Plain text #: ../src/guide/concept/aliases.md msgid "The `yiisoft/aliases` parameter initializes `Aliases` service from [`yiisoft/aliases`](https://github.com/yiisoft/aliases) package. You can set extra aliases in runtime by using the service:" -msgstr "" +msgstr "O parâmetro `yiisoft/aliases` inicializa o serviço `Aliases` do pacote [`yiisoft/aliases`](https://github.com/yiisoft/aliases). Você pode definir aliases extras em tempo de execução usando o serviço:" #. type: Fenced code block (php) #: ../src/guide/concept/aliases.md @@ -106,17 +126,23 @@ msgid "" " $aliases->set('@uploads', '@root/uploads');\n" "}\n" msgstr "" +"use \\Yiisoft\\Aliases\\Aliases;\n" +"\n" +"public function actionIndex(Aliases $aliases)\n" +"{\n" +" $aliases->set('@uploads', '@root/uploads');\n" +"}\n" #. type: Title ## #: ../src/guide/concept/aliases.md #, no-wrap msgid "Using aliases in configuration" -msgstr "" +msgstr "Usando aliases na configuração" #. type: Plain text #: ../src/guide/concept/aliases.md msgid "It's preferred to resolve aliases at the configuration level, so services get URLs and paths as ready to use strings:" -msgstr "" +msgstr "É preferível resolver os aliases no nível da configuração, para que os serviços recebam URLs e caminhos como strings prontas para uso:" #. type: Fenced code block (php) #: ../src/guide/concept/aliases.md @@ -137,17 +163,31 @@ msgid "" " ),\n" "];\n" msgstr "" +" static fn (Aliases $aliases) => new FileCache(\n" +" $aliases->get($params['yiisoft/cache-file']['fileCache']['path'])\n" +" ),\n" +"];\n" #. type: Title ## #: ../src/guide/concept/aliases.md #, no-wrap msgid "Resolving aliases" -msgstr "" +msgstr "Resolvendo aliases" #. type: Plain text #: ../src/guide/concept/aliases.md msgid "You can use `Aliases` service to resolve an alias or derived alias into the file path or URL it represents:" -msgstr "" +msgstr "Você pode usar o serviço `Aliases` para resolver um alias ou alias derivado no caminho de arquivo ou URL que ele representa:" #. type: Fenced code block (php) #: ../src/guide/concept/aliases.md @@ -162,11 +202,19 @@ msgid "" " $file = $aliases->get('@foo/bar/file.php'); // /path/to/foo/bar/file.php\n" "}\n" msgstr "" +"use \\Yiisoft\\Aliases\\Aliases;\n" +"\n" +"public function actionIndex(Aliases $aliases)\n" +"{\n" +" $foo = $aliases->get('@foo'); // /path/to/foo\n" +" $bar = $aliases->get('@bar'); // https://www.example.com\n" +" $file = $aliases->get('@foo/bar/file.php'); // /path/to/foo/bar/file.php\n" +"}\n" #. type: Plain text #: ../src/guide/concept/aliases.md msgid "The path/URL represented by a derived alias is determined by replacing the root alias part with its corresponding path/URL in the derived alias." -msgstr "" +msgstr "O caminho/URL representado por um alias derivado é determinado substituindo a parte do alias raiz pelo caminho/URL correspondente." #. type: Plain text #: ../src/guide/concept/aliases.md @@ -175,11 +223,13 @@ msgid "" "> [!NOTE]\n" "> The `get()` method doesn't check whether the resulting path/URL refers to an existing file or resource.\n" msgstr "" +"> [!NOTE]\n" +"> O método `get()` não verifica se o caminho/URL resultante se refere a um arquivo ou recurso existente.\n" #. type: Plain text #: ../src/guide/concept/aliases.md msgid "A root alias may also contain slash `/` characters. The `get()` method is intelligent enough to tell, which part of an alias is a root alias and thus correctly determines the corresponding file path or URL:" -msgstr "" +msgstr "Um alias raiz também pode conter caracteres de barra `/`. O método `get()` é inteligente o suficiente para identificar qual parte de um alias é o alias raiz e, assim, determina corretamente o caminho de arquivo ou URL correspondente:" #. type: Fenced code block (php) #: ../src/guide/concept/aliases.md @@ -196,79 +246,89 @@ msgid "" " $aliases->get('@foo/bar/file.php'); // /path2/bar/file.php\n" "} \n" msgstr "" +"use \\Yiisoft\\Aliases\\Aliases;\n" +"\n" +"public function actionIndex(Aliases $aliases)\n" +"{\n" +" $aliases->set('@foo', '/path/to/foo');\n" +" $aliases->set('@foo/bar', '/path2/bar');\n" +"\n" +" $aliases->get('@foo/test/file.php'); // /path/to/foo/test/file.php\n" +" $aliases->get('@foo/bar/file.php'); // /path2/bar/file.php\n" +"} \n" #. type: Plain text #: ../src/guide/concept/aliases.md msgid "If `@foo/bar` isn't defined as a root alias, the last statement would display `/path/to/foo/bar/file.php`." -msgstr "" +msgstr "Se `@foo/bar` não estiver definido como alias raiz, a última instrução exibiria `/path/to/foo/bar/file.php`." #. type: Title ## #: ../src/guide/concept/aliases.md #, no-wrap msgid "Predefined aliases" -msgstr "" +msgstr "Aliases predefinidos" #. type: Plain text #: ../src/guide/concept/aliases.md msgid "[Yii application](https://github.com/yiisoft/app) predefines a set of aliases to reference commonly used file paths and URLs:" -msgstr "" +msgstr "A [aplicação Yii](https://github.com/yiisoft/app) predefine um conjunto de aliases para referenciar caminhos de arquivos e URLs de uso comum:" #. type: Bullet: '- ' #: ../src/guide/concept/aliases.md msgid "`@root` - the base directory of the currently running application." -msgstr "" +msgstr "`@root` - a pasta base da aplicação em execução." #. type: Bullet: '- ' #: ../src/guide/concept/aliases.md msgid "`@assets` - application's public directory where it publishes assets." -msgstr "" +msgstr "`@assets` - pasta pública da aplicação onde ela publica os assets." #. type: Bullet: '- ' #: ../src/guide/concept/aliases.md msgid "`@assetsUrl` - URL of base directory with published assets." -msgstr "" +msgstr "`@assetsUrl` - URL da pasta base com os assets publicados." #. type: Bullet: '- ' #: ../src/guide/concept/aliases.md msgid "`@baseUrl` - the base URL of the currently running Web application. Defaults to `/`." -msgstr "" +msgstr "`@baseUrl` - a URL base da aplicação web em execução. O padrão é `/`." #. type: Bullet: '- ' #: ../src/guide/concept/aliases.md msgid "`@npm` - node packages directory." -msgstr "" +msgstr "`@npm` - pasta de pacotes node." #. type: Bullet: '- ' #: ../src/guide/concept/aliases.md msgid "`@bower` - bower packages directory." -msgstr "" +msgstr "`@bower` - pasta de pacotes bower." #. type: Bullet: '- ' #: ../src/guide/concept/aliases.md msgid "`@vendor` - Composer's `vendor` directory." -msgstr "" +msgstr "`@vendor` - a pasta `vendor` do Composer." #. type: Bullet: '- ' #: ../src/guide/concept/aliases.md msgid "`@public` - application's publicly accessible directory that with `index.php`." -msgstr "" +msgstr "`@public` - pasta publicamente acessível da aplicação, que contém o `index.php`." #. type: Bullet: '- ' #: ../src/guide/concept/aliases.md msgid "`@runtime` - the runtime path of the currently running application. Defaults to `@root/runtime`." -msgstr "" +msgstr "`@runtime` - o caminho de runtime da aplicação em execução. O padrão é `@root/runtime`." #. type: Bullet: '- ' #: ../src/guide/concept/aliases.md msgid "`@layout` - the directory with layouts." -msgstr "" +msgstr "`@layout` - a pasta com os layouts." #. type: Bullet: '- ' #: ../src/guide/concept/aliases.md msgid "`@resources` - directory with views, asset sources and other resources." -msgstr "" +msgstr "`@resources` - pasta com views, fontes de assets e outros recursos." #. type: Bullet: '- ' #: ../src/guide/concept/aliases.md msgid "`@views` - application view templates base directory." -msgstr "" +msgstr "`@views` - pasta base dos templates de view da aplicação." diff --git a/_translations/po/pt-BR/guide_concept_autoloading.md.po b/_translations/po/pt-BR/guide_concept_autoloading.md.po index 99319baf..08a34a37 100644 --- a/_translations/po/pt-BR/guide_concept_autoloading.md.po +++ b/_translations/po/pt-BR/guide_concept_autoloading.md.po @@ -8,39 +8,34 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-01-08 08:54+0000\n" "PO-Revision-Date: 2026-01-08 08:54+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md -#: ../src/guide/concept/autoloading.md ../src/guide/security/best-practices.md -#: ../src/guide/structure/domain.md -#: ../src/guide/tutorial/console-applications.md -#: ../src/internals/004-namespaces.md ../src/internals/007-exceptions.md -#: ../src/internals/008-interfaces.md +#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md ../src/guide/concept/autoloading.md ../src/guide/security/best-practices.md ../src/guide/structure/domain.md ../src/guide/tutorial/console-applications.md ../src/internals/004-namespaces.md ../src/internals/007-exceptions.md ../src/internals/008-interfaces.md #, no-wrap msgid "References" -msgstr "" +msgstr "Referências" #. type: Title # #: ../src/guide/concept/autoloading.md #, no-wrap msgid "Class autoloading" -msgstr "" +msgstr "Autoload de classes" #. type: Plain text #: ../src/guide/concept/autoloading.md msgid "Since Yii uses [Composer](https://getcomposer.org) to manage packages, it automatically loads classes from these packages without the need to `require` their file explicitly. When it installs packages, it generates a [PSR-4 compatible autoloader](https://www.php-fig.org/psr/psr-4/). To use it, `require_once` autoloader `/vendor/autoload.php` in your `index.php` entry point file." -msgstr "" +msgstr "Como o Yii usa o [Composer](https://getcomposer.org) para gerenciar pacotes, ele carrega automaticamente as classes desses pacotes sem a necessidade de fazer `require` dos arquivos explicitamente. Ao instalar pacotes, o Composer gera um [autoloader compatível com PSR-4](https://www.php-fig.org/psr/psr-4/). Para usá-lo, faça `require_once` do autoloader `/vendor/autoload.php` no seu arquivo de ponto de entrada `index.php`." #. type: Plain text #: ../src/guide/concept/autoloading.md msgid "You can use autoloader not only for the packages installed, but for your application as well since it's also a package. To load classes of a certain namespace, add the following to `composer.json`:" -msgstr "" +msgstr "Você pode usar o autoloader não só para os pacotes instalados, mas também para a sua aplicação, já que ela também é um pacote. Para carregar classes de um determinado namespace, adicione o seguinte ao `composer.json`:" #. type: Fenced code block (json) #: ../src/guide/concept/autoloading.md @@ -54,23 +49,30 @@ msgid "" " }\n" "}\n" msgstr "" +"{\n" +" \"autoload\": {\n" +" \"psr-4\": {\n" +" \"App\\\\\": \"src/\"\n" +" }\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/concept/autoloading.md msgid "Where `App\\\\` is a root namespace and `src/` is a directory where you have your classes. You can add more source roots if needed. When done, execute `composer dump-autoload` or simply `composer du` and classes from the corresponding namespaces will start loading automatically." -msgstr "" +msgstr "Onde `App\\\\` é o namespace raiz e `src/` é a pasta onde ficam suas classes. Você pode adicionar mais raízes de código-fonte se precisar. Depois, execute `composer dump-autoload` ou simplesmente `composer du`, e as classes dos namespaces correspondentes passarão a ser carregadas automaticamente." #. type: Plain text #: ../src/guide/concept/autoloading.md msgid "If you need development-environment-specific autoloading that isn't used when executing Composer with `--no-dev` flag, add it to `autoload-dev` section instead of `autoload`." -msgstr "" +msgstr "Se você precisar de autoload específico do ambiente de desenvolvimento, que não seja usado ao executar o Composer com a flag `--no-dev`, adicione-o à seção `autoload-dev` em vez de `autoload`." #. type: Bullet: '- ' #: ../src/guide/concept/autoloading.md msgid "[PSR-4: Autoloader](https://www.php-fig.org/psr/psr-4/)." -msgstr "" +msgstr "[PSR-4: Autoloader](https://www.php-fig.org/psr/psr-4/)." #. type: Bullet: '- ' #: ../src/guide/concept/autoloading.md msgid "[Composer guide on autoloading](https://getcomposer.org/doc/01-basic-usage.md#autoloading)." -msgstr "" +msgstr "[Guia do Composer sobre autoload](https://getcomposer.org/doc/01-basic-usage.md#autoloading)." diff --git a/_translations/po/pt-BR/guide_concept_configuration.md.po b/_translations/po/pt-BR/guide_concept_configuration.md.po index ca7f7eab..acd4c330 100644 --- a/_translations/po/pt-BR/guide_concept_configuration.md.po +++ b/_translations/po/pt-BR/guide_concept_configuration.md.po @@ -8,47 +8,44 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-05-29 19:04+0000\n" "PO-Revision-Date: 2026-05-29 19:04+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/cookbook/sentry-integration.md ../src/guide/concept/configuration.md -#: ../src/guide/tutorial/using-yii-with-frankenphp.md -#: ../src/guide/tutorial/using-yii-with-roadrunner.md -#: ../src/guide/views/view-injections.md +#: ../src/cookbook/sentry-integration.md ../src/guide/concept/configuration.md ../src/guide/tutorial/using-yii-with-frankenphp.md ../src/guide/tutorial/using-yii-with-roadrunner.md ../src/guide/views/view-injections.md #, no-wrap msgid "Configuration" -msgstr "" +msgstr "Configuração" #. type: Plain text #: ../src/guide/concept/configuration.md msgid "There are many ways to configure your application. We will focus on concepts used in the [default project template](https://github.com/yiisoft/app)." -msgstr "" +msgstr "Há muitas formas de configurar a sua aplicação. Aqui o foco são os conceitos usados no [template de projeto padrão](https://github.com/yiisoft/app)." #. type: Plain text #: ../src/guide/concept/configuration.md msgid "Yii3 configs are part of the application. You can change many aspects of how the application works by editing configuration under `config/` directory." -msgstr "" +msgstr "As configurações do Yii3 fazem parte da aplicação. Você pode mudar muitos aspectos do funcionamento da aplicação editando a configuração na pasta `config/`." #. type: Title ## #: ../src/guide/concept/configuration.md #, no-wrap msgid "Config plugin" -msgstr "" +msgstr "Plugin de configuração" #. type: Plain text #: ../src/guide/concept/configuration.md msgid "The application template uses [yiisoft/config](https://github.com/yiisoft/config) as a composer plugin to assemble configs." -msgstr "" +msgstr "O template de aplicação usa o [yiisoft/config](https://github.com/yiisoft/config) como plugin do Composer para montar as configurações." #. type: Plain text #: ../src/guide/concept/configuration.md msgid "Packages provide default configurations through defined [config groups](https://github.com/yiisoft/config#config-groups) in the `config-plugin` key in the `extra` section of the `composer.json`:" -msgstr "" +msgstr "Os pacotes fornecem configurações padrão por meio de [grupos de configuração](https://github.com/yiisoft/config#config-groups) definidos na chave `config-plugin` da seção `extra` do `composer.json`:" #. type: Fenced code block (json) #: ../src/guide/concept/configuration.md @@ -64,31 +61,40 @@ msgid "" " }\n" "}\n" msgstr "" +"\"extra\": {\n" +" \"config-plugin-options\": {\n" +" \"source-directory\": \"config\",\n" +" },\n" +" \"config-plugin\": {\n" +" \"params\": \"params.php\",\n" +" \"web\": \"web.php\"\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/concept/configuration.md msgid "After Composer updates autoload files, such as during `dump-autoload`, `install`, `require`, `update`, or `remove`, the plugin scans installed packages for configurations and writes a merge plan to `config/.merge-plan.php`. The merge plan declares the order of merging found configurations into the final configuration to be passed to [DI container](di-container.md)." -msgstr "" +msgstr "Depois que o Composer atualiza os arquivos de autoload, como durante `dump-autoload`, `install`, `require`, `update` ou `remove`, o plugin procura configurações nos pacotes instalados e grava um merge plan em `config/.merge-plan.php`. O merge plan declara a ordem em que as configurações encontradas são mescladas na configuração final, que é passada ao [container de DI](di-container.md)." #. type: Plain text #: ../src/guide/concept/configuration.md msgid "At runtime, `Yiisoft\\Config\\Config` loads the defined config groups according to that merge plan. Configs are read in three layers:" -msgstr "" +msgstr "Em tempo de execução, `Yiisoft\\Config\\Config` carrega os grupos de configuração definidos de acordo com esse merge plan. As configurações são lidas em três camadas:" #. type: Bullet: '1. ' #: ../src/guide/concept/configuration.md msgid "Vendor package configs with default values." -msgstr "" +msgstr "Configurações dos pacotes em vendor, com os valores padrão." #. type: Bullet: '2. ' #: ../src/guide/concept/configuration.md msgid "Root package configs from the application `config/` directory." -msgstr "" +msgstr "Configurações do pacote raiz, da pasta `config/` da aplicação." #. type: Bullet: '3. ' #: ../src/guide/concept/configuration.md msgid "Environment-specific configs from the application." -msgstr "" +msgstr "Configurações da aplicação específicas de cada ambiente." #. type: Plain text #: ../src/guide/concept/configuration.md @@ -97,11 +103,13 @@ msgid "" "> [!WARNING]\n" "> Config keys with the same name are not allowed within a single layer.\n" msgstr "" +"> [!WARNING]\n" +"> Chaves de configuração com o mesmo nome não são permitidas dentro de uma mesma camada.\n" #. type: Plain text #: ../src/guide/concept/configuration.md msgid "The application template stores configurations in a PHP file instead of inline JSON:" -msgstr "" +msgstr "O template de aplicação guarda as configurações em um arquivo PHP em vez de JSON inline:" #. type: Fenced code block (json) #: ../src/guide/concept/configuration.md @@ -111,11 +119,14 @@ msgid "" " \"config-plugin-file\": \"config/configuration.php\"\n" "}\n" msgstr "" +"\"extra\": {\n" +" \"config-plugin-file\": \"config/configuration.php\"\n" +"}\n" #. type: Plain text #: ../src/guide/concept/configuration.md msgid "That file returns the same keys you could otherwise define in `composer.json`: `config-plugin`, `config-plugin-options`, and `config-plugin-environments`." -msgstr "" +msgstr "Esse arquivo retorna as mesmas chaves que você poderia definir no `composer.json`: `config-plugin`, `config-plugin-options` e `config-plugin-environments`." #. type: Fenced code block (php) #: ../src/guide/concept/configuration.md @@ -176,57 +187,111 @@ msgid "" " ],\n" "];\n" msgstr "" +"use App\\Environment;\n" +"\n" +"return [\n" +" 'config-plugin-options' => [\n" +" 'source-directory' => 'config',\n" +" ],\n" +" 'config-plugin' => [\n" +" 'params' => 'common/params.php',\n" +" 'params-web' => [\n" +" '$params',\n" +" 'web/params.php',\n" +" ],\n" +" 'params-console' => [\n" +" '$params',\n" +" 'console/params.php',\n" +" ],\n" +" 'bootstrap' => 'common/bootstrap.php',\n" +" 'bootstrap-web' => '$bootstrap',\n" +" 'bootstrap-console' => '$bootstrap',\n" +" 'di' => 'common/di/*.php',\n" +" 'di-web' => [\n" +" '$di',\n" +" 'web/di/*.php',\n" +" ],\n" +" 'di-console' => '$di',\n" +" 'di-delegates' => [],\n" +" 'di-delegates-console' => '$di-delegates',\n" +" 'di-delegates-web' => '$di-delegates',\n" +" 'di-providers' => [],\n" +" 'di-providers-web' => '$di-providers',\n" +" 'di-providers-console' => '$di-providers',\n" +" 'events' => [],\n" +" 'events-web' => '$events',\n" +" 'events-console' => '$events',\n" +" 'routes' => 'common/routes.php',\n" +" ],\n" +" 'config-plugin-environments' => [\n" +" Environment::DEV => [\n" +" 'params' => [\n" +" 'environments/dev/params.php',\n" +" ],\n" +" ],\n" +" Environment::TEST => [\n" +" 'params' => [\n" +" 'environments/test/params.php',\n" +" ],\n" +" ],\n" +" Environment::PROD => [\n" +" 'params' => [\n" +" 'environments/prod/params.php',\n" +" ],\n" +" ],\n" +" ],\n" +"];\n" #. type: Plain text #: ../src/guide/concept/configuration.md msgid "Config group names are mapping keys. Their values are file paths relative to the `source-directory` option, which defaults to the directory containing `composer.json`." -msgstr "" +msgstr "Os nomes dos grupos de configuração são as chaves do mapeamento. Os valores são caminhos de arquivos relativos à opção `source-directory`, cujo padrão é a pasta que contém o `composer.json`." #. type: Bullet: '- ' #: ../src/guide/concept/configuration.md msgid "A string value loads one file." -msgstr "" +msgstr "Um valor string carrega um arquivo." #. type: Bullet: '- ' #: ../src/guide/concept/configuration.md msgid "An array loads and merges multiple files in the given order." -msgstr "" +msgstr "Um array carrega e mescla vários arquivos na ordem indicada." #. type: Bullet: '- ' #: ../src/guide/concept/configuration.md msgid "`?` marks an optional file." -msgstr "" +msgstr "`?` marca um arquivo opcional." #. type: Bullet: '- ' #: ../src/guide/concept/configuration.md msgid "`*` marks a wildcard path." -msgstr "" +msgstr "`*` marca um caminho com curinga." #. type: Bullet: '- ' #: ../src/guide/concept/configuration.md msgid "`$group` references another config group to be merged." -msgstr "" +msgstr "`$group` referencia outro grupo de configuração a ser mesclado." #. type: Plain text #: ../src/guide/concept/configuration.md msgid "The `params` group is special: its values are available as `$params` in other config files by default." -msgstr "" +msgstr "O grupo `params` é especial: por padrão, os valores dele ficam disponíveis como `$params` nos outros arquivos de configuração." #. type: Plain text #: ../src/guide/concept/configuration.md msgid "You can read more in the [yiisoft/config documentation](https://github.com/yiisoft/config/blob/master/README.md)." -msgstr "" +msgstr "Leia mais na [documentação do yiisoft/config](https://github.com/yiisoft/config/blob/master/README.md)." #. type: Title ## #: ../src/guide/concept/configuration.md #, no-wrap msgid "Config files" -msgstr "" +msgstr "Arquivos de configuração" #. type: Plain text #: ../src/guide/concept/configuration.md msgid "Now, as you know how the plugin assembles configs, look at the `config/` directory structure used by the default application template:" -msgstr "" +msgstr "Agora que você sabe como o plugin monta as configurações, veja a estrutura da pasta `config/` usada pelo template de aplicação padrão:" #. type: Fenced code block #: ../src/guide/concept/configuration.md @@ -254,52 +319,73 @@ msgid "" ".merge-plan.php\n" "configuration.php\n" msgstr "" +"common/\n" +" bootstrap.php\n" +" params.php\n" +" routes.php\n" +" di/\n" +" *.php\n" +"console/\n" +" params.php\n" +"environments/\n" +" dev/\n" +" params.php\n" +" prod/\n" +" params.php\n" +" test/\n" +" params.php\n" +"web/\n" +" params.php\n" +" di/\n" +" *.php\n" +".merge-plan.php\n" +"configuration.php\n" #. type: Plain text #: ../src/guide/concept/configuration.md msgid "This structure follows the groups defined in `config/configuration.php`:" -msgstr "" +msgstr "Essa estrutura segue os grupos definidos em `config/configuration.php`:" #. type: Bullet: '- ' #: ../src/guide/concept/configuration.md msgid "`params`, `params-web`, and `params-console` load parameter files from `common/`, `web/`, and `console/`." -msgstr "" +msgstr "`params`, `params-web` e `params-console` carregam arquivos de parâmetros de `common/`, `web/` e `console/`." #. type: Bullet: '- ' #: ../src/guide/concept/configuration.md msgid "`di` and `di-web` load container definitions from `common/di/` and `web/di/`." -msgstr "" +msgstr "`di` e `di-web` carregam definições do container de `common/di/` e `web/di/`." #. type: Bullet: '- ' #: ../src/guide/concept/configuration.md msgid "`routes` and `bootstrap` load `common/routes.php` and `common/bootstrap.php`." -msgstr "" +msgstr "`routes` e `bootstrap` carregam `common/routes.php` e `common/bootstrap.php`." #. type: Bullet: '- ' #: ../src/guide/concept/configuration.md msgid "`config-plugin-environments` adds environment-specific parameter files from `environments/dev/`, `environments/test/`, and `environments/prod/`." -msgstr "" +msgstr "`config-plugin-environments` acrescenta arquivos de parâmetros específicos de cada ambiente de `environments/dev/`, `environments/test/` e `environments/prod/`." #. type: Plain text #: ../src/guide/concept/configuration.md msgid "At runtime, `.merge-plan.php` stores the assembled merge plan generated from `configuration.php`." -msgstr "" +msgstr "Em tempo de execução, `.merge-plan.php` guarda o merge plan montado a partir de `configuration.php`." #. type: Title ### #: ../src/guide/concept/configuration.md #, no-wrap msgid "Container configuration" -msgstr "" +msgstr "Configuração do container" #. type: Plain text #: ../src/guide/concept/configuration.md msgid "The application consists of services registered in a [dependency container](di-container.md). In the default template, direct container definitions live in `config/common/di/*.php` and `config/web/di/*.php`." -msgstr "" +msgstr "A aplicação é formada por serviços registrados em um [container de dependências](di-container.md). No template padrão, as definições diretas do container ficam em `config/common/di/*.php` e `config/web/di/*.php`." #. type: Plain text #: ../src/guide/concept/configuration.md msgid "Definitions from `common/di/` are shared by web and console entry points. The `di-web` group adds web-specific definitions from `web/di/`. The `di-console` group currently reuses the shared `di` definitions without extra files." -msgstr "" +msgstr "As definições de `common/di/` são compartilhadas pelos pontos de entrada web e de console. O grupo `di-web` acrescenta definições específicas da web, de `web/di/`. Atualmente, o grupo `di-console` reaproveita as definições compartilhadas de `di`, sem arquivos extras." #. type: Fenced code block (php) #: ../src/guide/concept/configuration.md @@ -323,82 +409,99 @@ msgid "" " ],\n" "];\n" msgstr "" +" [\n" +" '__construct()' => [\n" +" 'name' => $params['application']['name'],\n" +" 'charset' => $params['application']['charset'],\n" +" 'locale' => $params['application']['locale'],\n" +" ],\n" +" ],\n" +"];\n" #. type: Plain text #: ../src/guide/concept/configuration.md msgid "Config plugin passes the special `$params` variable to all config files. The definition uses it to configure services." -msgstr "" +msgstr "O plugin de configuração passa a variável especial `$params` para todos os arquivos de configuração. A definição a usa para configurar os serviços." #. type: Plain text #: ../src/guide/concept/configuration.md msgid "The guide on [\"Dependency injection and container\"](di-container.md) describes the configuration format and the idea of dependency injection in detail." -msgstr "" +msgstr "O guia [\"Injeção de dependência e container\"](di-container.md) descreve em detalhes o formato da configuração e a ideia de injeção de dependência." #. type: Plain text #: ../src/guide/concept/configuration.md msgid "For convenience, there is a naming convention for custom string keys:" -msgstr "" +msgstr "Por conveniência, existe uma convenção de nomes para chaves string personalizadas:" #. type: Bullet: '1. ' #: ../src/guide/concept/configuration.md msgid "Prefix package name such as `yiisoft/cache-file/custom-definition`." -msgstr "" +msgstr "Prefixe com o nome do pacote, como em `yiisoft/cache-file/custom-definition`." #. type: Bullet: '2. ' #: ../src/guide/concept/configuration.md msgid "In case configuration are for the application itself, skip package prefix, such as `custom-definition`." -msgstr "" +msgstr "Se a configuração for da própria aplicação, omita o prefixo do pacote, como em `custom-definition`." #. type: Title ### #: ../src/guide/concept/configuration.md #, no-wrap msgid "Service providers" -msgstr "" +msgstr "Service providers" #. type: Plain text #: ../src/guide/concept/configuration.md msgid "As an alternative to registering dependencies directly, you can use service providers. A service provider is a class that returns a reusable set of container definitions and extensions." -msgstr "" +msgstr "Como alternativa a registrar dependências diretamente, você pode usar service providers. Um service provider é uma classe que retorna um conjunto reutilizável de definições e extensões do container." #. type: Plain text #: ../src/guide/concept/configuration.md msgid "The default template exposes three config groups for service providers: `di-providers`, `di-providers-web`, and `di-providers-console`. In the template they are initialized as empty arrays in `config/configuration.php`, and you can later populate them inline or switch them to load values from files." -msgstr "" +msgstr "O template padrão expõe três grupos de configuração para service providers: `di-providers`, `di-providers-web` e `di-providers-console`. No template, eles são inicializados como arrays vazios em `config/configuration.php`, e depois você pode preenchê-los inline ou fazê-los carregar valores de arquivos." #. type: Plain text #: ../src/guide/concept/configuration.md msgid "Prefer direct container configuration for application services with a simple definition: a class name, an interface implementation, constructor arguments from `$params`, or a closure that creates a single service." -msgstr "" +msgstr "Prefira a configuração direta do container para serviços da aplicação com definição simples: um nome de classe, a implementação de uma interface, argumentos do construtor vindos de `$params` ou uma closure que cria um único serviço." #. type: Plain text #: ../src/guide/concept/configuration.md msgid "Use a service provider when the registration itself is a reusable unit:" -msgstr "" +msgstr "Use um service provider quando o próprio registro for uma unidade reutilizável:" #. type: Bullet: '- ' #: ../src/guide/concept/configuration.md msgid "A package registers several related services, aliases, or extensions." -msgstr "" +msgstr "Um pacote registra vários serviços, aliases ou extensões relacionados." #. type: Bullet: '- ' #: ../src/guide/concept/configuration.md msgid "A service registration also needs supporting definitions." -msgstr "" +msgstr "O registro de um serviço também precisa de definições de apoio." #. type: Bullet: '- ' #: ../src/guide/concept/configuration.md msgid "The same registration should be reused in several applications." -msgstr "" +msgstr "O mesmo registro deve ser reutilizado em várias aplicações." #. type: Bullet: '- ' #: ../src/guide/concept/configuration.md msgid "Registration depends on optional classes or environment-specific decisions." -msgstr "" +msgstr "O registro depende de classes opcionais ou de decisões específicas do ambiente." #. type: Plain text #: ../src/guide/concept/configuration.md msgid "Use a factory class when construction logic belongs to one service. A factory returns an object. A service provider returns definitions for several related services." -msgstr "" +msgstr "Use uma classe factory quando a lógica de construção pertence a um único serviço. Uma factory retorna um objeto. Um service provider retorna definições para vários serviços relacionados." #. type: Fenced code block (php) #: ../src/guide/concept/configuration.md @@ -418,21 +521,34 @@ msgid "" " // ...\n" "];\n" msgstr "" +"/* @var array $params */\n" +"\n" +"// ...\n" +"use App\\Provider\\CacheProvider;\n" +"use App\\Provider\\MiddlewareProvider;\n" +"// ...\n" +"\n" +"return [\n" +" // ...\n" +" 'yiisoft/yii-web/middleware' => MiddlewareProvider::class,\n" +" 'yiisoft/cache/cache' => new CacheProvider($params['yiisoft/cache-file']['file-cache']['path']),\n" +" // ...\n" +"];\n" #. type: Plain text #: ../src/guide/concept/configuration.md msgid "In this config keys are provider names. By convention these are `vendor/package-name/provider-name`. Values are provider class names or provider instances. These classes could be either created in the project itself or provided by a package." -msgstr "" +msgstr "Nesta configuração, as chaves são os nomes dos providers. Por convenção, eles seguem o formato `vendor/package-name/provider-name`. Os valores são nomes de classes de provider ou instâncias de provider. Essas classes podem ser criadas no próprio projeto ou fornecidas por um pacote." #. type: Plain text #: ../src/guide/concept/configuration.md msgid "If you need to configure some options for a service, similar to direct container configuration, take values from `$params` and pass them to providers." -msgstr "" +msgstr "Se você precisar configurar algumas opções de um serviço, da mesma forma que na configuração direta do container, pegue os valores de `$params` e passe-os aos providers." #. type: Plain text #: ../src/guide/concept/configuration.md msgid "Provider should implement `Yiisoft\\Di\\ServiceProviderInterface`. Below is a provider for a cache service:" -msgstr "" +msgstr "O provider deve implementar `Yiisoft\\Di\\ServiceProviderInterface`. Abaixo está um provider para um serviço de cache:" #. type: Fenced code block (php) #: ../src/guide/concept/configuration.md @@ -472,18 +588,50 @@ msgid "" " }\n" "}\n" msgstr "" +"use Psr\\Container\\ContainerInterface;\n" +"use Psr\\SimpleCache\\CacheInterface;\n" +"use Yiisoft\\Aliases\\Aliases;\n" +"use Yiisoft\\Cache\\Cache;\n" +"use Yiisoft\\Cache\\CacheInterface as YiiCacheInterface;\n" +"use Yiisoft\\Cache\\File\\FileCache;\n" +"use Yiisoft\\Di\\ServiceProviderInterface;\n" +"\n" +"final readonly class CacheProvider implements ServiceProviderInterface\n" +"{\n" +" public function __construct(\n" +" private string $cachePath = '@runtime/cache'\n" +" )\n" +" {\n" +" }\n" +"\n" +" public function getDefinitions(): array\n" +" {\n" +" return [\n" +" CacheInterface::class => function (ContainerInterface $container) {\n" +" $aliases = $container->get(Aliases::class);\n" +"\n" +" return new FileCache($aliases->get($this->cachePath));\n" +" },\n" +" YiiCacheInterface::class => Cache::class,\n" +" ];\n" +" }\n" +"\n" +" public function getExtensions(): array\n" +" {\n" +" return [];\n" +" }\n" +"}\n" #. type: Title ## -#: ../src/guide/concept/configuration.md -#: ../src/guide/structure/designing-packages.md +#: ../src/guide/concept/configuration.md ../src/guide/structure/designing-packages.md #, no-wrap msgid "Routes" -msgstr "" +msgstr "Rotas" #. type: Plain text #: ../src/guide/concept/configuration.md msgid "You can configure how the web application responds to certain URLs in `config/common/routes.php`:" -msgstr "" +msgstr "Você pode configurar como a aplicação web responde a determinadas URLs em `config/common/routes.php`:" #. type: Fenced code block (php) #: ../src/guide/concept/configuration.md ../src/guide/intro/upgrade-from-v2.md @@ -502,29 +650,39 @@ msgid "" " ),\n" "];\n" msgstr "" +"use App\\Web;\n" +"use Yiisoft\\Router\\Group;\n" +"use Yiisoft\\Router\\Route;\n" +"\n" +"return [\n" +" Group::create()\n" +" ->routes(\n" +" Route::get('/')\n" +" ->action(Web\\HomePage\\Action::class)\n" +" ->name('home'),\n" +" ),\n" +"];\n" #. type: Plain text #: ../src/guide/concept/configuration.md msgid "Read more about it in [\"Routes\"](../runtime/routing.md)." -msgstr "" +msgstr "Leia mais sobre isso em [\"Rotas\"](../runtime/routing.md)." #. type: Title ## -#: ../src/guide/concept/configuration.md ../src/guide/concept/events.md -#: ../src/guide/structure/designing-packages.md -#: ../src/internals/022-config-groups.md +#: ../src/guide/concept/configuration.md ../src/guide/concept/events.md ../src/guide/structure/designing-packages.md ../src/internals/022-config-groups.md #, no-wrap msgid "Events" -msgstr "" +msgstr "Eventos" #. type: Plain text #: ../src/guide/concept/configuration.md msgid "Many services emit certain events that you can attach to. The default template defines three event config groups in `config/configuration.php`: `events`, `events-web`, and `events-console`. They are empty by default, but you can populate them inline or point them to event config files." -msgstr "" +msgstr "Muitos serviços emitem eventos aos quais você pode se associar. O template padrão define três grupos de configuração de eventos em `config/configuration.php`: `events`, `events-web` e `events-console`. Eles vêm vazios por padrão, mas você pode preenchê-los inline ou apontá-los para arquivos de configuração de eventos." #. type: Plain text #: ../src/guide/concept/configuration.md msgid "The configuration is an array where keys are event names and values are arrays of handlers:" -msgstr "" +msgstr "A configuração é um array em que as chaves são os nomes dos eventos e os valores são arrays de handlers:" #. type: Fenced code block (php) #: ../src/guide/concept/configuration.md @@ -557,24 +715,48 @@ msgid "" " ],\n" "];\n" msgstr "" +"return [\n" +" EventName::class => [\n" +" // Uma closure comum, que será chamada pelo Dispatcher \"como está\".\n" +" static fn (EventName $event) => someStuff($event),\n" +" \n" +" // Uma closure comum com uma dependência extra. Todos os parâmetros depois do primeiro (o próprio evento)\n" +" // serão resolvidos pelo seu container de DI por meio do `yiisoft/injector`.\n" +" static fn (EventName $event, DependencyClass $dependency) => someStuff($event),\n" +" \n" +" // Um exemplo com um callable comum. Se o método `staticMethodName` tiver dependências,\n" +" // elas serão resolvidas da mesma forma que no exemplo anterior.\n" +" [SomeClass::class, 'staticMethodName'],\n" +" \n" +" // Métodos não estáticos também são permitidos. Nesse caso, `SomeClass` será instanciada pelo seu container de DI.\n" +" [SomeClass::class, 'methodName'],\n" +" \n" +" // Um objeto de uma classe que implementa o método `__invoke`\n" +" new InvokableClass(),\n" +" \n" +" // Nesse caso, a `InvokableClass` com o método `__invoke` será instanciada pelo seu container de DI\n" +" InvokableClass::class,\n" +" \n" +" // Qualquer definição de classe invocável pode estar aqui, desde que `$container->has('the definition')` seja true.\n" +" 'di-alias'\n" +" ],\n" +"];\n" #. type: Plain text #: ../src/guide/concept/configuration.md msgid "Read more about it in [\"Events\"](events.md)." -msgstr "" +msgstr "Leia mais sobre isso em [\"Eventos\"](events.md)." #. type: Title ## -#: ../src/guide/concept/configuration.md -#: ../src/guide/structure/designing-packages.md -#: ../src/internals/022-config-groups.md +#: ../src/guide/concept/configuration.md ../src/guide/structure/designing-packages.md ../src/internals/022-config-groups.md #, no-wrap msgid "Parameters" -msgstr "" +msgstr "Parâmetros" #. type: Plain text #: ../src/guide/concept/configuration.md msgid "Base parameters are stored in `config/common/params.php`. They are then extended by `config/web/params.php`, `config/console/params.php`, and environment-specific files under `config/environments/`." -msgstr "" +msgstr "Os parâmetros base ficam em `config/common/params.php`. Depois, eles são estendidos por `config/web/params.php`, `config/console/params.php` e pelos arquivos específicos de cada ambiente em `config/environments/`." #. type: Plain text #: ../src/guide/concept/configuration.md @@ -584,11 +766,14 @@ msgid "" "> Don't use parameters, constants, or environment variables directly in your application, configure\n" "> services instead.\n" msgstr "" +"> [!TIP]\n" +"> Não use parâmetros, constantes ou variáveis de ambiente diretamente na sua aplicação; em vez disso, configure\n" +"> os serviços.\n" #. type: Plain text #: ../src/guide/concept/configuration.md msgid "The default application `common/params.php` looks like the following:" -msgstr "" +msgstr "O `common/params.php` da aplicação padrão é assim:" #. type: Fenced code block (php) #: ../src/guide/concept/configuration.md @@ -633,49 +818,87 @@ msgid "" " ],\n" "];\n" msgstr "" +" require __DIR__ . '/application.php',\n" +"\n" +" 'yiisoft/aliases' => [\n" +" 'aliases' => require __DIR__ . '/aliases.php',\n" +" ],\n" +"\n" +" 'yiisoft/view' => [\n" +" 'basePath' => null,\n" +" 'parameters' => [\n" +" 'assetManager' => Reference::to(AssetManager::class),\n" +" 'applicationParams' => Reference::to(ApplicationParams::class),\n" +" 'aliases' => Reference::to(Aliases::class),\n" +" 'urlGenerator' => Reference::to(UrlGeneratorInterface::class),\n" +" 'currentRoute' => Reference::to(CurrentRoute::class),\n" +" ],\n" +" ],\n" +"\n" +" 'yiisoft/yii-view-renderer' => [\n" +" 'viewPath' => null,\n" +" 'layout' => '@src/Web/Shared/Layout/Main/layout.php',\n" +" 'injections' => [\n" +" Reference::to(CsrfViewInjection::class),\n" +" ],\n" +" ],\n" +"];\n" #. type: Plain text #: ../src/guide/concept/configuration.md msgid "For convenience, there is a naming convention about parameters:" -msgstr "" +msgstr "Por conveniência, existe uma convenção de nomes para os parâmetros:" #. type: Bullet: '1. ' #: ../src/guide/concept/configuration.md msgid "Group parameters package name such as `yiisoft/cache-file`." -msgstr "" +msgstr "Agrupe os parâmetros pelo nome do pacote, como em `yiisoft/cache-file`." #. type: Bullet: '2. ' #: ../src/guide/concept/configuration.md msgid "In case parameters are for the application itself, as in `application`, skip package prefix." -msgstr "" +msgstr "Se os parâmetros forem da própria aplicação, como em `application`, omita o prefixo do pacote." #. type: Bullet: '3. ' #: ../src/guide/concept/configuration.md msgid "In case there are many services in the package, such as `file-target` and `file-rotator` in `yiisoft/log-target-file` package, group parameters by service name." -msgstr "" +msgstr "Se houver muitos serviços no pacote, como `file-target` e `file-rotator` no pacote `yiisoft/log-target-file`, agrupe os parâmetros pelo nome do serviço." #. type: Bullet: '4. ' #: ../src/guide/concept/configuration.md msgid "Use `enabled` as parameter name to be able to disable or enable a service, such as `yiisoft/yii-debug`." -msgstr "" +msgstr "Use `enabled` como nome de parâmetro para poder desabilitar ou habilitar um serviço, como em `yiisoft/yii-debug`." #. type: Title ### #: ../src/guide/concept/configuration.md #, no-wrap msgid "Package configs" -msgstr "" +msgstr "Configurações de pacotes" #. type: Plain text #: ../src/guide/concept/configuration.md msgid "Config plugin does not copy vendor package configs automatically. It loads them directly from `vendor/` as the vendor layer and combines them with the root package and environment-specific layers." -msgstr "" +msgstr "O plugin de configuração não copia automaticamente as configurações dos pacotes em vendor. Ele as carrega diretamente de `vendor/` como camada vendor e as combina com as camadas do pacote raiz e específicas de cada ambiente." #. type: Plain text #: ../src/guide/concept/configuration.md msgid "If you want to customize a package config file in your application, use the `yii-config-copy` Composer command to copy it into your `config/` directory, usually under `config/packages/`. Once copied, the file becomes part of the root package layer, so it can override vendor defaults." -msgstr "" +msgstr "Se você quiser personalizar um arquivo de configuração de um pacote na sua aplicação, use o comando do Composer `yii-config-copy` para copiá-lo para a sua pasta `config/`, normalmente em `config/packages/`. Depois de copiado, o arquivo passa a fazer parte da camada do pacote raiz e pode sobrescrever os padrões de vendor." #. type: Plain text #: ../src/guide/concept/configuration.md msgid "The merge plan stored in `.merge-plan.php` defines how config groups are assembled. If you add new config files or directories and update the root package configuration, rebuild the merge plan with `composer yii-config-rebuild`." -msgstr "" +msgstr "O merge plan guardado em `.merge-plan.php` define como os grupos de configuração são montados. Se você adicionar novos arquivos ou pastas de configuração e atualizar a configuração do pacote raiz, reconstrua o merge plan com `composer yii-config-rebuild`." diff --git a/_translations/po/pt-BR/guide_concept_di-container.md.po b/_translations/po/pt-BR/guide_concept_di-container.md.po index f06f945a..1b1b9559 100644 --- a/_translations/po/pt-BR/guide_concept_di-container.md.po +++ b/_translations/po/pt-BR/guide_concept_di-container.md.po @@ -8,45 +8,40 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-06-05 20:33+0000\n" "PO-Revision-Date: 2026-06-05 20:33+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md -#: ../src/guide/concept/autoloading.md ../src/guide/concept/di-container.md -#: ../src/guide/security/best-practices.md ../src/guide/structure/domain.md -#: ../src/guide/tutorial/console-applications.md -#: ../src/internals/004-namespaces.md ../src/internals/007-exceptions.md -#: ../src/internals/008-interfaces.md +#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md ../src/guide/concept/autoloading.md ../src/guide/concept/di-container.md ../src/guide/security/best-practices.md ../src/guide/structure/domain.md ../src/guide/tutorial/console-applications.md ../src/internals/004-namespaces.md ../src/internals/007-exceptions.md ../src/internals/008-interfaces.md #, no-wrap msgid "References" -msgstr "" +msgstr "Referências" #. type: Title # #: ../src/guide/concept/di-container.md #, no-wrap msgid "Dependency injection and container" -msgstr "" +msgstr "Injeção de dependência e container" #. type: Title ## #: ../src/guide/concept/di-container.md #, no-wrap msgid "Dependency injection" -msgstr "" +msgstr "Injeção de dependência" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "There are two ways of re-using things in OOP: inheritance and composition." -msgstr "" +msgstr "Há duas formas de reaproveitar código em OOP: herança e composição." #. type: Plain text #: ../src/guide/concept/di-container.md msgid "Inheritance is simple:" -msgstr "" +msgstr "A herança é simples:" #. type: Fenced code block (php) #: ../src/guide/concept/di-container.md @@ -72,16 +67,35 @@ msgid "" " }\n" "}\n" msgstr "" +"class Cache\n" +"{\n" +" public function getCachedValue($key)\n" +" {\n" +" // ..\n" +" }\n" +"}\n" +"\n" +"final readonly class CachedWidget extends Cache\n" +"{\n" +" public function render(): string\n" +" {\n" +" $output = $this->getCachedValue('cachedWidget');\n" +" if ($output !== null) {\n" +" return $output;\n" +" }\n" +" // ... \n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "The issue here is that these two are becoming unnecessarily coupled or inter-dependent, making them more fragile." -msgstr "" +msgstr "O problema aqui é que essas duas classes ficam acopladas ou interdependentes sem necessidade, o que as torna mais frágeis." #. type: Plain text #: ../src/guide/concept/di-container.md msgid "Another way to handle this is composition:" -msgstr "" +msgstr "Outra forma de resolver isso é a composição:" #. type: Fenced code block (php) #: ../src/guide/concept/di-container.md @@ -118,123 +132,153 @@ msgid "" " }\n" "}\n" msgstr "" +"interface CacheInterface\n" +"{\n" +" public function getCachedValue($key);\n" +"}\n" +"\n" +"final readonly class Cache implements CacheInterface\n" +"{\n" +" public function getCachedValue($key)\n" +" {\n" +" // ..\n" +" }\n" +"}\n" +"\n" +"final readonly class CachedWidget\n" +"{\n" +" public function __construct(\n" +" private CacheInterface $cache\n" +" )\n" +" {\n" +" }\n" +" \n" +" public function render(): string\n" +" {\n" +" $output = $this->cache->getCachedValue('cachedWidget');\n" +" if ($output !== null) {\n" +" return $output;\n" +" }\n" +" // ... \n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "We've avoided unnecessary inheritance and used `CacheInterface` in the `CacheWidget` to reduce coupling. You can replace cache implementation without changing `CachedWidget` so it's becoming more stable. The less edits are made to the code, the less chance of breaking it." -msgstr "" +msgstr "Evitamos a herança desnecessária e usamos `CacheInterface` no `CacheWidget` para reduzir o acoplamento. Você pode trocar a implementação do cache sem alterar o `CachedWidget`, então ele fica mais estável. Quanto menos edições forem feitas no código, menor a chance de quebrá-lo." #. type: Plain text #: ../src/guide/concept/di-container.md msgid "The `CacheInterface` here is a dependency: a contract our object needs to function. In other words, our object depends on the contract." -msgstr "" +msgstr "Aqui, `CacheInterface` é uma dependência: um contrato de que o nosso objeto precisa para funcionar. Em outras palavras, o nosso objeto depende do contrato." #. type: Plain text #: ../src/guide/concept/di-container.md msgid "The process of putting an instance of a contract into an object (`CachedWidget`) is called dependency injection. There are many ways to perform it:" -msgstr "" +msgstr "O processo de colocar uma instância de um contrato dentro de um objeto (`CachedWidget`) se chama injeção de dependência. Há várias formas de fazer isso:" #. type: Bullet: '- ' #: ../src/guide/concept/di-container.md msgid "Constructor injection. Best for mandatory dependencies." -msgstr "" +msgstr "Injeção pelo construtor. A melhor para dependências obrigatórias." #. type: Bullet: '- ' #: ../src/guide/concept/di-container.md msgid "Method injection. Best for optional dependencies." -msgstr "" +msgstr "Injeção por método. A melhor para dependências opcionais." #. type: Bullet: '- ' #: ../src/guide/concept/di-container.md msgid "Property injection. Better to be avoided in PHP except maybe data transfer objects." -msgstr "" +msgstr "Injeção por propriedade. É melhor evitar em PHP, exceto talvez em data transfer objects." #. type: Title ### #: ../src/guide/concept/di-container.md #, no-wrap msgid "Why use private properties" -msgstr "" +msgstr "Por que usar propriedades privadas" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "In the composition example above, note that the `$cache` property is declared as `private`." -msgstr "" +msgstr "No exemplo de composição acima, repare que a propriedade `$cache` é declarada como `private`." #. type: Plain text #: ../src/guide/concept/di-container.md msgid "This approach embraces composition by ensuring objects have well-defined interfaces for interaction rather than direct property access, making the code more maintainable and less prone to certain types of mistakes." -msgstr "" +msgstr "Essa abordagem favorece a composição ao garantir que os objetos tenham interfaces bem definidas para interação, em vez de acesso direto às propriedades, o que deixa o código mais fácil de manter e menos sujeito a certos tipos de erro." #. type: Plain text #: ../src/guide/concept/di-container.md msgid "This design choice provides several benefits:" -msgstr "" +msgstr "Essa escolha de design traz vários benefícios:" #. type: Bullet: '- ' #: ../src/guide/concept/di-container.md msgid "**Encapsulation**: Private properties with getters/setters allow you to control access and make future changes without breaking existing code." -msgstr "" +msgstr "**Encapsulamento**: propriedades privadas com getters/setters permitem controlar o acesso e fazer mudanças futuras sem quebrar o código existente." #. type: Bullet: '- ' #: ../src/guide/concept/di-container.md msgid "**Data integrity**: Setters can validate, normalize, or format values before storing them, ensuring properties contain valid data." -msgstr "" +msgstr "**Integridade dos dados**: setters podem validar, normalizar ou formatar valores antes de armazená-los, garantindo que as propriedades contenham dados válidos." #. type: Bullet: '- ' #: ../src/guide/concept/di-container.md msgid "**Immutability**: Private properties enable immutable object patterns where setter `with*()` methods return new instances rather than modifying the current one." -msgstr "" +msgstr "**Imutabilidade**: propriedades privadas permitem padrões de objetos imutáveis, em que os métodos `with*()` retornam novas instâncias em vez de modificar a atual." #. type: Bullet: '- ' #: ../src/guide/concept/di-container.md msgid "**Flexibility**: You can create read-only or write-only properties or add additional logic to property access later." -msgstr "" +msgstr "**Flexibilidade**: você pode criar propriedades somente leitura ou somente escrita, ou acrescentar lógica ao acesso às propriedades mais tarde." #. type: Title ## #: ../src/guide/concept/di-container.md #, no-wrap msgid "DI container" -msgstr "" +msgstr "Container de DI" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "Injecting basic dependencies is straightforward. You're choosing a place where you don't care about dependencies, which is usually an action handler, which you aren't going to unit-test ever, create instances of dependencies needed and pass these to dependent classes." -msgstr "" +msgstr "Injetar dependências básicas é simples. Você escolhe um lugar onde não se importa com as dependências, que normalmente é um handler de action, que você nunca vai testar com testes unitários, cria as instâncias das dependências necessárias e as passa para as classes dependentes." #. type: Plain text #: ../src/guide/concept/di-container.md msgid "It works well when there are few dependencies overall and when there are no nested dependencies. When there are many and each dependency has dependencies itself, instantiating the whole hierarchy becomes a tedious process, which requires lots of code and may lead to hardly debuggable mistakes." -msgstr "" +msgstr "Isso funciona bem quando há poucas dependências no total e quando não há dependências aninhadas. Quando há muitas e cada dependência tem as suas próprias dependências, instanciar a hierarquia inteira se torna um processo tedioso, que exige muito código e pode levar a erros difíceis de depurar." #. type: Plain text #: ../src/guide/concept/di-container.md msgid "Additionally, lots of dependencies, such as certain third-party API wrappers, are the same for any class using it. So it makes sense to:" -msgstr "" +msgstr "Além disso, muitas dependências, como certos wrappers de APIs de terceiros, são as mesmas para qualquer classe que as use. Então faz sentido:" #. type: Bullet: '- ' #: ../src/guide/concept/di-container.md msgid "Define how to instantiate such common dependencies." -msgstr "" +msgstr "Definir como instanciar essas dependências comuns." #. type: Bullet: '- ' #: ../src/guide/concept/di-container.md msgid "Instantiate them when required and only once per request." -msgstr "" +msgstr "Instanciá-las quando necessário e apenas uma vez por requisição." #. type: Plain text #: ../src/guide/concept/di-container.md msgid "That's what dependency containers are for." -msgstr "" +msgstr "É para isso que servem os containers de dependências." #. type: Plain text #: ../src/guide/concept/di-container.md msgid "A dependency injection (DI) container is an object that knows how to instantiate and configure objects and all objects they depend on." -msgstr "" +msgstr "Um container de injeção de dependência (DI) é um objeto que sabe como instanciar e configurar objetos e todos os objetos dos quais eles dependem." #. type: Plain text #: ../src/guide/concept/di-container.md msgid "Yii provides the DI container feature through the [yiisoft/di](https://github.com/yiisoft/di) package and [yiisoft/injector](https://github.com/yiisoft/injector) package." -msgstr "" +msgstr "O Yii fornece o container de DI por meio dos pacotes [yiisoft/di](https://github.com/yiisoft/di) e [yiisoft/injector](https://github.com/yiisoft/injector)." #. type: Plain text #: ../src/guide/concept/di-container.md @@ -244,6 +288,9 @@ msgid "" "> The container contains only shared instances. If you need a factory, use the dedicated\n" "> [yiisoft/factory](https://github.com/yiisoft/factory) package.\n" msgstr "" +"> [!NOTE]\n" +"> O container contém apenas instâncias compartilhadas. Se você precisar de uma factory, use o pacote dedicado\n" +"> [yiisoft/factory](https://github.com/yiisoft/factory).\n" #. type: Plain text #: ../src/guide/concept/di-container.md @@ -253,17 +300,20 @@ msgid "" "> [Martin Fowler's article](https://martinfowler.com/articles/injection.html) has well\n" "> explained why DI container is useful. Here we will mainly explain the usage of the DI container provided by Yii.\n" msgstr "" +"> [!TIP]\n" +"> O [artigo de Martin Fowler](https://martinfowler.com/articles/injection.html) explica bem\n" +"> por que um container de DI é útil. Aqui vamos explicar principalmente o uso do container de DI fornecido pelo Yii.\n" #. type: Title ### #: ../src/guide/concept/di-container.md #, no-wrap msgid "Configuring container" -msgstr "" +msgstr "Configurando o container" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "Because to create a new object you need its dependencies, you should register them as early as possible. You can do it in the application configuration, `config/web.php`. For the following service:" -msgstr "" +msgstr "Como para criar um novo objeto você precisa das dependências dele, registre-as o quanto antes. Você pode fazer isso na configuração da aplicação, `config/web.php`. Para o seguinte serviço:" #. type: Fenced code block (php) #: ../src/guide/concept/di-container.md @@ -281,11 +331,22 @@ msgid "" " }\n" "}\n" msgstr "" +"final class MyService implements MyServiceInterface\n" +"{\n" +" public function __construct(int $amount)\n" +" {\n" +" }\n" +"\n" +" public function setDiscount(int $discount): void\n" +" {\n" +" \n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "configuration could be:" -msgstr "" +msgstr "a configuração poderia ser:" #. type: Fenced code block (php) #: ../src/guide/concept/di-container.md @@ -299,11 +360,18 @@ msgid "" " ],\n" "];\n" msgstr "" +"return [\n" +" MyServiceInterface::class => [\n" +" 'class' => MyService::class,\n" +" '__construct()' => [42],\n" +" 'setDiscount()' => [10],\n" +" ],\n" +"];\n" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "That's equal to the following:" -msgstr "" +msgstr "Isso equivale ao seguinte:" #. type: Fenced code block (php) #: ../src/guide/concept/di-container.md @@ -312,11 +380,13 @@ msgid "" "$myService = new MyService(42);\n" "$myService->setDiscount(10);\n" msgstr "" +"$myService = new MyService(42);\n" +"$myService->setDiscount(10);\n" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "You can provide arguments with names as well:" -msgstr "" +msgstr "Você também pode passar argumentos com nomes:" #. type: Fenced code block (php) #: ../src/guide/concept/di-container.md @@ -330,11 +400,18 @@ msgid "" " ],\n" "];\n" msgstr "" +"return [\n" +" MyServiceInterface::class => [\n" +" 'class' => MyService::class,\n" +" '__construct()' => ['amount' => 42],\n" +" 'setDiscount()' => ['discount' => 10],\n" +" ],\n" +"];\n" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "That's basically it. You define a map of interfaces to classes and define how to configure them. When an interface is requested in constructor or elsewhere, container creates an instance of a class and configures it as per the configuration:" -msgstr "" +msgstr "Basicamente é isso. Você define um mapa de interfaces para classes e define como configurá-las. Quando uma interface é solicitada no construtor ou em outro lugar, o container cria uma instância da classe e a configura conforme a configuração:" #. type: Fenced code block (php) #: ../src/guide/concept/di-container.md @@ -353,16 +430,28 @@ msgid "" " }\n" "}\n" msgstr "" +"final class MyAction\n" +"{\n" +" public function __construct(\n" +" private readonly MyServiceInterface $myService\n" +" ) {\n" +" }\n" +" \n" +" public function __invoke() \n" +" {\n" +" $this->myService->doSomething();\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "There are extra methods of declaring dependency configuration." -msgstr "" +msgstr "Há outras formas de declarar a configuração de dependências." #. type: Plain text #: ../src/guide/concept/di-container.md msgid "For simplest cases where there are no custom values needed and all the constructor dependencies could be obtained from a container, you can use a class name as a value." -msgstr "" +msgstr "Nos casos mais simples, em que não são necessários valores personalizados e todas as dependências do construtor podem ser obtidas do container, você pode usar um nome de classe como valor." #. type: Fenced code block (php) #: ../src/guide/concept/di-container.md @@ -379,11 +468,21 @@ msgid "" " } \n" "}\n" msgstr "" +"interface EngineInterface\n" +"{\n" +" \n" +"}\n" +"\n" +"final class EngineMarkOne implements EngineInterface\n" +"{\n" +" public function __construct(CacheInterface $cache) {\n" +" } \n" +"}\n" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "In the above example, if we already have cache defined in the container, nothing besides the class name is needed:" -msgstr "" +msgstr "No exemplo acima, se já houver um cache definido no container, não é preciso nada além do nome da classe:" #. type: Fenced code block (php) #: ../src/guide/concept/di-container.md @@ -394,11 +493,15 @@ msgid "" " EngineInterface::class => EngineMarkOne::class,\n" "];\n" msgstr "" +"return [\n" +" // declara uma classe para uma interface, resolvendo as dependências automaticamente\n" +" EngineInterface::class => EngineMarkOne::class,\n" +"];\n" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "If you have a dependency that has public properties, you can configure it as well." -msgstr "" +msgstr "Se você tiver uma dependência com propriedades públicas, também pode configurá-la." #. type: Fenced code block (php) #: ../src/guide/concept/di-container.md @@ -409,11 +512,15 @@ msgid "" " public string $name;\n" "}\n" msgstr "" +"final class NameProvider\n" +"{\n" +" public string $name;\n" +"}\n" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "Here's how to do it for the example above:" -msgstr "" +msgstr "Veja como fazer isso no exemplo acima:" #. type: Fenced code block (php) #: ../src/guide/concept/di-container.md @@ -424,16 +531,20 @@ msgid "" " '$name' => 'Alex',\n" "],\n" msgstr "" +"NameProvider::class => [\n" +" 'class' => NameProvider::class, \n" +" '$name' => 'Alex',\n" +"],\n" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "In this example, you may notice `NameProvider` specified twice. The key is what you may request as dependency and the value is how to create it." -msgstr "" +msgstr "Neste exemplo, você pode notar que `NameProvider` aparece duas vezes. A chave é o que você pode solicitar como dependência, e o valor é como criá-la." #. type: Plain text #: ../src/guide/concept/di-container.md msgid "If the configuration is tricky and requires some logic, a closure can be used:" -msgstr "" +msgstr "Se a configuração for complicada e exigir alguma lógica, você pode usar uma closure:" #. type: Fenced code block (php) #: ../src/guide/concept/di-container.md @@ -443,11 +554,14 @@ msgid "" " return new MyService($container->get('db'));\n" "},\n" msgstr "" +"MyServiceInterface::class => static function(ContainerInterface $container) {\n" +" return new MyService($container->get('db'));\n" +"},\n" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "Additionally, to `ContainerInterface`, you can request any registered service directly as a closure parameter. The injector will automatically resolve and inject these:" -msgstr "" +msgstr "Além do `ContainerInterface`, você pode solicitar qualquer serviço registrado diretamente como parâmetro da closure. O injector vai resolvê-los e injetá-los automaticamente:" #. type: Fenced code block (php) #: ../src/guide/concept/di-container.md @@ -457,44 +571,47 @@ msgid "" " return new MyService($db);\n" "},\n" msgstr "" +"MyServiceInterface::class => static function(ConnectionInterface $db) {\n" +" return new MyService($db);\n" +"},\n" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "It's possible to use a static method call:" -msgstr "" +msgstr "É possível usar a chamada de um método estático:" #. type: Fenced code block (php) #: ../src/guide/concept/di-container.md #, no-wrap msgid "MyServiceInterface::class => [MyFactory::class, 'create'],\n" -msgstr "" +msgstr "MyServiceInterface::class => [MyFactory::class, 'create'],\n" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "Or an instance of an object:" -msgstr "" +msgstr "Ou uma instância de um objeto:" #. type: Fenced code block (php) #: ../src/guide/concept/di-container.md #, no-wrap msgid "MyServiceInterface::class => new MyService(),\n" -msgstr "" +msgstr "MyServiceInterface::class => new MyService(),\n" #. type: Title ### #: ../src/guide/concept/di-container.md #, no-wrap msgid "Injecting dependencies properly" -msgstr "" +msgstr "Injetando dependências corretamente" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "Directly referencing a container in a class is a bad idea since the code becomes non-generic, coupled to the container interface and, what's worse, dependencies are becoming hidden. Because of that, Yii inverts the control by automatically injecting objects from a container in some constructors and methods based on method argument types." -msgstr "" +msgstr "Referenciar o container diretamente em uma classe é uma má ideia, porque o código deixa de ser genérico, fica acoplado à interface do container e, pior ainda, as dependências ficam escondidas. Por isso, o Yii inverte o controle, injetando automaticamente objetos do container em alguns construtores e métodos com base nos tipos dos argumentos." #. type: Plain text #: ../src/guide/concept/di-container.md msgid "This is primarily done in constructor and handing method of action handlers:" -msgstr "" +msgstr "Isso é feito principalmente no construtor e no método de tratamento dos handlers de action:" #. type: Fenced code block (php) #: ../src/guide/concept/di-container.md @@ -523,13 +640,35 @@ msgid "" " }\n" "}\n" msgstr "" +"use \\Yiisoft\\Cache\\CacheInterface;\n" +"\n" +"final readonly class MyController\n" +"{\n" +" public function __construct(\n" +" private CacheInterface $cache\n" +" )\n" +" {\n" +" $this->cache = $cache; \n" +" }\n" +"\n" +" public function actionDashboard(RevenueReport $report)\n" +" {\n" +" $reportData = $this->cache->getOrSet('revenue_report', function() use ($report) {\n" +" return $report->getData(); \n" +" });\n" +"\n" +" return $this->render('dashboard', [\n" +" 'reportData' => $reportData,\n" +" ]);\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "Since it's [yiisoft/injector](https://github.com/yiisoft/injector) that instantiates and calls action handler, it checks the constructor and method argument types, gets dependencies of these types from a container and passes them as arguments. That's usually called auto-wiring. It happens for sub-dependencies as well, that's if you don't give dependency explicitly, the container would check if it has such a dependency first. It's enough to declare a dependency you need, and it would be got from a container automatically." -msgstr "" +msgstr "Como é o [yiisoft/injector](https://github.com/yiisoft/injector) que instancia e chama o handler de action, ele verifica os tipos dos argumentos do construtor e do método, obtém do container as dependências desses tipos e as passa como argumentos. Isso normalmente se chama autowiring. Acontece também com as subdependências: se você não fornecer uma dependência explicitamente, o container vai verificar primeiro se tem essa dependência. Basta declarar a dependência de que você precisa, e ela será obtida do container automaticamente." #. type: Bullet: '- ' #: ../src/guide/concept/di-container.md msgid "[Inversion of Control Containers and the Dependency Injection pattern by Martin Fowler](https://martinfowler.com/articles/injection.html)" -msgstr "" +msgstr "[Inversion of Control Containers and the Dependency Injection pattern, de Martin Fowler](https://martinfowler.com/articles/injection.html)" diff --git a/_translations/po/pt-BR/guide_concept_events.md.po b/_translations/po/pt-BR/guide_concept_events.md.po index ba44b834..57dd1600 100644 --- a/_translations/po/pt-BR/guide_concept_events.md.po +++ b/_translations/po/pt-BR/guide_concept_events.md.po @@ -8,51 +8,49 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-06-05 20:33+0000\n" "PO-Revision-Date: 2026-06-05 20:33+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/guide/concept/configuration.md ../src/guide/concept/events.md -#: ../src/guide/structure/designing-packages.md -#: ../src/internals/022-config-groups.md +#: ../src/guide/concept/configuration.md ../src/guide/concept/events.md ../src/guide/structure/designing-packages.md ../src/internals/022-config-groups.md #, no-wrap msgid "Events" -msgstr "" +msgstr "Eventos" #. type: Plain text #: ../src/guide/concept/events.md msgid "Events allow you to run custom code at certain execution points without changing the code that emits the event. You attach a custom code called a listener to an event. When the event is dispatched, the listener is executed." -msgstr "" +msgstr "Eventos permitem executar código personalizado em determinados pontos da execução, sem alterar o código que emite o evento. Você associa a um evento um código personalizado chamado listener. Quando o evento é disparado, o listener é executado." #. type: Plain text #: ../src/guide/concept/events.md msgid "For example, when a user signs up, you need to send a welcome email. You can do it in `SignupService`. Later, when you also need to resize the user's avatar image, the service has to know about that too." -msgstr "" +msgstr "Por exemplo, quando um usuário se cadastra, você precisa enviar um e-mail de boas-vindas. Dá para fazer isso no `SignupService`. Mais tarde, quando você também precisar redimensionar a imagem de avatar do usuário, o serviço vai ter que saber disso também." #. type: Plain text #: ../src/guide/concept/events.md msgid "A cleaner flow is to dispatch a `UserSignedUp` event from `SignupService`. The welcome email sender and the avatar processor listen to this event. Additional signup-related work can be added by registering another listener." -msgstr "" +msgstr "Um fluxo mais limpo é disparar um evento `UserSignedUp` a partir do `SignupService`. O remetente do e-mail de boas-vindas e o processador de avatar escutam esse evento. Trabalho adicional relacionado ao cadastro pode ser incluído registrando outro listener." #. type: Plain text #: ../src/guide/concept/events.md msgid "Yii uses [yiisoft/yii-event](https://github.com/yiisoft/yii-event) for application event configuration. It builds on the [yiisoft/event-dispatcher](https://github.com/yiisoft/event-dispatcher) package, which provides a [PSR-14](https://www.php-fig.org/psr/psr-14/) compatible event dispatcher." -msgstr "" +msgstr "O Yii usa o [yiisoft/yii-event](https://github.com/yiisoft/yii-event) para a configuração de eventos da aplicação. Ele é construído sobre o pacote [yiisoft/event-dispatcher](https://github.com/yiisoft/event-dispatcher), que fornece um event dispatcher compatível com [PSR-14](https://www.php-fig.org/psr/psr-14/)." #. type: Title ## #: ../src/guide/concept/events.md #, no-wrap msgid "Event classes" -msgstr "" +msgstr "Classes de evento" #. type: Plain text #: ../src/guide/concept/events.md msgid "An event is an object. It usually contains data that listeners need:" -msgstr "" +msgstr "Um evento é um objeto. Normalmente ele contém os dados de que os listeners precisam:" #. type: Fenced code block (php) #: ../src/guide/concept/events.md @@ -65,17 +63,23 @@ msgid "" " ) {}\n" "}\n" msgstr "" +"final readonly class UserSignedUp\n" +"{\n" +" public function __construct(\n" +" public SignupForm $form,\n" +" ) {}\n" +"}\n" #. type: Title ## #: ../src/guide/concept/events.md #, no-wrap msgid "Event listeners" -msgstr "" +msgstr "Listeners de eventos" #. type: Plain text #: ../src/guide/concept/events.md msgid "An event listener is a [PHP callable](https://www.php.net/manual/en/language.types.callable.php) that receives an event:" -msgstr "" +msgstr "Um listener de evento é um [callable do PHP](https://www.php.net/manual/en/language.types.callable.php) que recebe um evento:" #. type: Fenced code block (php) #: ../src/guide/concept/events.md @@ -85,11 +89,14 @@ msgid "" " // Send a welcome email.\n" "}\n" msgstr "" +"static function (UserSignedUp $event): void {\n" +" // Envia um e-mail de boas-vindas.\n" +"}\n" #. type: Plain text #: ../src/guide/concept/events.md msgid "You can also use an invokable class:" -msgstr "" +msgstr "Você também pode usar uma classe invocável:" #. type: Fenced code block (php) #: ../src/guide/concept/events.md @@ -103,37 +110,44 @@ msgid "" " }\n" "}\n" msgstr "" +"final readonly class WelcomeEmailSender\n" +"{\n" +" public function __invoke(UserSignedUp $event): void\n" +" {\n" +" // Envia um e-mail de boas-vindas.\n" +" }\n" +"}\n" #. type: Title ## #: ../src/guide/concept/events.md #, no-wrap msgid "Configuring event listeners" -msgstr "" +msgstr "Configurando listeners de eventos" #. type: Plain text #: ../src/guide/concept/events.md msgid "In an application, configure listeners in:" -msgstr "" +msgstr "Em uma aplicação, configure os listeners em:" #. type: Bullet: '- ' #: ../src/guide/concept/events.md msgid "`config/events.php` for all application types." -msgstr "" +msgstr "`config/events.php` para todos os tipos de aplicação." #. type: Bullet: '- ' #: ../src/guide/concept/events.md msgid "`config/events-web.php` for web application events." -msgstr "" +msgstr "`config/events-web.php` para eventos da aplicação web." #. type: Bullet: '- ' #: ../src/guide/concept/events.md msgid "`config/events-console.php` for console application events." -msgstr "" +msgstr "`config/events-console.php` para eventos da aplicação de console." #. type: Plain text #: ../src/guide/concept/events.md msgid "The configuration is an array where keys are event class names and values are lists of listeners:" -msgstr "" +msgstr "A configuração é um array em que as chaves são os nomes das classes de evento e os valores são listas de listeners:" #. type: Fenced code block (php) #: ../src/guide/concept/events.md @@ -154,27 +168,41 @@ msgid "" " ],\n" "];\n" msgstr "" +" [\n" +" WelcomeEmailSender::class,\n" +" static fn (UserSignedUp $event, AvatarProcessor $avatarProcessor) => $avatarProcessor->resize($event->form),\n" +" ],\n" +"];\n" #. type: Plain text #: ../src/guide/concept/events.md msgid "The listener may be a closure, a callable array, an invokable object, an invokable class name, or a DI alias. For closure and callable array listeners, parameters after the first event parameter are resolved from the DI container. Invokable class names are instantiated by the container." -msgstr "" +msgstr "O listener pode ser uma closure, um array callable, um objeto invocável, o nome de uma classe invocável ou um alias de DI. Para listeners do tipo closure e array callable, os parâmetros depois do primeiro (o evento) são resolvidos pelo container de DI. Nomes de classes invocáveis são instanciados pelo container." #. type: Plain text #: ../src/guide/concept/events.md msgid "Dependencies are resolved when the event is dispatched." -msgstr "" +msgstr "As dependências são resolvidas quando o evento é disparado." #. type: Title ## #: ../src/guide/concept/events.md #, no-wrap msgid "Dispatching events" -msgstr "" +msgstr "Disparando eventos" #. type: Plain text #: ../src/guide/concept/events.md msgid "To dispatch an event, use `Psr\\EventDispatcher\\EventDispatcherInterface`:" -msgstr "" +msgstr "Para disparar um evento, use `Psr\\EventDispatcher\\EventDispatcherInterface`:" #. type: Fenced code block (php) #: ../src/guide/concept/events.md @@ -196,38 +224,53 @@ msgid "" " }\n" "}\n" msgstr "" +"use Psr\\EventDispatcher\\EventDispatcherInterface;\n" +"\n" +"final readonly class SignupService\n" +"{\n" +" public function __construct(\n" +" private EventDispatcherInterface $eventDispatcher,\n" +" ) {}\n" +"\n" +" public function signup(SignupForm $form): void\n" +" {\n" +" // Cadastra o usuário.\n" +"\n" +" $this->eventDispatcher->dispatch(new UserSignedUp($form));\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/concept/events.md msgid "The dispatcher asks a listener provider for listeners that match the event and calls them one by one." -msgstr "" +msgstr "O dispatcher pede a um listener provider os listeners que correspondem ao evento e os chama um por um." #. type: Title ## #: ../src/guide/concept/events.md #, no-wrap msgid "Event listener order" -msgstr "" +msgstr "Ordem dos listeners" #. type: Plain text #: ../src/guide/concept/events.md msgid "When several listeners are configured for the same event, they are called in the order they are listed in the config. If an event implements `Psr\\EventDispatcher\\StoppableEventInterface`, the dispatcher checks `isPropagationStopped()` before calling the next listener. When it returns `true`, the dispatcher stops processing the event." -msgstr "" +msgstr "Quando vários listeners são configurados para o mesmo evento, eles são chamados na ordem em que aparecem na configuração. Se um evento implementa `Psr\\EventDispatcher\\StoppableEventInterface`, o dispatcher verifica `isPropagationStopped()` antes de chamar o próximo listener. Quando ele retorna `true`, o dispatcher para de processar o evento." #. type: Plain text #: ../src/guide/concept/events.md msgid "Keep listeners independent where possible. Ordering is useful for technical needs, but business logic is usually easier to maintain when each listener can run on its own." -msgstr "" +msgstr "Mantenha os listeners independentes sempre que possível. A ordem é útil para necessidades técnicas, mas a lógica de negócio costuma ser mais fácil de manter quando cada listener consegue rodar sozinho." #. type: Title ## #: ../src/guide/concept/events.md #, no-wrap msgid "Event hierarchy" -msgstr "" +msgstr "Hierarquia de eventos" #. type: Plain text #: ../src/guide/concept/events.md msgid "Events don't have names or wildcard matching. Event class names, interfaces, and inheritance can be used when one listener should handle several related events:" -msgstr "" +msgstr "Eventos não têm nomes nem correspondência por curinga. Nomes de classes de evento, interfaces e herança podem ser usados quando um listener precisa tratar vários eventos relacionados:" #. type: Fenced code block (php) #: ../src/guide/concept/events.md @@ -245,11 +288,22 @@ msgid "" "{\n" "}\n" msgstr "" +"interface DocumentEvent\n" +"{\n" +"}\n" +"\n" +"final readonly class BeforeDocumentProcessed implements DocumentEvent\n" +"{\n" +"}\n" +"\n" +"final readonly class AfterDocumentProcessed implements DocumentEvent\n" +"{\n" +"}\n" #. type: Plain text #: ../src/guide/concept/events.md msgid "With the interface, you can listen to all document-related events:" -msgstr "" +msgstr "Com a interface, você pode escutar todos os eventos relacionados a documentos:" #. type: Fenced code block (php) #: ../src/guide/concept/events.md @@ -265,17 +319,26 @@ msgid "" "\n" "$provider = new Provider($listeners);\n" msgstr "" +"use Yiisoft\\EventDispatcher\\Provider\\ListenerCollection;\n" +"use Yiisoft\\EventDispatcher\\Provider\\Provider;\n" +"\n" +"$listeners = (new ListenerCollection())\n" +" ->add(static function (DocumentEvent $event): void {\n" +" // Registra em log os eventos de documentos.\n" +" });\n" +"\n" +"$provider = new Provider($listeners);\n" #. type: Title ## #: ../src/guide/concept/events.md #, no-wrap msgid "Manual listener provider setup" -msgstr "" +msgstr "Configuração manual do listener provider" #. type: Plain text #: ../src/guide/concept/events.md msgid "In an application, use event configuration. For package-level code or tests, you can create a listener provider manually:" -msgstr "" +msgstr "Em uma aplicação, use a configuração de eventos. Para código de pacotes ou testes, você pode criar um listener provider manualmente:" #. type: Fenced code block (php) #: ../src/guide/concept/events.md @@ -295,12 +358,25 @@ msgid "" "\n" "$dispatcher->dispatch(new UserSignedUp($form));\n" msgstr "" +"use Yiisoft\\EventDispatcher\\Dispatcher\\Dispatcher;\n" +"use Yiisoft\\EventDispatcher\\Provider\\ListenerCollection;\n" +"use Yiisoft\\EventDispatcher\\Provider\\Provider;\n" +"\n" +"$listeners = (new ListenerCollection())\n" +" ->add(static function (UserSignedUp $event): void {\n" +" // Envia um e-mail de boas-vindas.\n" +" });\n" +"\n" +"$provider = new Provider($listeners);\n" +"$dispatcher = new Dispatcher($provider);\n" +"\n" +"$dispatcher->dispatch(new UserSignedUp($form));\n" #. type: Plain text #: ../src/guide/concept/events.md #, no-wrap msgid "`ListenerCollection::add()` returns a new collection instance. Assign the result when building a collection step by step:\n" -msgstr "" +msgstr "`ListenerCollection::add()` retorna uma nova instância da coleção. Atribua o resultado ao montar uma coleção passo a passo:\n" #. type: Fenced code block (php) #: ../src/guide/concept/events.md @@ -314,3 +390,10 @@ msgid "" " UserSignedUp::class,\n" ");\n" msgstr "" +"$listeners = new ListenerCollection();\n" +"$listeners = $listeners->add(\n" +" static function (UserSignedUp $event): void {\n" +" // Envia um e-mail de boas-vindas.\n" +" },\n" +" UserSignedUp::class,\n" +");\n" diff --git a/_translations/po/pt-BR/guide_concept_immutability.md.po b/_translations/po/pt-BR/guide_concept_immutability.md.po index b4c27343..f65ddfee 100644 --- a/_translations/po/pt-BR/guide_concept_immutability.md.po +++ b/_translations/po/pt-BR/guide_concept_immutability.md.po @@ -8,30 +8,29 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2025-12-24 08:02+0000\n" "PO-Revision-Date: 2025-12-24 08:02+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/en/guide/concept/immutability.md ../src/en/internals/017-tags.md -#: ../src/en/internals/018-widgets.md +#: ../src/en/guide/concept/immutability.md ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md #, no-wrap msgid "Immutability" -msgstr "" +msgstr "Imutabilidade" #. type: Plain text #: ../src/en/guide/concept/immutability.md msgid "Immutability means an object's state cannot change after it has been created. Instead of modifying an instance, you create a new instance with the desired changes. This approach is common for value objects such as Money, IDs, and DTOs. It helps to avoid accidental side effects: methods cannot silently change shared state, which makes code easier to reason about." -msgstr "" +msgstr "Imutabilidade significa que o estado de um objeto não pode mudar depois que ele é criado. Em vez de modificar uma instância, você cria uma nova instância com as mudanças desejadas. Essa abordagem é comum em value objects como Money, IDs e DTOs. Ela ajuda a evitar efeitos colaterais acidentais: os métodos não conseguem alterar silenciosamente um estado compartilhado, o que torna o código mais fácil de entender." #. type: Title ## #: ../src/en/guide/concept/immutability.md #, no-wrap msgid "Mutable pitfalls (what we avoid)" -msgstr "" +msgstr "Armadilhas da mutabilidade (o que evitamos)" #. type: Fenced code block (php) #: ../src/en/guide/concept/immutability.md @@ -47,17 +46,26 @@ msgid "" "$list = $base->orderBy(['created_at' => SORT_DESC])->all();\n" "// Oops: still limited to 1 because the previous limit(1) modified $base.\n" msgstr "" +"// Uma query base compartilhada, montada uma vez e reutilizada:\n" +"$base = Post::find()->where(['status' => Post::STATUS_PUBLISHED]);\n" +"\n" +"// Em algum lugar profundo do código, precisamos de um só post:\n" +"$one = $base->limit(1)->one(); // altera o builder subjacente (o limit fica grudado!)\n" +"\n" +"// Depois reutilizamos o mesmo $base esperando a lista completa:\n" +"$list = $base->orderBy(['created_at' => SORT_DESC])->all();\n" +"// Ops: continua limitado a 1, porque o limit(1) anterior modificou $base.\n" #. type: Title ## #: ../src/en/guide/concept/immutability.md #, no-wrap msgid "Creating an immutable object in PHP" -msgstr "" +msgstr "Criando um objeto imutável em PHP" #. type: Plain text #: ../src/en/guide/concept/immutability.md msgid "There is no direct way to modify an instance, but you can use clone to create a new instance with the desired changes. That is what `with*` methods do." -msgstr "" +msgstr "Não há como modificar uma instância diretamente, mas você pode usar clone para criar uma nova instância com as mudanças desejadas. É isso que os métodos `with*` fazem." #. type: Fenced code block (php) #: ../src/en/guide/concept/immutability.md @@ -136,16 +144,88 @@ msgid "" "$discounted = $price->withAmount(800);\n" "// $price is still 1000 USD, $discounted is 800 USD\n" msgstr "" +"final class Money\n" +"{\n" +" public function __construct(\n" +" private int $amount,\n" +" private string $currency,\n" +" ) {\n" +" $this->validateAmount($amount);\n" +" $this->validateCurrency($currency);\n" +" }\n" +" \n" +" private function validateAmount(string $amount) \n" +" {\n" +" if ($amount < 0) {\n" +" throw new InvalidArgumentException('Amount must be positive.');\n" +" }\n" +" }\n" +" \n" +" private function validateCurrency(string $currency)\n" +" {\n" +" if (!in_array($currency, ['USD', 'EUR'])) {\n" +" throw new InvalidArgumentException('Invalid currency. Only USD and EUR are supported.');\n" +" }\n" +" } \n" +"\n" +" public function withAmount(int $amount): self\n" +" {\n" +" $this->validateAmount($amount);\n" +" \n" +" if ($amount === $this->amount) {\n" +" return $this;\n" +" }\n" +" \n" +" $clone = clone $this;\n" +" $clone->amount = $amount;\n" +" return $clone;\n" +" }\n" +" \n" +" public function withCurrency(string $currency): self\n" +" {\n" +" $this->validateCurrency($currency);\n" +" \n" +" if ($currency === $this->currency) {\n" +" return $this;\n" +" }\n" +" \n" +" $clone = clone $this;\n" +" $clone->currency = $currency;\n" +" return $clone;\n" +" }\n" +" \n" +" public function amount(): int \n" +" {\n" +" return $this->amount;\n" +" }\n" +" \n" +" public function currency(): string \n" +" {\n" +" return $this->currency;\n" +" }\n" +"\n" +" public function add(self $money): self\n" +" {\n" +" if ($money->currency !== $this->currency) {\n" +" throw new InvalidArgumentException('Currency mismatch. Cannot add money of different currency.');\n" +" }\n" +" return $this->withAmount($this->amount + $money->amount);\n" +" }\n" +"}\n" +"\n" +"$price = new Money(1000, 'USD');\n" +"$discounted = $price->withAmount(800);\n" +"// $price continua 1000 USD, $discounted é 800 USD\n" #. type: Bullet: '- ' #: ../src/en/guide/concept/immutability.md msgid "We mark the class `final` to prevent subclass mutations; alternatively, design for extension carefully." -msgstr "" +msgstr "Marcamos a classe como `final` para impedir mutações por subclasses; como alternativa, projete a extensão com cuidado." #. type: Bullet: '- ' #: ../src/en/guide/concept/immutability.md msgid "Validate in the constructor and `with*` methods so every instance is always valid." -msgstr "" +msgstr "Valide no construtor e nos métodos `with*`, para que toda instância seja sempre válida." #. type: Plain text #: ../src/en/guide/concept/immutability.md @@ -155,22 +235,25 @@ msgid "" "> If you define a simple DTO, you can use modern PHP `readonly` and leave properties `public`. The `readonly` keyword\n" "> would ensure that the properties cannot be modified after the object is created.\n" msgstr "" +"> [!TIP]\n" +"> Se você define um DTO simples, pode usar o `readonly` do PHP moderno e deixar as propriedades `public`. A palavra-chave `readonly`\n" +"> garante que as propriedades não possam ser modificadas depois que o objeto é criado.\n" #. type: Title ## #: ../src/en/guide/concept/immutability.md #, no-wrap msgid "Using clone (and why it is inexpensive)" -msgstr "" +msgstr "Usando clone (e por que é barato)" #. type: Plain text #: ../src/en/guide/concept/immutability.md msgid "PHP's clone performs a shallow copy of the object. For immutable value objects that contain only scalars or other immutable objects, shallow cloning is enough and fast. In modern PHP, cloning small value objects is inexpensive in both time and memory." -msgstr "" +msgstr "O clone do PHP faz uma cópia rasa do objeto. Para value objects imutáveis que contêm apenas escalares ou outros objetos imutáveis, a clonagem rasa é suficiente e rápida. No PHP moderno, clonar value objects pequenos é barato em tempo e em memória." #. type: Plain text #: ../src/en/guide/concept/immutability.md msgid "If your object holds mutable sub-objects that must also be copied, implement `__clone` to deep-clone them:" -msgstr "" +msgstr "Se o seu objeto guarda subobjetos mutáveis que também precisam ser copiados, implemente `__clone` para fazer a clonagem profunda deles:" #. type: Fenced code block (php) #: ../src/en/guide/concept/immutability.md @@ -201,24 +284,48 @@ msgid "" " }\n" "}\n" msgstr "" +"final class Order\n" +"{\n" +" public function __construct(\n" +" private Money $total\n" +" ) {}\n" +" \n" +" public function total(): Money \n" +" {\n" +" return $this->total;\n" +" }\n" +"\n" +" public function __clone(): void\n" +" {\n" +" // Money é imutável no nosso exemplo, então a clonagem profunda não é necessária.\n" +" // Se fosse mutável, você poderia fazer: $this->total = clone $this->total;\n" +" }\n" +"\n" +" public function withTotal(Money $total): self\n" +" {\n" +" $clone = clone $this;\n" +" $clone->total = $total;\n" +" return $clone;\n" +" }\n" +"}\n" #. type: Title ## #: ../src/en/guide/concept/immutability.md #, no-wrap msgid "Usage style" -msgstr "" +msgstr "Estilo de uso" #. type: Bullet: '- ' #: ../src/en/guide/concept/immutability.md msgid "Build a value object once and pass it around. If you need a change, use a `with*` method that returns a new instance." -msgstr "" +msgstr "Crie um value object uma vez e passe-o adiante. Se precisar de uma mudança, use um método `with*` que retorna uma nova instância." #. type: Bullet: '- ' #: ../src/en/guide/concept/immutability.md msgid "Prefer scalar/immutable fields inside immutable objects; if a field can mutate, isolate it and deep-clone in `__clone` when needed." -msgstr "" +msgstr "Prefira campos escalares/imutáveis dentro de objetos imutáveis; se um campo puder mudar, isole-o e faça a clonagem profunda em `__clone` quando necessário." #. type: Plain text #: ../src/en/guide/concept/immutability.md msgid "Immutability aligns well with Yii's preference for predictable, side-effect-free code and makes services, caching, and configuration more robust." -msgstr "" +msgstr "A imutabilidade combina bem com a preferência do Yii por código previsível e sem efeitos colaterais, e torna serviços, cache e configuração mais robustos." diff --git a/_translations/po/pt-BR/guide_structure_action.md.po b/_translations/po/pt-BR/guide_structure_action.md.po index de56aaf2..5c0c5efb 100644 --- a/_translations/po/pt-BR/guide_structure_action.md.po +++ b/_translations/po/pt-BR/guide_structure_action.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-05-05 21:53+0000\n" "PO-Revision-Date: 2026-05-05 21:53+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,17 +19,17 @@ msgstr "" #: ../src/guide/intro/upgrade-from-v2.md ../src/guide/structure/action.md #, no-wrap msgid "Actions" -msgstr "" +msgstr "Actions" #. type: Plain text #: ../src/guide/structure/action.md msgid "In a web application, the request URL determines what's executed. Matching is made by a router configured with multiple routes. Each route can be attached to a middleware that, given request, produces a response. Since middleware overall could be chained and can pass actual handling to the next middleware, we call the middleware actually doing the job an action." -msgstr "" +msgstr "Em uma aplicação web, a URL da requisição determina o que é executado. A correspondência é feita por um router configurado com várias rotas. Cada rota pode ser associada a um middleware que, dada a requisição, produz uma resposta. Como os middlewares podem ser encadeados e podem passar o tratamento efetivo para o próximo middleware, chamamos de action o middleware que realmente faz o trabalho." #. type: Plain text #: ../src/guide/structure/action.md msgid "There are multiple ways to describe an action. The simplest one is using a closure:" -msgstr "" +msgstr "Há várias formas de descrever uma action. A mais simples é usando uma closure:" #. type: Fenced code block (php) #: ../src/guide/structure/action.md @@ -45,11 +45,20 @@ msgid "" " return $response;\n" "});\n" msgstr "" +"use \\Psr\\Http\\Message\\ServerRequestInterface;\n" +"use \\Psr\\Http\\Message\\ResponseInterface;\n" +"use Yiisoft\\Router\\Route;\n" +"\n" +"Route::get('/')->action(function (ServerRequestInterface $request) use ($responseFactory): ResponseInterface {\n" +" $response = $responseFactory->createResponse();\n" +" $response->getBody()->write('You are at homepage.');\n" +" return $response;\n" +"});\n" #. type: Plain text #: ../src/guide/structure/action.md msgid "It's fine for simple handling since any more complicated one would require getting dependencies, so a good idea would be moving the handling to a class method. Callback middleware could be used for the purpose:" -msgstr "" +msgstr "Isso funciona bem para um tratamento simples, já que qualquer coisa mais complicada exigiria obter dependências; então, uma boa ideia é mover o tratamento para um método de classe. Um middleware de callback pode ser usado para isso:" #. type: Fenced code block (php) #: ../src/guide/structure/action.md @@ -59,11 +68,14 @@ msgid "" "\n" "Route::get('/')->action(FrontPageAction::class),\n" msgstr "" +"use Yiisoft\\Router\\Route;\n" +"\n" +"Route::get('/')->action(FrontPageAction::class),\n" #. type: Plain text #: ../src/guide/structure/action.md msgid "The class itself would be like:" -msgstr "" +msgstr "A classe em si seria assim:" #. type: Fenced code block (php) #: ../src/guide/structure/action.md @@ -80,11 +92,21 @@ msgid "" " }\n" "}\n" msgstr "" +"use \\Psr\\Http\\Message\\ServerRequestInterface;\n" +"use \\Psr\\Http\\Message\\ResponseInterface;\n" +"\n" +"final readonly class FrontPageAction\n" +"{\n" +" public function __invoke(ServerRequestInterface $request): ResponseInterface\n" +" {\n" +" // monta a resposta para a página inicial \n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/structure/action.md msgid "For many cases, it makes sense to group handling for many routes into a single class:" -msgstr "" +msgstr "Em muitos casos, faz sentido agrupar o tratamento de várias rotas em uma única classe:" #. type: Fenced code block (php) #: ../src/guide/structure/action.md @@ -95,11 +117,15 @@ msgid "" "Route::get('/post/index')->action([PostController::class, 'actionIndex']),\n" "Route::get('/post/view/{id:\\d+}')->action([PostController::class, 'actionView']),\n" msgstr "" +"use Yiisoft\\Router\\Route;\n" +"\n" +"Route::get('/post/index')->action([PostController::class, 'actionIndex']),\n" +"Route::get('/post/view/{id:\\d+}')->action([PostController::class, 'actionView']),\n" #. type: Plain text #: ../src/guide/structure/action.md msgid "The class itself would look like the following:" -msgstr "" +msgstr "A classe em si ficaria assim:" #. type: Fenced code block (php) #: ../src/guide/structure/action.md @@ -127,22 +153,43 @@ msgid "" " }\n" "}\n" msgstr "" +"use \\Psr\\Http\\Message\\ServerRequestInterface;\n" +"use \\Psr\\Http\\Message\\ResponseInterface;\n" +"use Yiisoft\\Router\\HydratorAttribute\\RouteArgument;\n" +"\n" +"final readonly class PostController\n" +"{\n" +" public function actionIndex(ServerRequestInterface $request): ResponseInterface\n" +" {\n" +" // renderiza a lista de posts\n" +" }\n" +" \n" +" \n" +" public function actionView(\n" +" ServerRequestInterface $request,\n" +" #[RouteArgument('id')]\n" +" int $id,\n" +" ): ResponseInterface\n" +" {\n" +" // renderiza um único post pelo $id\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/structure/action.md msgid "We usually call such a class \"controller.\"" -msgstr "" +msgstr "Normalmente chamamos uma classe assim de \"controller\"." #. type: Plain text #: ../src/guide/structure/action.md msgid "The `{id}` part of the `/post/view/{id:\\d+}` route is a named route parameter. Route parameters are available from `Yiisoft\\Router\\CurrentRoute`. To receive one as an action argument, add the `RouteArgument` attribute to the corresponding parameter. The attribute name should match the route parameter name." -msgstr "" +msgstr "A parte `{id}` da rota `/post/view/{id:\\d+}` é um parâmetro de rota nomeado. Os parâmetros de rota estão disponíveis em `Yiisoft\\Router\\CurrentRoute`. Para recebê-lo como argumento da action, adicione o atributo `RouteArgument` ao parâmetro correspondente. O nome no atributo deve corresponder ao nome do parâmetro de rota." #. type: Title ## #: ../src/guide/structure/action.md #, no-wrap msgid "Autowiring" -msgstr "" +msgstr "Autowiring" #. type: Plain text #: ../src/guide/structure/action.md @@ -151,6 +198,8 @@ msgid "" "Both constructors of action-classes and action-methods are automatically getting services from\n" " the dependency injection container:\n" msgstr "" +"Tanto os construtores das classes de action quanto os métodos de action recebem automaticamente serviços do\n" +" container de injeção de dependência:\n" #. type: Fenced code block (php) #: ../src/guide/structure/action.md @@ -181,8 +230,32 @@ msgid "" " }\n" "}\n" msgstr "" +"use \\Psr\\Http\\Message\\ServerRequestInterface;\n" +"use \\Psr\\Http\\Message\\ResponseInterface;\n" +"use Psr\\Log\\LoggerInterface;\n" +"\n" +"final readonly class PostController\n" +"{\n" +" public function __construct(\n" +" private PostRepository $postRepository\n" +" )\n" +" {\n" +" }\n" +"\n" +" public function actionIndex(ServerRequestInterface $request, LoggerInterface $logger): ResponseInterface\n" +" {\n" +" $logger->debug('Rendering posts list');\n" +" // renderiza a lista de posts\n" +" }\n" +" \n" +" \n" +" public function actionView(ServerRequestInterface $request): ResponseInterface\n" +" {\n" +" // renderiza um único post \n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/structure/action.md msgid "In the above example `PostRepository` is injected automatically via constructor. That means it is available in every action. Logger is injected into `index` action only." -msgstr "" +msgstr "No exemplo acima, `PostRepository` é injetado automaticamente pelo construtor. Isso significa que ele fica disponível em todas as actions. O logger é injetado apenas na action `index`." diff --git a/_translations/po/pt-BR/guide_structure_application.md.po b/_translations/po/pt-BR/guide_structure_application.md.po index 5d222613..ba8a1c44 100644 --- a/_translations/po/pt-BR/guide_structure_application.md.po +++ b/_translations/po/pt-BR/guide_structure_application.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2025-12-27 03:24+0000\n" "PO-Revision-Date: 2025-12-27 03:24+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,29 +19,29 @@ msgstr "" #: ../src/guide/structure/application.md #, no-wrap msgid "Application" -msgstr "" +msgstr "Aplicação" #. type: Plain text #: ../src/guide/structure/application.md msgid "The primary purpose of the web application and its runner in Yii3 is to process requests to get responses." -msgstr "" +msgstr "O principal propósito da aplicação web e do seu runner no Yii3 é processar requisições para obter respostas." #. type: Plain text #: ../src/guide/structure/application.md msgid "Typically, the runtime consists of:" -msgstr "" +msgstr "Normalmente, o ciclo de execução consiste em:" #. type: Bullet: '1. ' #: ../src/guide/structure/application.md msgid "Startup. Get config, create an instance of container and do additional environment initialization such as registering error handler, so it can handle errors occurring. Fire `ApplicationStartup` event." -msgstr "" +msgstr "Inicialização. Obter a configuração, criar uma instância do container e fazer a inicialização adicional do ambiente, como registrar o error handler para que ele possa tratar os erros que ocorrerem. Disparar o evento `ApplicationStartup`." #. type: Bullet: '2. ' #: ../src/guide/structure/application.md msgid "Handle requests via passing request objects to middleware dispatcher to execute [middleware stack](middleware.md) and get a response object. In usual PHP applications, it's done once. In [environments such as RoadRunner](../tutorial/using-with-event-loop.md), it could be done multiple times with the same application instance. Response object is converted into an actual HTTP response by using emitter. Fire `AfterEmit` event." -msgstr "" +msgstr "Tratar requisições passando os objetos de requisição para o dispatcher de middlewares, que executa a [pilha de middlewares](middleware.md) e obtém um objeto de resposta. Em aplicações PHP comuns, isso é feito uma vez. Em [ambientes como o RoadRunner](../tutorial/using-with-event-loop.md), pode ser feito várias vezes com a mesma instância da aplicação. O objeto de resposta é convertido em uma resposta HTTP real usando o emitter. Disparar o evento `AfterEmit`." #. type: Bullet: '3. ' #: ../src/guide/structure/application.md msgid "Shutdown. Fire `ApplicationShutdown` event." -msgstr "" +msgstr "Encerramento. Disparar o evento `ApplicationShutdown`." diff --git a/_translations/po/pt-BR/guide_structure_designing-packages.md.po b/_translations/po/pt-BR/guide_structure_designing-packages.md.po index a599a143..86c7d0b0 100644 --- a/_translations/po/pt-BR/guide_structure_designing-packages.md.po +++ b/_translations/po/pt-BR/guide_structure_designing-packages.md.po @@ -8,91 +8,80 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-06-02 22:29+0000\n" "PO-Revision-Date: 2026-06-02 22:29+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Fenced code block (sh) -#: ../src/cookbook/using-yii-in-third-party-apps.md -#: ../src/guide/structure/designing-packages.md -#: ../src/guide/structure/module.md ../src/guide/structure/package.md -#: ../src/guide/tutorial/i18n.md +#: ../src/cookbook/using-yii-in-third-party-apps.md ../src/guide/structure/designing-packages.md ../src/guide/structure/module.md ../src/guide/structure/package.md ../src/guide/tutorial/i18n.md #, no-wrap msgid "composer yii-config-rebuild\n" -msgstr "" +msgstr "composer yii-config-rebuild\n" #. type: Title ## -#: ../src/guide/concept/configuration.md -#: ../src/guide/structure/designing-packages.md -#: ../src/guide/structure/module.md +#: ../src/guide/concept/configuration.md ../src/guide/structure/designing-packages.md ../src/guide/structure/module.md #, no-wrap msgid "Routes" -msgstr "" +msgstr "Rotas" #. type: Title ## -#: ../src/guide/concept/configuration.md ../src/guide/concept/events.md -#: ../src/guide/structure/designing-packages.md -#: ../src/internals/022-config-groups.md +#: ../src/guide/concept/configuration.md ../src/guide/concept/events.md ../src/guide/structure/designing-packages.md ../src/internals/022-config-groups.md #, no-wrap msgid "Events" -msgstr "" +msgstr "Eventos" #. type: Title ## -#: ../src/guide/concept/configuration.md -#: ../src/guide/structure/designing-packages.md -#: ../src/internals/022-config-groups.md +#: ../src/guide/concept/configuration.md ../src/guide/structure/designing-packages.md ../src/internals/022-config-groups.md #, no-wrap msgid "Parameters" -msgstr "" +msgstr "Parâmetros" #. type: Title ## -#: ../src/guide/databases/db-migrations.md -#: ../src/guide/structure/designing-packages.md +#: ../src/guide/databases/db-migrations.md ../src/guide/structure/designing-packages.md #, no-wrap msgid "Migrations" -msgstr "" +msgstr "Migrations" #. type: Title ## -#: ../src/guide/intro/upgrade-from-v2.md -#: ../src/guide/structure/designing-packages.md +#: ../src/guide/intro/upgrade-from-v2.md ../src/guide/structure/designing-packages.md #, no-wrap msgid "Console commands" -msgstr "" +msgstr "Comandos de console" #. type: Title # #: ../src/guide/structure/designing-packages.md #, no-wrap msgid "Designing packages for Yii applications" -msgstr "" +msgstr "Projetando pacotes para aplicações Yii" #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "This page describes how to design a Composer package that adds behavior to a Yii application through configuration. Use it when your package needs to register services, routes, events, commands, assets, migrations, translations, or a theme." -msgstr "" +msgstr "Esta página descreve como projetar um pacote Composer que acrescenta comportamento a uma aplicação Yii por meio de configuração. Use-a quando o seu pacote precisar registrar serviços, rotas, eventos, comandos, assets, migrations, traduções ou um tema." #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "For installing and updating packages in an application, see [Using packages](package.md)." -msgstr "" +msgstr "Para instalar e atualizar pacotes em uma aplicação, veja [Usando pacotes](package.md)." #. type: Title ## #: ../src/guide/structure/designing-packages.md #, no-wrap msgid "Composer metadata" -msgstr "" +msgstr "Metadados do Composer" #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "Each package must have a `composer.json` file in its root directory. At minimum, define a package name, dependencies, autoloading, and Yii config metadata when the package integrates with a Yii application." -msgstr "" +msgstr "Todo pacote precisa ter um arquivo `composer.json` na pasta raiz. No mínimo, defina o nome do pacote, as dependências, o autoload e os metadados de configuração do Yii quando o pacote se integra a uma aplicação Yii." #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "Use a package name in the `vendor-name/project-name` format:" -msgstr "" +msgstr "Use um nome de pacote no formato `vendor-name/project-name`:" #. type: Fenced code block (json) #: ../src/guide/structure/designing-packages.md @@ -113,27 +102,41 @@ msgid "" " }\n" "}\n" msgstr "" +"{\n" +" \"name\": \"vendor/blog\",\n" +" \"type\": \"library\",\n" +" \"description\": \"Blog integration for Yii applications\",\n" +" \"require\": {\n" +" \"php\": \">=8.2\",\n" +" \"yiisoft/router\": \"^4.0\"\n" +" },\n" +" \"autoload\": {\n" +" \"psr-4\": {\n" +" \"Vendor\\\\Blog\\\\\": \"src/\"\n" +" }\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "Use stable dependency constraints for stable releases. Avoid using `yiisoft` as your vendor name because it is reserved for Yii packages." -msgstr "" +msgstr "Use restrições de dependência estáveis em releases estáveis. Evite usar `yiisoft` como nome de vendor, porque ele é reservado para os pacotes do Yii." #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "If your package requires a Yii application, prefixing the project name with `yii-` can make that clear on Packagist." -msgstr "" +msgstr "Se o seu pacote exige uma aplicação Yii, prefixar o nome do projeto com `yii-` pode deixar isso claro no Packagist." #. type: Title ## #: ../src/guide/structure/designing-packages.md #, no-wrap msgid "Package layout" -msgstr "" +msgstr "Estrutura do pacote" #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "A Yii-aware package is a regular Composer package with PHP classes, optional resource files, and optional config files. Keep the configuration in a predictable directory and make the public API explicit:" -msgstr "" +msgstr "Um pacote compatível com o Yii é um pacote Composer comum, com classes PHP, arquivos de recursos opcionais e arquivos de configuração opcionais. Mantenha a configuração em uma pasta previsível e deixe a API pública explícita:" #. type: Fenced code block #: ../src/guide/structure/designing-packages.md @@ -160,22 +163,42 @@ msgid "" "views/\n" " ...\n" msgstr "" +"composer.json\n" +"config/\n" +" params.php\n" +" di.php\n" +" di-providers.php\n" +" routes.php\n" +" events.php\n" +" params-web.php\n" +" params-console.php\n" +" di-console.php\n" +"src/\n" +" ...\n" +"assets/\n" +" ...\n" +"migrations/\n" +" ...\n" +"messages/\n" +" ...\n" +"views/\n" +" ...\n" #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "Use only the files your package needs. For example, a package with console commands but no web routes does not need `routes.php`." -msgstr "" +msgstr "Use apenas os arquivos de que o seu pacote precisa. Por exemplo, um pacote com comandos de console, mas sem rotas web, não precisa de `routes.php`." #. type: Title ## #: ../src/guide/structure/designing-packages.md #, no-wrap msgid "Config plugin metadata" -msgstr "" +msgstr "Metadados do plugin de configuração" #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "Yii applications use [yiisoft/config](https://github.com/yiisoft/config) to discover package configuration. Declare package config files in the `extra.config-plugin` section of `composer.json`:" -msgstr "" +msgstr "Aplicações Yii usam o [yiisoft/config](https://github.com/yiisoft/config) para descobrir a configuração dos pacotes. Declare os arquivos de configuração do pacote na seção `extra.config-plugin` do `composer.json`:" #. type: Fenced code block (json) #: ../src/guide/structure/designing-packages.md @@ -203,46 +226,67 @@ msgid "" " }\n" "}\n" msgstr "" +"{\n" +" \"name\": \"vendor/blog\",\n" +" \"type\": \"library\",\n" +" \"autoload\": {\n" +" \"psr-4\": {\n" +" \"Vendor\\\\Blog\\\\\": \"src/\"\n" +" }\n" +" },\n" +" \"extra\": {\n" +" \"config-plugin\": {\n" +" \"params\": \"config/params.php\",\n" +" \"di\": \"config/di.php\",\n" +" \"di-providers\": \"config/di-providers.php\",\n" +" \"routes\": \"config/routes.php\",\n" +" \"events\": \"config/events.php\",\n" +" \"params-web\": \"config/params-web.php\",\n" +" \"params-console\": \"config/params-console.php\",\n" +" \"di-console\": \"config/di-console.php\"\n" +" }\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "Each `config-plugin` key is a config group name and each value is a path relative to the package root." -msgstr "" +msgstr "Cada chave de `config-plugin` é o nome de um grupo de configuração, e cada valor é um caminho relativo à raiz do pacote." #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "Use the common, web, and console groups consistently:" -msgstr "" +msgstr "Use os grupos comuns, web e de console de forma consistente:" #. type: Bullet: '- ' #: ../src/guide/structure/designing-packages.md msgid "`params`, `di`, `di-providers`, `di-delegates`, `events`, and `bootstrap` apply to both web and console entry points." -msgstr "" +msgstr "`params`, `di`, `di-providers`, `di-delegates`, `events` e `bootstrap` valem para os pontos de entrada web e de console." #. type: Bullet: '- ' #: ../src/guide/structure/designing-packages.md msgid "`params-web`, `di-web`, `di-providers-web`, `events-web`, `bootstrap-web`, and `routes` apply to web entry points." -msgstr "" +msgstr "`params-web`, `di-web`, `di-providers-web`, `events-web`, `bootstrap-web` e `routes` valem para os pontos de entrada web." #. type: Bullet: '- ' #: ../src/guide/structure/designing-packages.md msgid "`params-console`, `di-console`, `di-providers-console`, `events-console`, and `bootstrap-console` apply to console entry points." -msgstr "" +msgstr "`params-console`, `di-console`, `di-providers-console`, `events-console` e `bootstrap-console` valem para os pontos de entrada de console." #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "If your package defines a new config group, document how an application should load that group. Prefer the standard groups when you integrate with Yii services because application templates and Yii packages already use these names." -msgstr "" +msgstr "Se o seu pacote define um novo grupo de configuração, documente como a aplicação deve carregar esse grupo. Prefira os grupos padrão ao se integrar com serviços do Yii, porque os templates de aplicação e os pacotes do Yii já usam esses nomes." #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "After users install, update, remove, or dump Composer autoload files, the config plugin rebuilds the merge plan that Yii reads at runtime. If users edit their root package configuration manually, ask them to run:" -msgstr "" +msgstr "Depois que os usuários instalam, atualizam, removem ou fazem dump dos arquivos de autoload do Composer, o plugin de configuração reconstrói o merge plan que o Yii lê em tempo de execução. Se os usuários editarem manualmente a configuração do pacote raiz, peça que executem:" #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "Put default options in `config/params.php`. Group package parameters under the Composer package name to avoid collisions:" -msgstr "" +msgstr "Coloque as opções padrão em `config/params.php`. Agrupe os parâmetros do pacote sob o nome do pacote no Composer para evitar colisões:" #. type: Fenced code block (php) #: ../src/guide/structure/designing-packages.md @@ -259,27 +303,37 @@ msgid "" " ],\n" "];\n" msgstr "" +" [\n" +" 'postsPerPage' => 20,\n" +" 'cacheTtl' => 3600,\n" +" ],\n" +"];\n" #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "Application developers can override these values in their own `config/common/params.php`, `config/web/params.php`, `config/console/params.php`, or environment-specific parameter files." -msgstr "" +msgstr "Os desenvolvedores da aplicação podem sobrescrever esses valores nos próprios `config/common/params.php`, `config/web/params.php`, `config/console/params.php` ou nos arquivos de parâmetros específicos de cada ambiente." #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "Do not read environment variables or global state from package code when a parameter can express the choice. Use parameters to configure services through DI definitions or service providers." -msgstr "" +msgstr "Não leia variáveis de ambiente nem estado global no código do pacote quando um parâmetro puder expressar a escolha. Use parâmetros para configurar serviços por meio de definições de DI ou service providers." #. type: Title ## #: ../src/guide/structure/designing-packages.md #, no-wrap msgid "DI definitions" -msgstr "" +msgstr "Definições de DI" #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "Use `config/di.php`, `config/di-web.php`, or `config/di-console.php` for direct container definitions:" -msgstr "" +msgstr "Use `config/di.php`, `config/di-web.php` ou `config/di-console.php` para definições diretas do container:" #. type: Fenced code block (php) #: ../src/guide/structure/designing-packages.md @@ -303,27 +357,44 @@ msgid "" " ],\n" "];\n" msgstr "" +" [\n" +" 'class' => PostRepository::class,\n" +" '__construct()' => [\n" +" 'cacheTtl' => $params['vendor/blog']['cacheTtl'],\n" +" ],\n" +" ],\n" +"];\n" #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "Prefer direct DI definitions when the configuration describes one service clearly." -msgstr "" +msgstr "Prefira definições de DI diretas quando a configuração descreve um serviço de forma clara." #. type: Title ## #: ../src/guide/structure/designing-packages.md #, no-wrap msgid "DI service providers" -msgstr "" +msgstr "Service providers de DI" #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "Use a DI provider when registration belongs together as a reusable unit: several related services, aliases, factory definitions, or extensions." -msgstr "" +msgstr "Use um provider de DI quando o registro forma uma unidade reutilizável: vários serviços relacionados, aliases, definições de factory ou extensões." #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "Register providers in `config/di-providers.php`:" -msgstr "" +msgstr "Registre os providers em `config/di-providers.php`:" #. type: Fenced code block (php) #: ../src/guide/structure/designing-packages.md @@ -339,11 +410,20 @@ msgid "" " 'vendor/blog/post-repository' => BlogProvider::class,\n" "];\n" msgstr "" +" BlogProvider::class,\n" +"];\n" #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "Declare the group in `composer.json`:" -msgstr "" +msgstr "Declare o grupo no `composer.json`:" #. type: Fenced code block (json) #: ../src/guide/structure/designing-packages.md @@ -355,11 +435,16 @@ msgid "" " }\n" "}\n" msgstr "" +"\"extra\": {\n" +" \"config-plugin\": {\n" +" \"di-providers\": \"config/di-providers.php\"\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "A provider can return several service definitions and extensions. Place the provider class in `src/Provider/BlogProvider.php`:" -msgstr "" +msgstr "Um provider pode retornar várias definições de serviços e extensões. Coloque a classe do provider em `src/Provider/BlogProvider.php`:" #. type: Fenced code block (php) #: ../src/guide/structure/designing-packages.md @@ -399,11 +484,44 @@ msgid "" " }\n" "}\n" msgstr "" +" PostRepository::class,\n" +" PostRepositoryInterface::class => static fn (\n" +" ContainerInterface $container\n" +" ): CachedPostRepository => new CachedPostRepository(\n" +" $container->get(PostRepository::class),\n" +" $container->get(LoggerInterface::class),\n" +" ),\n" +" ];\n" +" }\n" +"\n" +" public function getExtensions(): array\n" +" {\n" +" return [];\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "Web packages can add routes through `config/routes.php`, declared as the `routes` group:" -msgstr "" +msgstr "Pacotes web podem adicionar rotas por meio de `config/routes.php`, declarado como o grupo `routes`:" #. type: Fenced code block (php) #: ../src/guide/structure/designing-packages.md @@ -425,21 +543,36 @@ msgid "" " ),\n" "];\n" msgstr "" +"routes(\n" +" Route::get('')\n" +" ->action(IndexAction::class)\n" +" ->name('vendor/blog/index'),\n" +" ),\n" +"];\n" #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "Route names should be package-prefixed. This avoids collisions with application routes and with routes from other packages." -msgstr "" +msgstr "Os nomes das rotas devem ter o prefixo do pacote. Isso evita colisões com as rotas da aplicação e com as rotas de outros pacotes." #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "Keep package routes small and overridable. If an application needs full control over URLs, document the actions and let the application define its own routes." -msgstr "" +msgstr "Mantenha as rotas do pacote pequenas e fáceis de sobrescrever. Se uma aplicação precisar de controle total sobre as URLs, documente as actions e deixe a aplicação definir as próprias rotas." #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "Use `config/events.php`, `config/events-web.php`, or `config/events-console.php` to attach package handlers to events:" -msgstr "" +msgstr "Use `config/events.php`, `config/events-web.php` ou `config/events-console.php` para associar handlers do pacote a eventos:" #. type: Fenced code block (php) #: ../src/guide/structure/designing-packages.md @@ -458,22 +591,34 @@ msgid "" " ],\n" "];\n" msgstr "" +" [\n" +" ClearPostListCache::class,\n" +" ],\n" +"];\n" #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "Handlers can be closures, callables, invokable objects, invokable class names, or DI aliases supported by the event dispatcher configuration. Prefer class names for package handlers because applications can override their dependencies through the container." -msgstr "" +msgstr "Os handlers podem ser closures, callables, objetos invocáveis, nomes de classes invocáveis ou aliases de DI suportados pela configuração do event dispatcher. Prefira nomes de classes para os handlers do pacote, porque as aplicações podem sobrescrever as dependências deles pelo container." #. type: Title # #: ../src/guide/structure/designing-packages.md ../src/guide/views/asset.md #, no-wrap msgid "Assets" -msgstr "" +msgstr "Assets" #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "If your package ships CSS, JavaScript, images, or fonts, define asset bundles as PHP classes. For example, place this class in `src/Asset/BlogAsset.php`:" -msgstr "" +msgstr "Se o seu pacote traz CSS, JavaScript, imagens ou fontes, defina asset bundles como classes PHP. Por exemplo, coloque esta classe em `src/Asset/BlogAsset.php`:" #. type: Fenced code block (php) #: ../src/guide/structure/designing-packages.md @@ -502,32 +647,54 @@ msgid "" " ];\n" "}\n" msgstr "" +"register(BlogAsset::class);\n" -msgstr "" +msgstr "$assetManager->register(BlogAsset::class);\n" #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "Use `$sourcePath` for files shipped inside the package. Use `$basePath` and `$baseUrl` as the public target where the asset manager publishes them." -msgstr "" +msgstr "Use `$sourcePath` para os arquivos que vêm dentro do pacote. Use `$basePath` e `$baseUrl` como o destino público onde o asset manager os publica." #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "Packages that need database schema changes should ship migrations and add their namespace or path to `yiisoft/db-migration` parameters." -msgstr "" +msgstr "Pacotes que precisam de mudanças no esquema do banco de dados devem trazer migrations e adicionar o namespace ou o caminho delas aos parâmetros do `yiisoft/db-migration`." #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "For namespaced migrations:" -msgstr "" +msgstr "Para migrations com namespace:" #. type: Fenced code block (php) #: ../src/guide/structure/designing-packages.md @@ -545,11 +712,22 @@ msgid "" " ],\n" "];\n" msgstr "" +" [\n" +" 'sourceNamespaces' => [\n" +" 'Vendor\\\\Blog\\\\Migration',\n" +" ],\n" +" ],\n" +"];\n" #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "For path-based migrations:" -msgstr "" +msgstr "Para migrations baseadas em caminho:" #. type: Fenced code block (php) #: ../src/guide/structure/designing-packages.md @@ -567,32 +745,43 @@ msgid "" " ],\n" "];\n" msgstr "" +" [\n" +" 'sourcePaths' => [\n" +" __DIR__ . '/../migrations',\n" +" ],\n" +" ],\n" +"];\n" #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "Put this in `config/params-console.php` and declare it as `params-console` in `composer.json`." -msgstr "" +msgstr "Coloque isso em `config/params-console.php` e declare-o como `params-console` no `composer.json`." #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "This only contributes package migration locations. The application still needs `yiisoft/db-migration` installed and a database connection configured before migration commands can run." -msgstr "" +msgstr "Isso apenas informa os locais das migrations do pacote. A aplicação ainda precisa ter o `yiisoft/db-migration` instalado e uma conexão com o banco de dados configurada antes que os comandos de migration possam rodar." #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "Package migrations must be stable after release. Do not edit a migration that users may already have applied. Add a new migration instead." -msgstr "" +msgstr "As migrations do pacote devem ficar estáveis depois do release. Não edite uma migration que os usuários talvez já tenham aplicado. Em vez disso, adicione uma nova migration." #. type: Title ## #: ../src/guide/structure/designing-packages.md #, no-wrap msgid "Translations" -msgstr "" +msgstr "Traduções" #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "If the package has user-facing messages, give it a dedicated translation category and register a category source in `config/di.php`:" -msgstr "" +msgstr "Se o pacote tem mensagens exibidas ao usuário, dê a ele uma categoria de tradução própria e registre uma category source em `config/di.php`:" #. type: Fenced code block (php) #: ../src/guide/structure/designing-packages.md @@ -622,11 +811,34 @@ msgid "" " ],\n" "];\n" msgstr "" +" [\n" +" 'definition' => static function (): CategorySource {\n" +" $messageSource = new MessageSource(__DIR__ . '/../messages');\n" +"\n" +" return new CategorySource(\n" +" 'vendor-blog',\n" +" $messageSource,\n" +" new IntlMessageFormatter(),\n" +" $messageSource,\n" +" );\n" +" },\n" +" 'tags' => ['translation.categorySource'],\n" +" ],\n" +"];\n" #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "Store messages by locale and category:" -msgstr "" +msgstr "Guarde as mensagens por locale e categoria:" #. type: Fenced code block #: ../src/guide/structure/designing-packages.md @@ -638,28 +850,33 @@ msgid "" " de/\n" " vendor-blog.php\n" msgstr "" +"messages/\n" +" en-US/\n" +" vendor-blog.php\n" +" de/\n" +" vendor-blog.php\n" #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "Use the explicit category when translating:" -msgstr "" +msgstr "Use a categoria explícita ao traduzir:" #. type: Fenced code block (php) #: ../src/guide/structure/designing-packages.md #, no-wrap msgid "$translator->translate('post.created', category: 'vendor-blog');\n" -msgstr "" +msgstr "$translator->translate('post.created', category: 'vendor-blog');\n" #. type: Title ## #: ../src/guide/structure/designing-packages.md #, no-wrap msgid "Themes" -msgstr "" +msgstr "Temas" #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "A package can ship view files and assets for a theme. Do not activate it from vendor package configuration. Instead, document the root application configuration needed to enable it. For the application template, this belongs in `config/web/params.php`:" -msgstr "" +msgstr "Um pacote pode trazer arquivos de view e assets para um tema. Não o ative pela configuração do pacote em vendor. Em vez disso, documente a configuração da aplicação raiz necessária para habilitá-lo. No template de aplicação, isso fica em `config/web/params.php`:" #. type: Fenced code block (php) #: ../src/guide/structure/designing-packages.md @@ -681,26 +898,41 @@ msgid "" " ],\n" "];\n" msgstr "" +" [\n" +" 'theme' => [\n" +" 'pathMap' => [\n" +" '@views' => '@vendor/vendor/blog/views',\n" +" ],\n" +" 'basePath' => '@vendor/vendor/blog/assets',\n" +" 'baseUrl' => '@assetsUrl/vendor-blog',\n" +" ],\n" +" ],\n" +"];\n" #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "Themes replace view paths according to a path map. Document which application view paths your theme replaces and which asset URL must be published or exposed by the application." -msgstr "" +msgstr "Os temas substituem caminhos de views de acordo com um mapa de caminhos. Documente quais caminhos de views da aplicação o seu tema substitui e qual URL de assets a aplicação precisa publicar ou expor." #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "Do not set `yiisoft/view.theme` directly in vendor package configuration. `yiisoft/view` already defines that key, and duplicate keys in the same configuration layer are not allowed." -msgstr "" +msgstr "Não defina `yiisoft/view.theme` diretamente na configuração do pacote em vendor. O `yiisoft/view` já define essa chave, e chaves duplicadas na mesma camada de configuração não são permitidas." #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "If your package only provides optional theme files, do not make the theme active by default. Provide the view files, asset bundle, and a documented parameter snippet so the application can opt in." -msgstr "" +msgstr "Se o seu pacote fornece apenas arquivos de tema opcionais, não deixe o tema ativo por padrão. Forneça os arquivos de view, o asset bundle e um trecho de parâmetros documentado, para que a aplicação possa optar por usá-lo." #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "Console packages can add Symfony Console commands through `config/params-console.php`:" -msgstr "" +msgstr "Pacotes de console podem adicionar comandos do Symfony Console por meio de `config/params-console.php`:" #. type: Fenced code block (php) #: ../src/guide/structure/designing-packages.md @@ -720,70 +952,83 @@ msgid "" " ],\n" "];\n" msgstr "" +" [\n" +" 'commands' => [\n" +" 'blog/reindex' => ReindexCommand::class,\n" +" ],\n" +" ],\n" +"];\n" #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "Command names should be package-prefixed. Keep command dependencies constructor-injected and registered through DI." -msgstr "" +msgstr "Os nomes dos comandos devem ter o prefixo do pacote. Mantenha as dependências dos comandos injetadas pelo construtor e registradas via DI." #. type: Title ## #: ../src/guide/structure/designing-packages.md #, no-wrap msgid "Application overrides" -msgstr "" +msgstr "Sobrescritas pela aplicação" #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "Package configuration is the default layer. The application can override it in its root package configuration. Design for that:" -msgstr "" +msgstr "A configuração do pacote é a camada padrão. A aplicação pode sobrescrevê-la na configuração do pacote raiz. Projete pensando nisso:" #. type: Bullet: '- ' #: ../src/guide/structure/designing-packages.md msgid "Use package-prefixed parameter keys, route names, event handler IDs, and DI aliases." -msgstr "" +msgstr "Use chaves de parâmetros, nomes de rotas, IDs de handlers de eventos e aliases de DI com o prefixo do pacote." #. type: Bullet: '- ' #: ../src/guide/structure/designing-packages.md msgid "Keep default configuration small and documented." -msgstr "" +msgstr "Mantenha a configuração padrão pequena e documentada." #. type: Bullet: '- ' #: ../src/guide/structure/designing-packages.md msgid "Avoid doing irreversible work during service registration." -msgstr "" +msgstr "Evite fazer trabalho irreversível durante o registro de serviços." #. type: Bullet: '- ' #: ../src/guide/structure/designing-packages.md msgid "Put optional integrations in separate config files or providers when they require optional Composer packages." -msgstr "" +msgstr "Coloque integrações opcionais em arquivos de configuração ou providers separados quando elas exigirem pacotes Composer opcionais." #. type: Bullet: '- ' #: ../src/guide/structure/designing-packages.md msgid "Test the package inside a minimal Yii application so the config plugin, DI container, routes, console commands, migrations, translations, and assets are exercised together." -msgstr "" +msgstr "Teste o pacote dentro de uma aplicação Yii mínima, para que o plugin de configuração, o container de DI, as rotas, os comandos de console, as migrations, as traduções e os assets sejam exercitados juntos." #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "When a user needs to customize package configuration, they usually do not need to copy the package config file. They can partially redefine the needed keys in the application configuration." -msgstr "" +msgstr "Quando um usuário precisa personalizar a configuração do pacote, normalmente não precisa copiar o arquivo de configuração do pacote. Ele pode redefinir parcialmente as chaves necessárias na configuração da aplicação." #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "After changing config group mappings, they should rebuild the merge plan with:" -msgstr "" +msgstr "Depois de alterar os mapeamentos de grupos de configuração, ele deve reconstruir o merge plan com:" #. type: Title ## #: ../src/guide/structure/designing-packages.md #, no-wrap msgid "Releasing packages" -msgstr "" +msgstr "Publicando pacotes" #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "Before tagging a release, test the package by itself and inside a minimal Yii application. Include a `README.md`, `CHANGELOG.md`, and `UPGRADE.md` when behavior or configuration changes require explanation." -msgstr "" +msgstr "Antes de criar a tag de um release, teste o pacote isoladamente e dentro de uma aplicação Yii mínima. Inclua `README.md`, `CHANGELOG.md` e `UPGRADE.md` quando mudanças de comportamento ou de configuração precisarem de explicação." #. type: Plain text #: ../src/guide/structure/designing-packages.md msgid "Use [semantic versioning](https://semver.org) for public releases. After the first release, do not edit migrations that users may already have applied; add new migrations instead." -msgstr "" +msgstr "Use [versionamento semântico](https://semver.org) nos releases públicos. Depois do primeiro release, não edite migrations que os usuários talvez já tenham aplicado; adicione novas migrations." diff --git a/_translations/po/pt-BR/guide_structure_entry-script.md.po b/_translations/po/pt-BR/guide_structure_entry-script.md.po index cee78c99..59b06479 100644 --- a/_translations/po/pt-BR/guide_structure_entry-script.md.po +++ b/_translations/po/pt-BR/guide_structure_entry-script.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-10-07 15:22+0000\n" "PO-Revision-Date: 2026-10-07 15:22+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,68 +19,68 @@ msgstr "" #: ../src/guide/structure/entry-script.md #, no-wrap msgid "Entry scripts" -msgstr "" +msgstr "Scripts de entrada" #. type: Plain text #: ../src/guide/structure/entry-script.md msgid "Entry scripts are the first step in the application bootstrapping process. An application (either Web application or console application) has a single entry script. End users make requests to entry scripts which instantiate application instances and forward the requests to them." -msgstr "" +msgstr "Os scripts de entrada são o primeiro passo no processo de inicialização da aplicação. Uma aplicação (seja web ou de console) tem um único script de entrada. Os usuários finais fazem requisições aos scripts de entrada, que instanciam a aplicação e encaminham as requisições para ela." #. type: Plain text #: ../src/guide/structure/entry-script.md msgid "Entry scripts for Web applications must be stored under Web-accessible directories so that they can be accessed by end users. They're often named as `index.php`, but can also use any other names, provided Web servers can locate them." -msgstr "" +msgstr "Os scripts de entrada de aplicações web devem ficar em pastas acessíveis pela web, para que os usuários finais possam acessá-los. Eles costumam se chamar `index.php`, mas podem ter qualquer outro nome, desde que os servidores web consigam localizá-los." #. type: Plain text #: ../src/guide/structure/entry-script.md msgid "Entry script for console application is `./yii`." -msgstr "" +msgstr "O script de entrada da aplicação de console é `./yii`." #. type: Plain text #: ../src/guide/structure/entry-script.md msgid "Entry scripts mainly perform the following work with the help of `ApplicationRunner`:" -msgstr "" +msgstr "Os scripts de entrada fazem principalmente o seguinte, com a ajuda do `ApplicationRunner`:" #. type: Bullet: '* ' #: ../src/guide/structure/entry-script.md msgid "Register [Composer autoloader](https://getcomposer.org/doc/01-basic-usage.md#autoloading);" -msgstr "" +msgstr "Registram o [autoloader do Composer](https://getcomposer.org/doc/01-basic-usage.md#autoloading);" #. type: Bullet: '* ' #: ../src/guide/structure/entry-script.md msgid "Obtain configuration;" -msgstr "" +msgstr "Obtêm a configuração;" #. type: Bullet: '* ' #: ../src/guide/structure/entry-script.md msgid "Use configuration to initialize a dependency injection container;" -msgstr "" +msgstr "Usam a configuração para inicializar um container de injeção de dependência;" #. type: Bullet: '* ' #: ../src/guide/structure/entry-script.md msgid "Get an instance of the request." -msgstr "" +msgstr "Obtêm uma instância da requisição." #. type: Bullet: '* ' #: ../src/guide/structure/entry-script.md msgid "Pass it to `Application` to handle and get a response from it." -msgstr "" +msgstr "Passam-na para a `Application` tratar e obtêm dela uma resposta." #. type: Bullet: '* ' #: ../src/guide/structure/entry-script.md msgid "With the help of an emitter that transforms a response object into an actual HTTP response that's sent to the client browser." -msgstr "" +msgstr "Com a ajuda de um emitter, transformam o objeto de resposta em uma resposta HTTP real, que é enviada ao navegador do cliente." #. type: Title ## #: ../src/guide/structure/entry-script.md #, no-wrap msgid "Web Applications" -msgstr "" +msgstr "Aplicações web" #. type: Plain text #: ../src/guide/structure/entry-script.md msgid "The following is the code in the entry script for the application template:" -msgstr "" +msgstr "Este é o código do script de entrada do template de aplicação:" #. type: Fenced code block (php) #: ../src/guide/structure/entry-script.md @@ -111,17 +111,41 @@ msgid "" "// Run application:\n" "$runner->run();\n" msgstr "" +"debug();\n" +"// Executa a aplicação:\n" +"$runner->run();\n" #. type: Title ## #: ../src/guide/structure/entry-script.md #, no-wrap msgid "Console Applications" -msgstr "" +msgstr "Aplicações de console" #. type: Plain text #: ../src/guide/structure/entry-script.md msgid "Similarly, the following is the code for the entry script of a console application:" -msgstr "" +msgstr "Da mesma forma, este é o código do script de entrada de uma aplicação de console:" #. type: Fenced code block (php) #: ../src/guide/structure/entry-script.md @@ -169,34 +193,75 @@ msgid "" " exit($exitCode);\n" "}\n" msgstr "" +"#!/usr/bin/env php\n" +"withDefinitions($config->get('console'))\n" +" ->withProviders($config->get('providers-console'));\n" +"$container = new Container($containerConfig);\n" +"\n" +"/** @var ContainerInterface $container */\n" +"$container = $container->get(ContainerInterface::class);\n" +"\n" +"$application = $container->get(Application::class);\n" +"$exitCode = 1;\n" +"\n" +"try {\n" +" $application->start();\n" +" $exitCode = $application->run(null, new ConsoleBufferedOutput());\n" +"} catch (\\Error $error) {\n" +" $application->renderThrowable($error, new ConsoleBufferedOutput());\n" +"} finally {\n" +" $application->shutdown($exitCode);\n" +" exit($exitCode);\n" +"}\n" #. type: Title ## #: ../src/guide/structure/entry-script.md #, no-wrap msgid "Alternative runtimes" -msgstr "" +msgstr "Runtimes alternativos" #. type: Plain text #: ../src/guide/structure/entry-script.md msgid "For alternative runtimes such as FrankenPHP, Rapira, RoadRunner, or Swoole, special entry scripts should be used. See:" -msgstr "" +msgstr "Para runtimes alternativos como FrankenPHP, Rapira, RoadRunner ou Swoole, devem ser usados scripts de entrada especiais. Veja:" #. type: Bullet: '- ' #: ../src/guide/structure/entry-script.md msgid "[Using Yii with FrankenPHP](../tutorial/using-yii-with-frankenphp.md)" -msgstr "" +msgstr "[Usando o Yii com FrankenPHP](../tutorial/using-yii-with-frankenphp.md)" #. type: Bullet: '- ' #: ../src/guide/structure/entry-script.md msgid "[Using Yii with Rapira](../tutorial/using-yii-with-rapira.md)" -msgstr "" +msgstr "[Usando o Yii com Rapira](../tutorial/using-yii-with-rapira.md)" #. type: Bullet: '- ' #: ../src/guide/structure/entry-script.md msgid "[Using Yii with RoadRunner](../tutorial/using-yii-with-roadrunner.md)" -msgstr "" +msgstr "[Usando o Yii com RoadRunner](../tutorial/using-yii-with-roadrunner.md)" #. type: Bullet: '- ' #: ../src/guide/structure/entry-script.md msgid "[Using Yii with Swoole](../tutorial/using-yii-with-swoole.md)" -msgstr "" +msgstr "[Usando o Yii com Swoole](../tutorial/using-yii-with-swoole.md)" diff --git a/_translations/po/pt-BR/guide_structure_middleware.md.po b/_translations/po/pt-BR/guide_structure_middleware.md.po index 9eb85211..1477dc46 100644 --- a/_translations/po/pt-BR/guide_structure_middleware.md.po +++ b/_translations/po/pt-BR/guide_structure_middleware.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-06-29 17:10+0000\n" "PO-Revision-Date: 2026-06-29 17:10+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,68 +19,68 @@ msgstr "" #: ../src/guide/structure/middleware.md #, no-wrap msgid "Middleware" -msgstr "" +msgstr "Middleware" #. type: Plain text #: ../src/guide/structure/middleware.md msgid "Yii works with HTTP using the abstraction layer built around [PSR-7 HTTP message interfaces](https://www.php-fig.org/psr/psr-7/) and [PSR-15 request handler/middleware interfaces](https://www.php-fig.org/psr/psr-15/)." -msgstr "" +msgstr "O Yii trabalha com HTTP usando a camada de abstração construída em torno das [interfaces de mensagens HTTP da PSR-7](https://www.php-fig.org/psr/psr-7/) e das [interfaces de request handler/middleware da PSR-15](https://www.php-fig.org/psr/psr-15/)." #. type: Plain text #: ../src/guide/structure/middleware.md msgid "The application is composed of one or several middleware. Middleware runs between request and response. When the URL is requested, the request object is passed to the middleware dispatcher that starts executing middleware one after another. Each middleware, given the request, can:" -msgstr "" +msgstr "A aplicação é composta por um ou vários middlewares. O middleware roda entre a requisição e a resposta. Quando a URL é requisitada, o objeto de requisição é passado para o dispatcher de middlewares, que começa a executar os middlewares um após o outro. Cada middleware, dada a requisição, pode:" #. type: Bullet: '- ' #: ../src/guide/structure/middleware.md msgid "Pass the request to the next middleware performing some work before / after it." -msgstr "" +msgstr "Passar a requisição para o próximo middleware, fazendo algum trabalho antes / depois dele." #. type: Bullet: '- ' #: ../src/guide/structure/middleware.md msgid "Form the response and return it." -msgstr "" +msgstr "Montar a resposta e devolvê-la." #. type: Plain text #: ../src/guide/structure/middleware.md msgid "Depending on middleware used, application behavior may vary significantly." -msgstr "" +msgstr "Dependendo dos middlewares usados, o comportamento da aplicação pode variar bastante." #. type: Plain text #: ../src/guide/structure/middleware.md msgid "![Middleware](/images/guide/middleware.svg)" -msgstr "" +msgstr "![Middleware](/images/guide/middleware.svg)" #. type: Plain text #: ../src/guide/structure/middleware.md msgid "In the above each next middleware wraps the previous middleware. Alternatively, it could be presented as follows:" -msgstr "" +msgstr "Acima, cada middleware seguinte envolve o anterior. Também é possível representar assim:" #. type: Plain text #: ../src/guide/structure/middleware.md msgid "![Middleware](/images/guide/middleware_alternative.svg)" -msgstr "" +msgstr "![Middleware](/images/guide/middleware_alternative.svg)" #. type: Title ## #: ../src/guide/structure/middleware.md #, no-wrap msgid "Using middleware" -msgstr "" +msgstr "Usando middlewares" #. type: Plain text #: ../src/guide/structure/middleware.md msgid "Any [PSR-15](https://www.php-fig.org/psr/psr-15/) compatible middleware could be used with Yii, and there are many. Say, you need to add basic authentication to one of the application URLs. URL-dependent middleware is configured using router, so you need to change the router factory." -msgstr "" +msgstr "Qualquer middleware compatível com a [PSR-15](https://www.php-fig.org/psr/psr-15/) pode ser usado com o Yii, e existem muitos. Digamos que você precise adicionar autenticação básica a uma das URLs da aplicação. Middlewares que dependem da URL são configurados pelo router, então você precisa alterar a router factory." #. type: Plain text #: ../src/guide/structure/middleware.md msgid "Authentication middleware is implemented by `middlewares/http-authentication` package so execute `composer require middlewares/http-authentication` in the application root directory." -msgstr "" +msgstr "O middleware de autenticação é implementado pelo pacote `middlewares/http-authentication`, então execute `composer require middlewares/http-authentication` na pasta raiz da aplicação." #. type: Plain text #: ../src/guide/structure/middleware.md msgid "Now register the middleware in DI container configuration `config/web.php`:" -msgstr "" +msgstr "Agora registre o middleware na configuração do container de DI, `config/web.php`:" #. type: Fenced code block (php) #: ../src/guide/structure/middleware.md @@ -98,11 +98,22 @@ msgid "" " 'attribute()' => ['username'],\n" "],\n" msgstr "" +" [\n" +" 'class' => \\Middlewares\\BasicAuthentication::class,\n" +" '__construct()' => [\n" +" 'users' => [\n" +" 'foo' => 'bar',\n" +" ],\n" +" ],\n" +" 'realm()' => ['Access to the staging site via basic auth'],\n" +" 'attribute()' => ['username'],\n" +"],\n" #. type: Plain text #: ../src/guide/structure/middleware.md msgid "In the `config/routes.php`, add new route:" -msgstr "" +msgstr "No `config/routes.php`, adicione uma nova rota:" #. type: Fenced code block (php) #: ../src/guide/structure/middleware.md @@ -125,16 +136,32 @@ msgid "" " ->prependMiddleware(BasicAuthentication::class)\n" "];\n" msgstr "" +"action([SiteController::class, 'auth'])\n" +" ->name('site/auth')\n" +" ->prependMiddleware(BasicAuthentication::class)\n" +"];\n" #. type: Plain text #: ../src/guide/structure/middleware.md msgid "When configuring routing, you're binding `/basic-auth` URL to a chain of middleware consisting of basic authentication, and the action itself. A chain is a special middleware that executes all the middleware it's configured with." -msgstr "" +msgstr "Ao configurar o roteamento, você está associando a URL `/basic-auth` a uma cadeia de middlewares formada pela autenticação básica e pela própria action. Uma cadeia é um middleware especial que executa todos os middlewares com que foi configurada." #. type: Plain text #: ../src/guide/structure/middleware.md msgid "The action itself could be the following:" -msgstr "" +msgstr "A action em si poderia ser a seguinte:" #. type: Fenced code block (php) #: ../src/guide/structure/middleware.md @@ -147,16 +174,22 @@ msgid "" " return $response;\n" "}\n" msgstr "" +"public function auth(ServerRequestInterface $request): ResponseInterface\n" +"{\n" +" $response = $this->responseFactory->createResponse();\n" +" $response->getBody()->write('Hi ' . $request->getAttribute('username'));\n" +" return $response;\n" +"}\n" #. type: Plain text #: ../src/guide/structure/middleware.md msgid "Basic authentication middleware wrote to request `username` attribute, so you can access the data if needed." -msgstr "" +msgstr "O middleware de autenticação básica gravou o atributo `username` na requisição, então você pode acessar esse dado se precisar." #. type: Plain text #: ../src/guide/structure/middleware.md msgid "To apply middleware to application overall regardless of URL, adjust `config/application.php`:" -msgstr "" +msgstr "Para aplicar um middleware à aplicação como um todo, independentemente da URL, ajuste o `config/application.php`:" #. type: Fenced code block (php) #: ../src/guide/structure/middleware.md @@ -182,39 +215,58 @@ msgid "" " ],\n" "];\n" msgstr "" +"return [\n" +" Yiisoft\\Yii\\Http\\Application::class => [\n" +" '__construct()' => [\n" +" 'dispatcher' => DynamicReference::to(static function (Injector $injector) {\n" +" return ($injector->make(MiddlewareDispatcher::class))\n" +" ->withMiddlewares(\n" +" [\n" +" ErrorCatcher::class,\n" +" BasicAuthentication::class,\n" +" SessionMiddleware::class,\n" +" CsrfTokenMiddleware::class,\n" +" Router::class,\n" +" ]\n" +" );\n" +" }),\n" +" 'fallbackHandler' => Reference::to(NotFoundHandler::class),\n" +" ],\n" +" ],\n" +"];\n" #. type: Title ## #: ../src/guide/structure/middleware.md #, no-wrap msgid "Creating your own middleware" -msgstr "" +msgstr "Criando o seu próprio middleware" #. type: Plain text #: ../src/guide/structure/middleware.md msgid "To create middleware, you need to implement a single `process` method of `Psr\\Http\\Server\\MiddlewareInterface`:" -msgstr "" +msgstr "Para criar um middleware, você precisa implementar um único método, `process`, da `Psr\\Http\\Server\\MiddlewareInterface`:" #. type: Fenced code block (php) #: ../src/guide/structure/middleware.md #, no-wrap msgid "public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface;\n" -msgstr "" +msgstr "public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface;\n" #. type: Plain text #: ../src/guide/structure/middleware.md msgid "There are multiple ways to handle a request, and choosing one depends on what the middleware should achieve." -msgstr "" +msgstr "Há várias formas de tratar uma requisição, e a escolha depende do que o middleware deve fazer." #. type: Title ### #: ../src/guide/structure/middleware.md #, no-wrap msgid "Forming a response directly" -msgstr "" +msgstr "Montando uma resposta diretamente" #. type: Plain text #: ../src/guide/structure/middleware.md msgid "To respond directly, one needs a response factory passed via constructor:" -msgstr "" +msgstr "Para responder diretamente, é preciso uma response factory passada pelo construtor:" #. type: Fenced code block (php) #: ../src/guide/structure/middleware.md @@ -245,12 +297,36 @@ msgid "" " }\n" "}\n" msgstr "" +"responseFactory->createResponse();\n" +" $response->getBody()->write('Hello!');\n" +" return $response;\n" +" }\n" +"}\n" #. type: Title ### #: ../src/guide/structure/middleware.md #, no-wrap msgid "Delegating handling to the next middleware" -msgstr "" +msgstr "Delegando o tratamento para o próximo middleware" #. type: Plain text #: ../src/guide/structure/middleware.md @@ -259,6 +335,8 @@ msgid "" "If middleware either isn't intended to form a response or change the request or can't do anything this time,\n" "handling could be left to the next middleware in the stack: \n" msgstr "" +"Se o middleware não tem a intenção de montar uma resposta nem de alterar a requisição, ou se não pode fazer nada desta vez,\n" +"o tratamento pode ficar para o próximo middleware da pilha: \n" #. type: Fenced code block (php) #: ../src/guide/structure/middleware.md @@ -269,11 +347,15 @@ msgid "" " return $handler->handle($request); \n" "}\n" msgstr "" +"public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface\n" +"{\n" +" return $handler->handle($request); \n" +"}\n" #. type: Plain text #: ../src/guide/structure/middleware.md msgid "In case you need to pass data to the next middleware, you can use request attributes:" -msgstr "" +msgstr "Se você precisar passar dados para o próximo middleware, pode usar atributos da requisição:" #. type: Fenced code block (php) #: ../src/guide/structure/middleware.md @@ -282,28 +364,30 @@ msgid "" "$request = $request->withAttribute('answer', 42);\n" "return $handler->handle($request);\n" msgstr "" +"$request = $request->withAttribute('answer', 42);\n" +"return $handler->handle($request);\n" #. type: Plain text #: ../src/guide/structure/middleware.md msgid "To get it in the next middleware:" -msgstr "" +msgstr "Para obtê-los no próximo middleware:" #. type: Fenced code block (php) #: ../src/guide/structure/middleware.md #, no-wrap msgid "$answer = $request->getAttribute('answer');\n" -msgstr "" +msgstr "$answer = $request->getAttribute('answer');\n" #. type: Title ### #: ../src/guide/structure/middleware.md #, no-wrap msgid "Capturing response to manipulate it" -msgstr "" +msgstr "Capturando a resposta para manipulá-la" #. type: Plain text #: ../src/guide/structure/middleware.md msgid "You may want to capture the response to manipulate it. It could be useful for adding CORS headers, gzipping content, etc." -msgstr "" +msgstr "Você pode querer capturar a resposta para manipulá-la. Isso pode ser útil para adicionar headers CORS, compactar o conteúdo com gzip etc." #. type: Fenced code block (php) #: ../src/guide/structure/middleware.md @@ -313,3 +397,6 @@ msgid "" "// extra handing\n" "return $response;\n" msgstr "" +"$response = $handler->handle($request);\n" +"// tratamento extra\n" +"return $response;\n" diff --git a/_translations/po/pt-BR/guide_structure_module.md.po b/_translations/po/pt-BR/guide_structure_module.md.po index 340d3dbd..8b0fecbe 100644 --- a/_translations/po/pt-BR/guide_structure_module.md.po +++ b/_translations/po/pt-BR/guide_structure_module.md.po @@ -8,65 +8,60 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-06-02 22:29+0000\n" "PO-Revision-Date: 2026-06-02 22:29+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Fenced code block (sh) -#: ../src/cookbook/using-yii-in-third-party-apps.md -#: ../src/guide/structure/designing-packages.md -#: ../src/guide/structure/module.md ../src/guide/structure/package.md -#: ../src/guide/tutorial/i18n.md +#: ../src/cookbook/using-yii-in-third-party-apps.md ../src/guide/structure/designing-packages.md ../src/guide/structure/module.md ../src/guide/structure/package.md ../src/guide/tutorial/i18n.md #, no-wrap msgid "composer yii-config-rebuild\n" -msgstr "" +msgstr "composer yii-config-rebuild\n" #. type: Title ## -#: ../src/guide/concept/configuration.md -#: ../src/guide/structure/designing-packages.md -#: ../src/guide/structure/module.md +#: ../src/guide/concept/configuration.md ../src/guide/structure/designing-packages.md ../src/guide/structure/module.md #, no-wrap msgid "Routes" -msgstr "" +msgstr "Rotas" #. type: Title # #: ../src/guide/structure/module.md #, no-wrap msgid "Modules" -msgstr "" +msgstr "Módulos" #. type: Plain text #: ../src/guide/structure/module.md msgid "A module is an application part grouped around a business context or a reusable feature. In Yii, this is a design boundary, not a required base class. A module can be:" -msgstr "" +msgstr "Um módulo é uma parte da aplicação agrupada em torno de um contexto de negócio ou de um recurso reutilizável. No Yii, isso é uma fronteira de design, não uma classe base obrigatória. Um módulo pode ser:" #. type: Bullet: '- ' #: ../src/guide/structure/module.md msgid "application code under the `App\\` namespace;" -msgstr "" +msgstr "código da aplicação no namespace `App\\`;" #. type: Bullet: '- ' #: ../src/guide/structure/module.md msgid "a [Composer package](package.md) installed into `vendor/`;" -msgstr "" +msgstr "um [pacote Composer](package.md) instalado em `vendor/`;" #. type: Bullet: '- ' #: ../src/guide/structure/module.md msgid "code that starts in the application and is later extracted into a package." -msgstr "" +msgstr "código que começa na aplicação e depois é extraído para um pacote." #. type: Plain text #: ../src/guide/structure/module.md msgid "Use a module when a group of actions, domain services, repositories, event handlers, views, assets, commands, and related configuration changes together and has a name that makes sense to the business." -msgstr "" +msgstr "Use um módulo quando um grupo de actions, serviços de domínio, repositórios, handlers de eventos, views, assets, comandos e a configuração relacionada mudam juntos e têm um nome que faz sentido para o negócio." #. type: Plain text #: ../src/guide/structure/module.md msgid "For example, a blog module can live in an application as:" -msgstr "" +msgstr "Por exemplo, um módulo de blog pode ficar na aplicação assim:" #. type: Fenced code block #: ../src/guide/structure/module.md @@ -82,83 +77,92 @@ msgid "" " IndexAction.php\n" " index.php\n" msgstr "" +"src/\n" +" Blog/\n" +" Post/\n" +" Post.php\n" +" PostRepositoryInterface.php\n" +" InMemoryPostRepository.php\n" +" Web/\n" +" IndexAction.php\n" +" index.php\n" #. type: Plain text #: ../src/guide/structure/module.md msgid "The same structure can later become a Composer package by changing the namespace and adding package metadata and configuration files. See [Designing packages](designing-packages.md) for package-specific details." -msgstr "" +msgstr "A mesma estrutura pode virar um pacote Composer mais tarde, mudando o namespace e adicionando os metadados e os arquivos de configuração do pacote. Veja [Projetando pacotes](designing-packages.md) para os detalhes específicos de pacotes." #. type: Title ## #: ../src/guide/structure/module.md #, no-wrap msgid "Module boundaries" -msgstr "" +msgstr "Fronteiras de módulos" #. type: Plain text #: ../src/guide/structure/module.md msgid "Keep module code together by context first and by technical type second. This is close to the [vertical slices](../../cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md) approach, but at a larger application-structure boundary. Prefer `App\\Blog\\Post\\PostRepositoryInterface` over a global `App\\Repository\\PostRepositoryInterface` when the repository belongs to blog posts only." -msgstr "" +msgstr "Mantenha o código do módulo agrupado primeiro por contexto e depois por tipo técnico. Isso se aproxima da abordagem de [vertical slices](../../cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md), mas numa fronteira maior da estrutura da aplicação. Prefira `App\\Blog\\Post\\PostRepositoryInterface` a um `App\\Repository\\PostRepositoryInterface` global quando o repositório pertence apenas aos posts do blog." #. type: Plain text #: ../src/guide/structure/module.md msgid "Treat module classes as a public API only when another module is expected to use them. Good public API classes are usually:" -msgstr "" +msgstr "Trate as classes de um módulo como API pública apenas quando se espera que outro módulo as use. Boas classes de API pública normalmente são:" #. type: Bullet: '- ' #: ../src/guide/structure/module.md msgid "commands or queries that express a use case;" -msgstr "" +msgstr "comandos ou queries que expressam um caso de uso;" #. type: Bullet: '- ' #: ../src/guide/structure/module.md msgid "DTOs or value objects passed between modules;" -msgstr "" +msgstr "DTOs ou value objects trocados entre módulos;" #. type: Bullet: '- ' #: ../src/guide/structure/module.md msgid "interfaces for services another module may call;" -msgstr "" +msgstr "interfaces de serviços que outro módulo pode chamar;" #. type: Bullet: '- ' #: ../src/guide/structure/module.md msgid "events emitted by the module." -msgstr "" +msgstr "eventos emitidos pelo módulo." #. type: Plain text #: ../src/guide/structure/module.md msgid "Keep implementation classes private to the module namespace. Other modules should not depend on `App\\Blog\\Post\\InMemoryPostRepository` or a controller action directly. They should depend on an interface, a use case class, or an event." -msgstr "" +msgstr "Mantenha as classes de implementação privadas ao namespace do módulo. Outros módulos não devem depender diretamente de `App\\Blog\\Post\\InMemoryPostRepository` ou de uma action de controller. Eles devem depender de uma interface, de uma classe de caso de uso ou de um evento." #. type: Title ## #: ../src/guide/structure/module.md #, no-wrap msgid "Interfaces between modules" -msgstr "" +msgstr "Interfaces entre módulos" #. type: Plain text #: ../src/guide/structure/module.md msgid "Put an interface where the contract belongs:" -msgstr "" +msgstr "Coloque a interface onde o contrato pertence:" #. type: Bullet: '- ' #: ../src/guide/structure/module.md msgid "If the interface describes a capability provided by a module, place it in that module. For example, `App\\Blog\\Post\\PostRepositoryInterface` belongs to the blog module because it describes how blog posts are read." -msgstr "" +msgstr "Se a interface descreve uma capacidade fornecida por um módulo, coloque-a nesse módulo. Por exemplo, `App\\Blog\\Post\\PostRepositoryInterface` pertence ao módulo de blog porque descreve como os posts do blog são lidos." #. type: Bullet: '- ' #: ../src/guide/structure/module.md msgid "If the interface describes what a module needs from the outside world, place it in the consuming module. For example, `App\\Order\\Customer\\CustomerVerifierInterface` belongs to the order module if orders only need a yes-or-no customer check. The customer module, an application adapter, or a package can provide the implementation." -msgstr "" +msgstr "Se a interface descreve o que um módulo precisa do mundo externo, coloque-a no módulo consumidor. Por exemplo, `App\\Order\\Customer\\CustomerVerifierInterface` pertence ao módulo de pedidos se os pedidos só precisam de uma verificação de cliente do tipo sim ou não. O módulo de clientes, um adaptador da aplicação ou um pacote pode fornecer a implementação." #. type: Plain text #: ../src/guide/structure/module.md msgid "This keeps dependencies explicit. A module can depend on another module's public contract, but it should not reach into another module's internal implementation classes." -msgstr "" +msgstr "Isso mantém as dependências explícitas. Um módulo pode depender do contrato público de outro módulo, mas não deve acessar as classes de implementação internas de outro módulo." #. type: Plain text #: ../src/guide/structure/module.md msgid "First, define the interface in the module:" -msgstr "" +msgstr "Primeiro, defina a interface no módulo:" #. type: Fenced code block (php) #: ../src/guide/structure/module.md @@ -178,11 +182,24 @@ msgid "" " public function findLatest(): array;\n" "}\n" msgstr "" +"\n" +" */\n" +" public function findLatest(): array;\n" +"}\n" #. type: Plain text #: ../src/guide/structure/module.md msgid "Put the implementation in the same module and bind the interface to it:" -msgstr "" +msgstr "Coloque a implementação no mesmo módulo e associe a interface a ela:" #. type: Fenced code block (php) #: ../src/guide/structure/module.md @@ -199,22 +216,32 @@ msgid "" " PostRepositoryInterface::class => InMemoryPostRepository::class,\n" "];\n" msgstr "" +" InMemoryPostRepository::class,\n" +"];\n" #. type: Plain text #: ../src/guide/structure/module.md msgid "In the default application template, put this file under `config/common/di/`, for example `config/common/di/blog.php`. The template loads `config/common/di/*.php` into the shared `di` configuration group, so the binding is available to web and console entry points." -msgstr "" +msgstr "No template de aplicação padrão, coloque esse arquivo em `config/common/di/`, por exemplo `config/common/di/blog.php`. O template carrega `config/common/di/*.php` no grupo de configuração compartilhado `di`, então a associação fica disponível para os pontos de entrada web e de console." #. type: Title ## #: ../src/guide/structure/module.md #, no-wrap msgid "Web actions" -msgstr "" +msgstr "Actions web" #. type: Plain text #: ../src/guide/structure/module.md msgid "Actions belong to the module when they are the web entry point for module behavior:" -msgstr "" +msgstr "As actions pertencem ao módulo quando são o ponto de entrada web do comportamento do módulo:" #. type: Fenced code block (php) #: ../src/guide/structure/module.md @@ -246,16 +273,41 @@ msgid "" " }\n" "}\n" msgstr "" +"viewRenderer->render(__DIR__ . '/index', [\n" +" 'posts' => $this->posts->findLatest(),\n" +" ]);\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/structure/module.md msgid "Keep request parsing and response creation in the action. Keep business decisions in the module's domain classes or use case services." -msgstr "" +msgstr "Mantenha a leitura da requisição e a criação da resposta na action. Mantenha as decisões de negócio nas classes de domínio do módulo ou em serviços de caso de uso." #. type: Plain text #: ../src/guide/structure/module.md msgid "For a small application, add module routes directly to `config/common/routes.php`:" -msgstr "" +msgstr "Em uma aplicação pequena, adicione as rotas do módulo diretamente em `config/common/routes.php`:" #. type: Fenced code block (php) #: ../src/guide/structure/module.md @@ -286,16 +338,40 @@ msgid "" " ),\n" "];\n" msgstr "" +"routes(\n" +" Route::get('/')\n" +" ->action(Web\\HomePage\\Action::class)\n" +" ->name('home'),\n" +" ),\n" +"\n" +" Group::create('/blog')\n" +" ->routes(\n" +" Route::get('')\n" +" ->action(IndexAction::class)\n" +" ->name('blog/index'),\n" +" ),\n" +"];\n" #. type: Plain text #: ../src/guide/structure/module.md msgid "Use module-prefixed route names, such as `blog/index`, to avoid collisions." -msgstr "" +msgstr "Use nomes de rota com o prefixo do módulo, como `blog/index`, para evitar colisões." #. type: Plain text #: ../src/guide/structure/module.md msgid "If the application has many modules, you can give each module its own route config file. Change the `routes` group in `config/configuration.php`:" -msgstr "" +msgstr "Se a aplicação tem muitos módulos, você pode dar a cada módulo o seu próprio arquivo de configuração de rotas. Altere o grupo `routes` em `config/configuration.php`:" #. type: Fenced code block (php) #: ../src/guide/structure/module.md @@ -306,11 +382,15 @@ msgid "" " 'common/routes/*.php',\n" "],\n" msgstr "" +"'routes' => [\n" +" 'common/routes.php',\n" +" 'common/routes/*.php',\n" +"],\n" #. type: Plain text #: ../src/guide/structure/module.md msgid "Then create `config/common/routes/blog.php`:" -msgstr "" +msgstr "Depois crie `config/common/routes/blog.php`:" #. type: Fenced code block (php) #: ../src/guide/structure/module.md @@ -333,37 +413,53 @@ msgid "" " ),\n" "];\n" msgstr "" +"routes(\n" +" Route::get('')\n" +" ->action(IndexAction::class)\n" +" ->name('blog/index'),\n" +" ),\n" +"];\n" #. type: Plain text #: ../src/guide/structure/module.md msgid "After changing `config/configuration.php` or adding files matched by a config wildcard, rebuild the merge plan:" -msgstr "" +msgstr "Depois de alterar `config/configuration.php` ou de adicionar arquivos que casam com um curinga da configuração, reconstrua o merge plan:" #. type: Title ## #: ../src/guide/structure/module.md #, no-wrap msgid "Module configuration" -msgstr "" +msgstr "Configuração de módulos" #. type: Plain text #: ../src/guide/structure/module.md msgid "Application modules use the same configuration groups as packages. The difference is where the configuration lives:" -msgstr "" +msgstr "Os módulos da aplicação usam os mesmos grupos de configuração que os pacotes. A diferença é onde a configuração fica:" #. type: Bullet: '- ' #: ../src/guide/structure/module.md msgid "application module configuration lives in the root application under `config/`;" -msgstr "" +msgstr "a configuração de um módulo da aplicação fica na aplicação raiz, em `config/`;" #. type: Bullet: '- ' #: ../src/guide/structure/module.md msgid "package module configuration lives in the package and is declared in `extra.config-plugin`." -msgstr "" +msgstr "a configuração de um módulo em pacote fica no pacote e é declarada em `extra.config-plugin`." #. type: Plain text #: ../src/guide/structure/module.md msgid "Common locations for application module configuration are:" -msgstr "" +msgstr "Locais comuns para a configuração de módulos da aplicação são:" #. type: Fenced code block #: ../src/guide/structure/module.md @@ -381,16 +477,27 @@ msgid "" " web/\n" " params.php\n" msgstr "" +"config/\n" +" common/\n" +" di/\n" +" blog.php\n" +" routes/\n" +" blog.php\n" +" params.php\n" +" console/\n" +" params.php\n" +" web/\n" +" params.php\n" #. type: Plain text #: ../src/guide/structure/module.md msgid "Put shared service definitions in `common/di/`. Put web-only definitions in `web/di/`. Put console-only parameters or command registrations in `console/params.php`." -msgstr "" +msgstr "Coloque as definições de serviços compartilhadas em `common/di/`. Coloque as definições exclusivas da web em `web/di/`. Coloque os parâmetros ou registros de comandos exclusivos do console em `console/params.php`." #. type: Plain text #: ../src/guide/structure/module.md msgid "When a module grows enough to become reusable, move its PHP classes to a Composer package, move its configuration files to the package `config/` directory, and declare them in the package `composer.json`:" -msgstr "" +msgstr "Quando um módulo cresce a ponto de se tornar reutilizável, mova as classes PHP para um pacote Composer, mova os arquivos de configuração para a pasta `config/` do pacote e declare-os no `composer.json` do pacote:" #. type: Fenced code block (json) #: ../src/guide/structure/module.md @@ -405,44 +512,52 @@ msgid "" " }\n" "}\n" msgstr "" +"{\n" +" \"extra\": {\n" +" \"config-plugin\": {\n" +" \"di\": \"config/di.php\",\n" +" \"routes\": \"config/routes.php\"\n" +" }\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/structure/module.md msgid "The application can then override package defaults in its own config files." -msgstr "" +msgstr "A aplicação pode, então, sobrescrever os padrões do pacote nos próprios arquivos de configuração." #. type: Title ## #: ../src/guide/structure/module.md #, no-wrap msgid "Cross-module communication" -msgstr "" +msgstr "Comunicação entre módulos" #. type: Plain text #: ../src/guide/structure/module.md msgid "Choose the smallest coupling that supports the behavior:" -msgstr "" +msgstr "Escolha o menor acoplamento que atenda ao comportamento:" #. type: Bullet: '- ' #: ../src/guide/structure/module.md msgid "Use constructor injection with an interface for a direct synchronous call." -msgstr "" +msgstr "Use injeção pelo construtor com uma interface para uma chamada síncrona direta." #. type: Bullet: '- ' #: ../src/guide/structure/module.md msgid "Use an event when the producer should not know who reacts to something that happened." -msgstr "" +msgstr "Use um evento quando quem produz não deve saber quem reage a algo que aconteceu." #. type: Bullet: '- ' #: ../src/guide/structure/module.md msgid "Use an application service or use case class when orchestration belongs outside both modules." -msgstr "" +msgstr "Use um serviço de aplicação ou uma classe de caso de uso quando a orquestração pertence a um lugar fora dos dois módulos." #. type: Bullet: '- ' #: ../src/guide/structure/module.md msgid "Use a package when the module must be reused by more than one application." -msgstr "" +msgstr "Use um pacote quando o módulo precisa ser reutilizado por mais de uma aplicação." #. type: Plain text #: ../src/guide/structure/module.md msgid "Avoid service locator calls and global state inside module classes. Let actions, commands, and services receive their dependencies through constructors so module boundaries stay visible in code and testable in isolation." -msgstr "" +msgstr "Evite chamadas a service locator e estado global dentro das classes do módulo. Deixe que actions, comandos e serviços recebam as suas dependências pelos construtores, para que as fronteiras dos módulos fiquem visíveis no código e possam ser testadas isoladamente." diff --git a/_translations/po/pt-BR/guide_structure_overview.md.po b/_translations/po/pt-BR/guide_structure_overview.md.po index c9cef18a..8d4ffbaf 100644 --- a/_translations/po/pt-BR/guide_structure_overview.md.po +++ b/_translations/po/pt-BR/guide_structure_overview.md.po @@ -8,104 +8,103 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2025-12-24 08:02+0000\n" "PO-Revision-Date: 2025-12-24 08:02+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/en/guide/structure/overview.md -#: ../src/en/guide/views/script-style-meta.md +#: ../src/en/guide/structure/overview.md ../src/en/guide/views/script-style-meta.md #, no-wrap msgid "Overview" -msgstr "" +msgstr "Visão geral" #. type: Plain text #: ../src/en/guide/structure/overview.md msgid "Yii applications code is typically grouped into modules by context. In each module there could be grouping by type." -msgstr "" +msgstr "O código de aplicações Yii normalmente é agrupado em módulos por contexto. Dentro de cada módulo, pode haver um agrupamento por tipo." #. type: Plain text #: ../src/en/guide/structure/overview.md msgid "For example, if the application is an online store, the context could be:" -msgstr "" +msgstr "Por exemplo, se a aplicação for uma loja online, os contextos poderiam ser:" #. type: Bullet: '- ' #: ../src/en/guide/structure/overview.md msgid "Customer" -msgstr "" +msgstr "Cliente" #. type: Bullet: ' - ' #: ../src/en/guide/structure/overview.md msgid "Profile" -msgstr "" +msgstr "Perfil" #. type: Bullet: ' - ' #: ../src/en/guide/structure/overview.md msgid "Products list" -msgstr "" +msgstr "Lista de produtos" #. type: Bullet: ' - ' #: ../src/en/guide/structure/overview.md msgid "Checkout" -msgstr "" +msgstr "Checkout" #. type: Bullet: '- ' #: ../src/en/guide/structure/overview.md msgid "Logistics" -msgstr "" +msgstr "Logística" #. type: Bullet: '- ' #: ../src/en/guide/structure/overview.md msgid "Delivery" -msgstr "" +msgstr "Entrega" #. type: Bullet: ' - ' #: ../src/en/guide/structure/overview.md msgid "Addresses" -msgstr "" +msgstr "Endereços" #. type: Bullet: '- ' #: ../src/en/guide/structure/overview.md msgid "Helpdesk" -msgstr "" +msgstr "Helpdesk" #. type: Bullet: ' - ' #: ../src/en/guide/structure/overview.md msgid "Support" -msgstr "" +msgstr "Suporte" #. type: Bullet: ' - ' #: ../src/en/guide/structure/overview.md msgid "Claims" -msgstr "" +msgstr "Reclamações" #. type: Bullet: ' - ' #: ../src/en/guide/structure/overview.md msgid "Returns" -msgstr "" +msgstr "Devoluções" #. type: Bullet: '- ' #: ../src/en/guide/structure/overview.md msgid "Accounting" -msgstr "" +msgstr "Contabilidade" #. type: Bullet: ' - ' #: ../src/en/guide/structure/overview.md msgid "Transactions" -msgstr "" +msgstr "Transações" #. type: Bullet: ' - ' #: ../src/en/guide/structure/overview.md msgid "Taxes" -msgstr "" +msgstr "Impostos" #. type: Plain text #: ../src/en/guide/structure/overview.md msgid "For a \"Customer\" context, residing under `App\\Customer` namespace, structure would be:" -msgstr "" +msgstr "Para um contexto \"Customer\", localizado no namespace `App\\Customer`, a estrutura seria:" #. type: Fenced code block #: ../src/en/guide/structure/overview.md @@ -128,33 +127,49 @@ msgid "" " Checkout/ <-- module namespace\n" " CheckoutController.php\n" msgstr "" +"App/\n" +" Customer/ <-- namespace do módulo\n" +" Entity/\n" +" Customer.php <-- entidade compartilhada por \"Profile\" e \"Checkout\"\n" +" Profile/\n" +" Widget/\n" +" Gravatar.php\n" +" ProfileRepository.php <-- o repositório geralmente é específico do contexto\n" +" ProfileController.php <-- ponto de entrada de \"Customer\\Profile\"\n" +" ProductList/ <-- namespace do módulo \n" +" Entity/ <-- entidades específicas de \"Customer\\ProductList\"\n" +" Category.php\n" +" Product.php\n" +" ProductsListController.php <-- ponto de entrada de \"Customer\\ProductList\"\n" +" Checkout/ <-- namespace do módulo\n" +" CheckoutController.php\n" #. type: Plain text #: ../src/en/guide/structure/overview.md msgid "A context may include sub-contexts. If a class is shared by multiple contexts, it's moved to the ancestor of both contexts." -msgstr "" +msgstr "Um contexto pode incluir subcontextos. Se uma classe é compartilhada por vários contextos, ela é movida para o ancestral comum desses contextos." #. type: Plain text #: ../src/en/guide/structure/overview.md msgid "A context may have [an entry point known as \"action\" or \"controller\"](action.md). Its job is to take [a request instance](../runtime/request.md), pass it to [domain layer](domain.md) in a suitable format, and create [a response](../runtime/response.md) based on domain layer return." -msgstr "" +msgstr "Um contexto pode ter [um ponto de entrada conhecido como \"action\" ou \"controller\"](action.md). A função dele é receber [uma instância de requisição](../runtime/request.md), passá-la para a [camada de domínio](domain.md) em um formato adequado e criar [uma resposta](../runtime/response.md) com base no retorno da camada de domínio." #. type: Plain text #: ../src/en/guide/structure/overview.md msgid "Besides, Yii applications also have the following:" -msgstr "" +msgstr "Além disso, aplicações Yii também têm o seguinte:" #. type: Bullet: '* ' #: ../src/en/guide/structure/overview.md msgid "[entry scripts](entry-script.md): they're PHP scripts that are directly accessible by end users. They're responsible for starting a request handling cycle. Typically, a single entry script is handling the whole application." -msgstr "" +msgstr "[scripts de entrada](entry-script.md): são scripts PHP acessíveis diretamente pelos usuários finais. Eles são responsáveis por iniciar um ciclo de tratamento de requisição. Normalmente, um único script de entrada atende a aplicação inteira." #. type: Bullet: '* ' #: ../src/en/guide/structure/overview.md msgid "[services](service.md): they're typically stateless objects registered within dependency container and provide various action methods." -msgstr "" +msgstr "[serviços](service.md): normalmente são objetos sem estado registrados no container de dependências que fornecem diversos métodos de ação." #. type: Bullet: '* ' #: ../src/en/guide/structure/overview.md msgid "[middleware](middleware.md): they represent a code that needs to be invoked before and after the actual handling of each request by action handlers." -msgstr "" +msgstr "[middleware](middleware.md): representam código que precisa ser executado antes e depois do tratamento efetivo de cada requisição pelos handlers de action." diff --git a/_translations/po/pt-BR/guide_structure_package.md.po b/_translations/po/pt-BR/guide_structure_package.md.po index 57ba58ef..da36f8ee 100644 --- a/_translations/po/pt-BR/guide_structure_package.md.po +++ b/_translations/po/pt-BR/guide_structure_package.md.po @@ -8,84 +8,81 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-06-05 20:33+0000\n" "PO-Revision-Date: 2026-06-05 20:33+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Fenced code block (sh) -#: ../src/cookbook/using-yii-in-third-party-apps.md -#: ../src/guide/structure/designing-packages.md -#: ../src/guide/structure/module.md ../src/guide/structure/package.md -#: ../src/guide/tutorial/i18n.md +#: ../src/cookbook/using-yii-in-third-party-apps.md ../src/guide/structure/designing-packages.md ../src/guide/structure/module.md ../src/guide/structure/package.md ../src/guide/tutorial/i18n.md #, no-wrap msgid "composer yii-config-rebuild\n" -msgstr "" +msgstr "composer yii-config-rebuild\n" #. type: Title # #: ../src/guide/structure/package.md #, no-wrap msgid "Using packages" -msgstr "" +msgstr "Usando pacotes" #. type: Plain text #: ../src/guide/structure/package.md msgid "Reusable code is distributed as [Composer packages](https://getcomposer.org/doc/05-repositories.md#package). A package can be an infrastructure library, a Yii integration, a reusable feature, or a module representing an application context." -msgstr "" +msgstr "Código reutilizável é distribuído como [pacotes Composer](https://getcomposer.org/doc/05-repositories.md#package). Um pacote pode ser uma biblioteca de infraestrutura, uma integração com o Yii, um recurso reutilizável ou um módulo que representa um contexto da aplicação." #. type: Plain text #: ../src/guide/structure/package.md msgid "This page explains how to use packages in an application. To create a Yii-aware package, see [Designing packages for Yii applications](designing-packages.md)." -msgstr "" +msgstr "Esta página explica como usar pacotes em uma aplicação. Para criar um pacote compatível com o Yii, veja [Projetando pacotes para aplicações Yii](designing-packages.md)." #. type: Title ## #: ../src/guide/structure/package.md #, no-wrap msgid "Installing packages" -msgstr "" +msgstr "Instalando pacotes" #. type: Plain text #: ../src/guide/structure/package.md msgid "By default, Composer installs packages registered on [Packagist](https://packagist.org/), the main repository for open source PHP packages." -msgstr "" +msgstr "Por padrão, o Composer instala pacotes registrados no [Packagist](https://packagist.org/), o principal repositório de pacotes PHP de código aberto." #. type: Plain text #: ../src/guide/structure/package.md msgid "Install a package with:" -msgstr "" +msgstr "Instale um pacote com:" #. type: Fenced code block (sh) #: ../src/guide/structure/package.md #, no-wrap msgid "composer require vendor-name/package-name\n" -msgstr "" +msgstr "composer require vendor-name/package-name\n" #. type: Plain text #: ../src/guide/structure/package.md msgid "Composer updates two files:" -msgstr "" +msgstr "O Composer atualiza dois arquivos:" #. type: Bullet: '- ' #: ../src/guide/structure/package.md msgid "`composer.json` stores the package name and version constraint." -msgstr "" +msgstr "`composer.json` armazena o nome do pacote e a restrição de versão." #. type: Bullet: '- ' #: ../src/guide/structure/package.md msgid "`composer.lock` stores the exact versions installed." -msgstr "" +msgstr "`composer.lock` armazena as versões exatas instaladas." #. type: Plain text #: ../src/guide/structure/package.md msgid "Commit both files so other environments install the same dependency versions." -msgstr "" +msgstr "Faça commit dos dois arquivos para que outros ambientes instalem as mesmas versões das dependências." #. type: Plain text #: ../src/guide/structure/package.md msgid "Installed packages are stored in the application `vendor/` directory." -msgstr "" +msgstr "Os pacotes instalados ficam na pasta `vendor/` da aplicação." #. type: Plain text #: ../src/guide/structure/package.md @@ -95,97 +92,100 @@ msgid "" "> Never edit files in `vendor/` directly. Change application configuration, extend classes, decorate services, or\n" "> contribute fixes to the package instead.\n" msgstr "" +"> [!WARNING]\n" +"> Nunca edite arquivos em `vendor/` diretamente. Em vez disso, altere a configuração da aplicação, estenda classes, decore serviços ou\n" +"> contribua com correções para o pacote.\n" #. type: Plain text #: ../src/guide/structure/package.md msgid "Package classes are available through Composer autoloading after installation. See [Autoloading](../concept/autoloading.md) for details." -msgstr "" +msgstr "As classes dos pacotes ficam disponíveis pelo autoload do Composer após a instalação. Veja [Autoload](../concept/autoloading.md) para mais detalhes." #. type: Title ## #: ../src/guide/structure/package.md #, no-wrap msgid "Updating packages" -msgstr "" +msgstr "Atualizando pacotes" #. type: Plain text #: ../src/guide/structure/package.md msgid "Update a package within the version constraint recorded in `composer.json`:" -msgstr "" +msgstr "Atualize um pacote dentro da restrição de versão registrada no `composer.json`:" #. type: Fenced code block (sh) #: ../src/guide/structure/package.md #, no-wrap msgid "composer update vendor-name/package-name\n" -msgstr "" +msgstr "composer update vendor-name/package-name\n" #. type: Plain text #: ../src/guide/structure/package.md msgid "Change the accepted version constraint with `composer require`:" -msgstr "" +msgstr "Altere a restrição de versão aceita com `composer require`:" #. type: Fenced code block (sh) #: ../src/guide/structure/package.md #, no-wrap msgid "composer require vendor-name/package-name:^2.0\n" -msgstr "" +msgstr "composer require vendor-name/package-name:^2.0\n" #. type: Plain text #: ../src/guide/structure/package.md msgid "After updating a Yii-aware package, Composer rebuilds Yii's configuration merge plan. If you changed configuration group mappings manually, rebuild it explicitly:" -msgstr "" +msgstr "Depois de atualizar um pacote compatível com o Yii, o Composer reconstrói o merge plan de configuração do Yii. Se você alterou manualmente os mapeamentos de grupos de configuração, reconstrua-o explicitamente:" #. type: Title ## #: ../src/guide/structure/package.md #, no-wrap msgid "Removing packages" -msgstr "" +msgstr "Removendo pacotes" #. type: Plain text #: ../src/guide/structure/package.md msgid "Remove a package with:" -msgstr "" +msgstr "Remova um pacote com:" #. type: Fenced code block (sh) #: ../src/guide/structure/package.md #, no-wrap msgid "composer remove vendor-name/package-name\n" -msgstr "" +msgstr "composer remove vendor-name/package-name\n" #. type: Plain text #: ../src/guide/structure/package.md msgid "Then remove application code and configuration that referenced classes, services, routes, commands, assets, migrations, or translations from that package." -msgstr "" +msgstr "Em seguida, remova o código e a configuração da aplicação que referenciavam classes, serviços, rotas, comandos, assets, migrations ou traduções desse pacote." #. type: Title ## #: ../src/guide/structure/package.md #, no-wrap msgid "Private packages" -msgstr "" +msgstr "Pacotes privados" #. type: Plain text #: ../src/guide/structure/package.md msgid "For private code, configure Composer repositories in the application `composer.json`. Common options are:" -msgstr "" +msgstr "Para código privado, configure repositórios do Composer no `composer.json` da aplicação. As opções mais comuns são:" #. type: Bullet: '- ' #: ../src/guide/structure/package.md msgid "`vcs` for a Git repository." -msgstr "" +msgstr "`vcs` para um repositório Git." #. type: Bullet: '- ' #: ../src/guide/structure/package.md msgid "`path` for a local package during development." -msgstr "" +msgstr "`path` para um pacote local durante o desenvolvimento." #. type: Bullet: '- ' #: ../src/guide/structure/package.md msgid "`composer` for a private Composer repository." -msgstr "" +msgstr "`composer` para um repositório Composer privado." #. type: Plain text #: ../src/guide/structure/package.md msgid "For example, to work with a package located next to the application:" -msgstr "" +msgstr "Por exemplo, para trabalhar com um pacote localizado ao lado da aplicação:" #. type: Fenced code block (json) #: ../src/guide/structure/package.md @@ -200,40 +200,48 @@ msgid "" " ]\n" "}\n" msgstr "" +"{\n" +" \"repositories\": [\n" +" {\n" +" \"type\": \"path\",\n" +" \"url\": \"../packages/blog\"\n" +" }\n" +" ]\n" +"}\n" #. type: Plain text #: ../src/guide/structure/package.md msgid "Then install it normally:" -msgstr "" +msgstr "Depois, instale-o normalmente:" #. type: Fenced code block (sh) #: ../src/guide/structure/package.md #, no-wrap msgid "composer require vendor/blog\n" -msgstr "" +msgstr "composer require vendor/blog\n" #. type: Plain text #: ../src/guide/structure/package.md msgid "Read more in the [Composer repository documentation](https://getcomposer.org/doc/05-repositories.md)." -msgstr "" +msgstr "Leia mais na [documentação de repositórios do Composer](https://getcomposer.org/doc/05-repositories.md)." #. type: Title ## #: ../src/guide/structure/package.md #, no-wrap msgid "Package configuration" -msgstr "" +msgstr "Configuração de pacotes" #. type: Plain text #: ../src/guide/structure/package.md msgid "Some Yii packages provide default configuration through [yiisoft/config](https://github.com/yiisoft/config). After installation, the package configuration becomes part of the vendor layer and the application can override it in the root package configuration." -msgstr "" +msgstr "Alguns pacotes Yii fornecem configuração padrão por meio do [yiisoft/config](https://github.com/yiisoft/config). Após a instalação, a configuração do pacote passa a fazer parte da camada vendor, e a aplicação pode sobrescrevê-la na configuração do pacote raiz." #. type: Plain text #: ../src/guide/structure/package.md msgid "Prefer partial overrides in application config files over copying whole package config files. For example, override only the parameter or service definition you need." -msgstr "" +msgstr "Prefira sobrescritas parciais nos arquivos de configuração da aplicação em vez de copiar arquivos de configuração inteiros do pacote. Por exemplo, sobrescreva apenas o parâmetro ou a definição de serviço de que você precisa." #. type: Plain text #: ../src/guide/structure/package.md msgid "For more details, see [Configuration](../concept/configuration.md) and [Designing packages for Yii applications](designing-packages.md)." -msgstr "" +msgstr "Para mais detalhes, veja [Configuração](../concept/configuration.md) e [Projetando pacotes para aplicações Yii](designing-packages.md)." diff --git a/src/pt-BR/guide/concept/aliases.md b/src/pt-BR/guide/concept/aliases.md index c41871ed..273be6e8 100644 --- a/src/pt-BR/guide/concept/aliases.md +++ b/src/pt-BR/guide/concept/aliases.md @@ -1,18 +1,17 @@ # Aliases -You can use aliases to represent file paths or URLs so that you don't have -to hard-code absolute paths or URLs in your project. An alias must start -with the `@` character to be differentiated from normal file paths and -URLs. Alias defined without leading `@` will be prefixed with `@` character. +Você pode usar aliases para representar caminhos de arquivos ou URLs, +evitando escrever caminhos absolutos ou URLs fixos no seu projeto. Um alias +deve começar com o caractere `@` para se diferenciar de caminhos de arquivos +e URLs normais. Um alias definido sem o `@` inicial receberá o prefixo `@`. -Default Yii application has some aliases pre-defined in -`config/params.php`. For example, the alias `@public` represents the web -root path; `@baseUrl` represents the base URL for the currently running Web -application. +A aplicação Yii padrão tem alguns aliases predefinidos em +`config/params.php`. Por exemplo, o alias `@public` representa o caminho da +raiz web; `@baseUrl` representa a URL base da aplicação web em execução. -## Defining aliases +## Definindo aliases -You can define an alias via application's `config/params.php`: +Você pode definir um alias no `config/params.php` da aplicação: ```php return [ @@ -22,13 +21,13 @@ return [ 'aliases' => [ // ... - // an alias of a file path + // um alias de um caminho de arquivo '@foo' => '/path/to/foo', - // an alias of a URL + // um alias de uma URL '@bar' => 'https://www.example.com', - // an alias of a concrete file that contains a \foo\Bar class + // um alias de um arquivo concreto que contém a classe \foo\Bar '@foo/Bar.php' => '/definitely/not/foo/Bar.php', ], ], @@ -36,21 +35,21 @@ return [ ``` > [!NOTE] -> The file path or URL being aliased may *not* necessarily refer to an existing file or resource. +> O caminho de arquivo ou URL representado pelo alias *não* precisa necessariamente se referir a um arquivo ou recurso existente. -Given a defined alias, you may derive a new alias by appending a slash `/` -followed with one or more path segments. For example, `@foo` is a root -alias, while `@foo/bar/file.php` is a derived alias. +A partir de um alias definido, você pode derivar um novo alias acrescentando +uma barra `/` seguida de um ou mais segmentos de caminho. Por exemplo, +`@foo` é um alias raiz, enquanto `@foo/bar/file.php` é um alias derivado. -You can define an alias using another alias (either root or derived): +Você pode definir um alias usando outro alias (raiz ou derivado): ```php '@foobar' => '@foo/bar', ``` -The `yiisoft/aliases` parameter initializes `Aliases` service from -[`yiisoft/aliases`](https://github.com/yiisoft/aliases) package. You can -set extra aliases in runtime by using the service: +O parâmetro `yiisoft/aliases` inicializa o serviço `Aliases` do pacote +[`yiisoft/aliases`](https://github.com/yiisoft/aliases). Você pode definir +aliases extras em tempo de execução usando o serviço: ```php use \Yiisoft\Aliases\Aliases; @@ -61,10 +60,10 @@ public function actionIndex(Aliases $aliases) } ``` -## Using aliases in configuration +## Usando aliases na configuração -It's preferred to resolve aliases at the configuration level, so services -get URLs and paths as ready to use strings: +É preferível resolver os aliases no nível da configuração, para que os +serviços recebam URLs e caminhos como strings prontas para uso: ```php [!NOTE] -> The `get()` method doesn't check whether the resulting path/URL refers to an existing file or resource. +> O método `get()` não verifica se o caminho/URL resultante se refere a um arquivo ou recurso existente. -A root alias may also contain slash `/` characters. The `get()` method is -intelligent enough to tell, which part of an alias is a root alias and thus -correctly determines the corresponding file path or URL: +Um alias raiz também pode conter caracteres de barra `/`. O método `get()` é +inteligente o suficiente para identificar qual parte de um alias é o alias +raiz e, assim, determina corretamente o caminho de arquivo ou URL +correspondente: ```php use \Yiisoft\Aliases\Aliases; @@ -123,27 +123,26 @@ public function actionIndex(Aliases $aliases) } ``` -If `@foo/bar` isn't defined as a root alias, the last statement would -display `/path/to/foo/bar/file.php`. +Se `@foo/bar` não estiver definido como alias raiz, a última instrução +exibiria `/path/to/foo/bar/file.php`. -## Predefined aliases +## Aliases predefinidos -[Yii application](https://github.com/yiisoft/app) predefines a set of -aliases to reference commonly used file paths and URLs: +A [aplicação Yii](https://github.com/yiisoft/app) predefine um conjunto de +aliases para referenciar caminhos de arquivos e URLs de uso comum: -- `@root` - the base directory of the currently running application. -- `@assets` - application's public directory where it publishes assets. -- `@assetsUrl` - URL of base directory with published assets. -- `@baseUrl` - the base URL of the currently running Web - application. Defaults to `/`. -- `@npm` - node packages directory. -- `@bower` - bower packages directory. -- `@vendor` - Composer's `vendor` directory. -- `@public` - application's publicly accessible directory that with +- `@root` - a pasta base da aplicação em execução. +- `@assets` - pasta pública da aplicação onde ela publica os assets. +- `@assetsUrl` - URL da pasta base com os assets publicados. +- `@baseUrl` - a URL base da aplicação web em execução. O padrão é `/`. +- `@npm` - pasta de pacotes node. +- `@bower` - pasta de pacotes bower. +- `@vendor` - a pasta `vendor` do Composer. +- `@public` - pasta publicamente acessível da aplicação, que contém o `index.php`. -- `@runtime` - the runtime path of the currently running - application. Defaults to `@root/runtime`. -- `@layout` - the directory with layouts. -- `@resources` - directory with views, asset sources and other resources. -- `@views` - application view templates base directory. +- `@runtime` - o caminho de runtime da aplicação em execução. O padrão é + `@root/runtime`. +- `@layout` - a pasta com os layouts. +- `@resources` - pasta com views, fontes de assets e outros recursos. +- `@views` - pasta base dos templates de view da aplicação. diff --git a/src/pt-BR/guide/concept/autoloading.md b/src/pt-BR/guide/concept/autoloading.md index c01226ae..7038ac31 100644 --- a/src/pt-BR/guide/concept/autoloading.md +++ b/src/pt-BR/guide/concept/autoloading.md @@ -1,15 +1,16 @@ -# Class autoloading +# Autoload de classes -Since Yii uses [Composer](https://getcomposer.org) to manage packages, it -automatically loads classes from these packages without the need to -`require` their file explicitly. When it installs packages, it generates a -[PSR-4 compatible autoloader](https://www.php-fig.org/psr/psr-4/). To use -it, `require_once` autoloader `/vendor/autoload.php` in your `index.php` -entry point file. +Como o Yii usa o [Composer](https://getcomposer.org) para gerenciar pacotes, +ele carrega automaticamente as classes desses pacotes sem a necessidade de +fazer `require` dos arquivos explicitamente. Ao instalar pacotes, o +Composer gera um [autoloader compatível com +PSR-4](https://www.php-fig.org/psr/psr-4/). Para usá-lo, faça +`require_once` do autoloader `/vendor/autoload.php` no seu arquivo de ponto +de entrada `index.php`. -You can use autoloader not only for the packages installed, but for your -application as well since it's also a package. To load classes of a certain -namespace, add the following to `composer.json`: +Você pode usar o autoloader não só para os pacotes instalados, mas também +para a sua aplicação, já que ela também é um pacote. Para carregar classes +de um determinado namespace, adicione o seguinte ao `composer.json`: ```json { @@ -21,17 +22,18 @@ namespace, add the following to `composer.json`: } ``` -Where `App\\` is a root namespace and `src/` is a directory where you have -your classes. You can add more source roots if needed. When done, execute -`composer dump-autoload` or simply `composer du` and classes from the -corresponding namespaces will start loading automatically. +Onde `App\\` é o namespace raiz e `src/` é a pasta onde ficam suas +classes. Você pode adicionar mais raízes de código-fonte se +precisar. Depois, execute `composer dump-autoload` ou simplesmente `composer +du`, e as classes dos namespaces correspondentes passarão a ser carregadas +automaticamente. -If you need development-environment-specific autoloading that isn't used -when executing Composer with `--no-dev` flag, add it to `autoload-dev` -section instead of `autoload`. +Se você precisar de autoload específico do ambiente de desenvolvimento, que +não seja usado ao executar o Composer com a flag `--no-dev`, adicione-o à +seção `autoload-dev` em vez de `autoload`. -## References +## Referências - [PSR-4: Autoloader](https://www.php-fig.org/psr/psr-4/). -- [Composer guide on - autoloading](https://getcomposer.org/doc/01-basic-usage.md#autoloading). +- [Guia do Composer sobre + autoload](https://getcomposer.org/doc/01-basic-usage.md#autoloading). diff --git a/src/pt-BR/guide/concept/configuration.md b/src/pt-BR/guide/concept/configuration.md index e83bc33a..9177e7e8 100644 --- a/src/pt-BR/guide/concept/configuration.md +++ b/src/pt-BR/guide/concept/configuration.md @@ -1,20 +1,21 @@ -# Configuration +# Configuração -There are many ways to configure your application. We will focus on concepts -used in the [default project template](https://github.com/yiisoft/app). +Há muitas formas de configurar a sua aplicação. Aqui o foco são os conceitos +usados no [template de projeto padrão](https://github.com/yiisoft/app). -Yii3 configs are part of the application. You can change many aspects of how -the application works by editing configuration under `config/` directory. +As configurações do Yii3 fazem parte da aplicação. Você pode mudar muitos +aspectos do funcionamento da aplicação editando a configuração na pasta +`config/`. -## Config plugin +## Plugin de configuração -The application template uses -[yiisoft/config](https://github.com/yiisoft/config) as a composer plugin to -assemble configs. +O template de aplicação usa o +[yiisoft/config](https://github.com/yiisoft/config) como plugin do Composer +para montar as configurações. -Packages provide default configurations through defined [config -groups](https://github.com/yiisoft/config#config-groups) in the -`config-plugin` key in the `extra` section of the `composer.json`: +Os pacotes fornecem configurações padrão por meio de [grupos de +configuração](https://github.com/yiisoft/config#config-groups) definidos na +chave `config-plugin` da seção `extra` do `composer.json`: ```json "extra": { @@ -28,25 +29,26 @@ groups](https://github.com/yiisoft/config#config-groups) in the } ``` -After Composer updates autoload files, such as during `dump-autoload`, -`install`, `require`, `update`, or `remove`, the plugin scans installed -packages for configurations and writes a merge plan to -`config/.merge-plan.php`. The merge plan declares the order of merging -found configurations into the final configuration to be passed to [DI -container](di-container.md). +Depois que o Composer atualiza os arquivos de autoload, como durante +`dump-autoload`, `install`, `require`, `update` ou `remove`, o plugin +procura configurações nos pacotes instalados e grava um merge plan em +`config/.merge-plan.php`. O merge plan declara a ordem em que as +configurações encontradas são mescladas na configuração final, que é passada +ao [container de DI](di-container.md). -At runtime, `Yiisoft\Config\Config` loads the defined config groups -according to that merge plan. Configs are read in three layers: +Em tempo de execução, `Yiisoft\Config\Config` carrega os grupos de +configuração definidos de acordo com esse merge plan. As configurações são +lidas em três camadas: -1. Vendor package configs with default values. -2. Root package configs from the application `config/` directory. -3. Environment-specific configs from the application. +1. Configurações dos pacotes em vendor, com os valores padrão. +2. Configurações do pacote raiz, da pasta `config/` da aplicação. +3. Configurações da aplicação específicas de cada ambiente. > [!WARNING] -> Config keys with the same name are not allowed within a single layer. +> Chaves de configuração com o mesmo nome não são permitidas dentro de uma mesma camada. -The application template stores configurations in a PHP file instead of -inline JSON: +O template de aplicação guarda as configurações em um arquivo PHP em vez de +JSON inline: ```json "extra": { @@ -54,8 +56,8 @@ inline JSON: } ``` -That file returns the same keys you could otherwise define in -`composer.json`: `config-plugin`, `config-plugin-options`, and +Esse arquivo retorna as mesmas chaves que você poderia definir no +`composer.json`: `config-plugin`, `config-plugin-options` e `config-plugin-environments`. ```php @@ -115,26 +117,26 @@ return [ ]; ``` -Config group names are mapping keys. Their values are file paths relative to -the `source-directory` option, which defaults to the directory containing -`composer.json`. +Os nomes dos grupos de configuração são as chaves do mapeamento. Os valores +são caminhos de arquivos relativos à opção `source-directory`, cujo padrão é +a pasta que contém o `composer.json`. -- A string value loads one file. -- An array loads and merges multiple files in the given order. -- `?` marks an optional file. -- `*` marks a wildcard path. -- `$group` references another config group to be merged. +- Um valor string carrega um arquivo. +- Um array carrega e mescla vários arquivos na ordem indicada. +- `?` marca um arquivo opcional. +- `*` marca um caminho com curinga. +- `$group` referencia outro grupo de configuração a ser mesclado. -The `params` group is special: its values are available as `$params` in -other config files by default. +O grupo `params` é especial: por padrão, os valores dele ficam disponíveis +como `$params` nos outros arquivos de configuração. -You can read more in the [yiisoft/config -documentation](https://github.com/yiisoft/config/blob/master/README.md). +Leia mais na [documentação do +yiisoft/config](https://github.com/yiisoft/config/blob/master/README.md). -## Config files +## Arquivos de configuração -Now, as you know how the plugin assembles configs, look at the `config/` -directory structure used by the default application template: +Agora que você sabe como o plugin monta as configurações, veja a estrutura +da pasta `config/` usada pelo template de aplicação padrão: ``` common/ @@ -160,30 +162,31 @@ web/ configuration.php ``` -This structure follows the groups defined in `config/configuration.php`: +Essa estrutura segue os grupos definidos em `config/configuration.php`: -- `params`, `params-web`, and `params-console` load parameter files from - `common/`, `web/`, and `console/`. -- `di` and `di-web` load container definitions from `common/di/` and +- `params`, `params-web` e `params-console` carregam arquivos de parâmetros + de `common/`, `web/` e `console/`. +- `di` e `di-web` carregam definições do container de `common/di/` e `web/di/`. -- `routes` and `bootstrap` load `common/routes.php` and +- `routes` e `bootstrap` carregam `common/routes.php` e `common/bootstrap.php`. -- `config-plugin-environments` adds environment-specific parameter files - from `environments/dev/`, `environments/test/`, and `environments/prod/`. +- `config-plugin-environments` acrescenta arquivos de parâmetros específicos + de cada ambiente de `environments/dev/`, `environments/test/` e + `environments/prod/`. -At runtime, `.merge-plan.php` stores the assembled merge plan generated from -`configuration.php`. +Em tempo de execução, `.merge-plan.php` guarda o merge plan montado a partir +de `configuration.php`. -### Container configuration +### Configuração do container -The application consists of services registered in a [dependency -container](di-container.md). In the default template, direct container -definitions live in `config/common/di/*.php` and `config/web/di/*.php`. +A aplicação é formada por serviços registrados em um [container de +dependências](di-container.md). No template padrão, as definições diretas do +container ficam em `config/common/di/*.php` e `config/web/di/*.php`. -Definitions from `common/di/` are shared by web and console entry -points. The `di-web` group adds web-specific definitions from `web/di/`. The -`di-console` group currently reuses the shared `di` definitions without -extra files. +As definições de `common/di/` são compartilhadas pelos pontos de entrada web +e de console. O grupo `di-web` acrescenta definições específicas da web, de +`web/di/`. Atualmente, o grupo `di-console` reaproveita as definições +compartilhadas de `di`, sem arquivos extras. ```php [ - // Just a regular closure, it will be called from the Dispatcher "as is". + // Uma closure comum, que será chamada pelo Dispatcher "como está". static fn (EventName $event) => someStuff($event), - // A regular closure with an extra dependency. All the parameters after the first one (the event itself) - // will be resolved from your DI container within `yiisoft/injector`. + // Uma closure comum com uma dependência extra. Todos os parâmetros depois do primeiro (o próprio evento) + // serão resolvidos pelo seu container de DI por meio do `yiisoft/injector`. static fn (EventName $event, DependencyClass $dependency) => someStuff($event), - // An example with a regular callable. If the `staticMethodName` method has some dependencies, - // they will be resolved the same way as in the earlier example. + // Um exemplo com um callable comum. Se o método `staticMethodName` tiver dependências, + // elas serão resolvidas da mesma forma que no exemplo anterior. [SomeClass::class, 'staticMethodName'], - // Non-static methods are allowed too. In this case, `SomeClass` will be instantiated by your DI container. + // Métodos não estáticos também são permitidos. Nesse caso, `SomeClass` será instanciada pelo seu container de DI. [SomeClass::class, 'methodName'], - // An object of a class with the `__invoke` method implemented + // Um objeto de uma classe que implementa o método `__invoke` new InvokableClass(), - // In this case, the `InvokableClass` with the `__invoke` method will be instantiated by your DI container + // Nesse caso, a `InvokableClass` com o método `__invoke` será instanciada pelo seu container de DI InvokableClass::class, - // Any invokable class definition may be here as long as `$container->has('the definition')` is true. + // Qualquer definição de classe invocável pode estar aqui, desde que `$container->has('the definition')` seja true. 'di-alias' ], ]; ``` -Read more about it in ["Events"](events.md). +Leia mais sobre isso em ["Eventos"](events.md). -### Parameters +### Parâmetros -Base parameters are stored in `config/common/params.php`. They are then -extended by `config/web/params.php`, `config/console/params.php`, and -environment-specific files under `config/environments/`. +Os parâmetros base ficam em `config/common/params.php`. Depois, eles são +estendidos por `config/web/params.php`, `config/console/params.php` e pelos +arquivos específicos de cada ambiente em `config/environments/`. > [!TIP] -> Don't use parameters, constants, or environment variables directly in your application, configure -> services instead. +> Não use parâmetros, constantes ou variáveis de ambiente diretamente na sua aplicação; em vez disso, configure +> os serviços. -The default application `common/params.php` looks like the following: +O `common/params.php` da aplicação padrão é assim: ```php [!NOTE] -> The container contains only shared instances. If you need a factory, use the dedicated -> [yiisoft/factory](https://github.com/yiisoft/factory) package. +> O container contém apenas instâncias compartilhadas. Se você precisar de uma factory, use o pacote dedicado +> [yiisoft/factory](https://github.com/yiisoft/factory). > [!TIP] -> [Martin Fowler's article](https://martinfowler.com/articles/injection.html) has well -> explained why DI container is useful. Here we will mainly explain the usage of the DI container provided by Yii. +> O [artigo de Martin Fowler](https://martinfowler.com/articles/injection.html) explica bem +> por que um container de DI é útil. Aqui vamos explicar principalmente o uso do container de DI fornecido pelo Yii. -### Configuring container +### Configurando o container -Because to create a new object you need its dependencies, you should -register them as early as possible. You can do it in the application -configuration, `config/web.php`. For the following service: +Como para criar um novo objeto você precisa das dependências dele, +registre-as o quanto antes. Você pode fazer isso na configuração da +aplicação, `config/web.php`. Para o seguinte serviço: ```php final class MyService implements MyServiceInterface @@ -161,7 +164,7 @@ final class MyService implements MyServiceInterface } ``` -configuration could be: +a configuração poderia ser: ```php return [ @@ -173,14 +176,14 @@ return [ ]; ``` -That's equal to the following: +Isso equivale ao seguinte: ```php $myService = new MyService(42); $myService->setDiscount(10); ``` -You can provide arguments with names as well: +Você também pode passar argumentos com nomes: ```php return [ @@ -192,10 +195,10 @@ return [ ]; ``` -That's basically it. You define a map of interfaces to classes and define -how to configure them. When an interface is requested in constructor or -elsewhere, container creates an instance of a class and configures it as per -the configuration: +Basicamente é isso. Você define um mapa de interfaces para classes e define +como configurá-las. Quando uma interface é solicitada no construtor ou em +outro lugar, o container cria uma instância da classe e a configura conforme +a configuração: ```php final class MyAction @@ -212,11 +215,11 @@ final class MyAction } ``` -There are extra methods of declaring dependency configuration. +Há outras formas de declarar a configuração de dependências. -For simplest cases where there are no custom values needed and all the -constructor dependencies could be obtained from a container, you can use a -class name as a value. +Nos casos mais simples, em que não são necessários valores personalizados e +todas as dependências do construtor podem ser obtidas do container, você +pode usar um nome de classe como valor. ```php interface EngineInterface @@ -231,18 +234,18 @@ final class EngineMarkOne implements EngineInterface } ``` -In the above example, if we already have cache defined in the container, -nothing besides the class name is needed: +No exemplo acima, se já houver um cache definido no container, não é preciso +nada além do nome da classe: ```php return [ - // declare a class for an interface, resolve dependencies automatically + // declara uma classe para uma interface, resolvendo as dependências automaticamente EngineInterface::class => EngineMarkOne::class, ]; ``` -If you have a dependency that has public properties, you can configure it as -well. +Se você tiver uma dependência com propriedades públicas, também pode +configurá-la. ```php @@ -252,7 +255,7 @@ final class NameProvider } ``` -Here's how to do it for the example above: +Veja como fazer isso no exemplo acima: ```php NameProvider::class => [ @@ -261,11 +264,12 @@ NameProvider::class => [ ], ``` -In this example, you may notice `NameProvider` specified twice. The key is -what you may request as dependency and the value is how to create it. +Neste exemplo, você pode notar que `NameProvider` aparece duas vezes. A +chave é o que você pode solicitar como dependência, e o valor é como +criá-la. -If the configuration is tricky and requires some logic, a closure can be -used: +Se a configuração for complicada e exigir alguma lógica, você pode usar uma +closure: ```php MyServiceInterface::class => static function(ContainerInterface $container) { @@ -273,9 +277,9 @@ MyServiceInterface::class => static function(ContainerInterface $container) { }, ``` -Additionally, to `ContainerInterface`, you can request any registered -service directly as a closure parameter. The injector will automatically -resolve and inject these: +Além do `ContainerInterface`, você pode solicitar qualquer serviço +registrado diretamente como parâmetro da closure. O injector vai +resolvê-los e injetá-los automaticamente: ```php MyServiceInterface::class => static function(ConnectionInterface $db) { @@ -283,27 +287,28 @@ MyServiceInterface::class => static function(ConnectionInterface $db) { }, ``` -It's possible to use a static method call: +É possível usar a chamada de um método estático: ```php MyServiceInterface::class => [MyFactory::class, 'create'], ``` -Or an instance of an object: +Ou uma instância de um objeto: ```php MyServiceInterface::class => new MyService(), ``` -### Injecting dependencies properly +### Injetando dependências corretamente -Directly referencing a container in a class is a bad idea since the code -becomes non-generic, coupled to the container interface and, what's worse, -dependencies are becoming hidden. Because of that, Yii inverts the control -by automatically injecting objects from a container in some constructors and -methods based on method argument types. +Referenciar o container diretamente em uma classe é uma má ideia, porque o +código deixa de ser genérico, fica acoplado à interface do container e, pior +ainda, as dependências ficam escondidas. Por isso, o Yii inverte o +controle, injetando automaticamente objetos do container em alguns +construtores e métodos com base nos tipos dos argumentos. -This is primarily done in constructor and handing method of action handlers: +Isso é feito principalmente no construtor e no método de tratamento dos +handlers de action: ```php use \Yiisoft\Cache\CacheInterface; @@ -330,17 +335,17 @@ final readonly class MyController } ``` -Since it's [yiisoft/injector](https://github.com/yiisoft/injector) that -instantiates and calls action handler, it checks the constructor and method -argument types, gets dependencies of these types from a container and passes -them as arguments. That's usually called auto-wiring. It happens for -sub-dependencies as well, that's if you don't give dependency explicitly, -the container would check if it has such a dependency first. It's enough to -declare a dependency you need, and it would be got from a container -automatically. +Como é o [yiisoft/injector](https://github.com/yiisoft/injector) que +instancia e chama o handler de action, ele verifica os tipos dos argumentos +do construtor e do método, obtém do container as dependências desses tipos e +as passa como argumentos. Isso normalmente se chama autowiring. Acontece +também com as subdependências: se você não fornecer uma dependência +explicitamente, o container vai verificar primeiro se tem essa dependência. +Basta declarar a dependência de que você precisa, e ela será obtida do +container automaticamente. -## References +## Referências -- [Inversion of Control Containers and the Dependency Injection pattern by +- [Inversion of Control Containers and the Dependency Injection pattern, de Martin Fowler](https://martinfowler.com/articles/injection.html) diff --git a/src/pt-BR/guide/concept/events.md b/src/pt-BR/guide/concept/events.md index 0f3ac8fb..5337ff4f 100644 --- a/src/pt-BR/guide/concept/events.md +++ b/src/pt-BR/guide/concept/events.md @@ -1,28 +1,30 @@ -# Events +# Eventos -Events allow you to run custom code at certain execution points without -changing the code that emits the event. You attach a custom code called a -listener to an event. When the event is dispatched, the listener is -executed. +Eventos permitem executar código personalizado em determinados pontos da +execução, sem alterar o código que emite o evento. Você associa a um evento +um código personalizado chamado listener. Quando o evento é disparado, o +listener é executado. -For example, when a user signs up, you need to send a welcome email. You can -do it in `SignupService`. Later, when you also need to resize the user's -avatar image, the service has to know about that too. +Por exemplo, quando um usuário se cadastra, você precisa enviar um e-mail de +boas-vindas. Dá para fazer isso no `SignupService`. Mais tarde, quando você +também precisar redimensionar a imagem de avatar do usuário, o serviço vai +ter que saber disso também. -A cleaner flow is to dispatch a `UserSignedUp` event from -`SignupService`. The welcome email sender and the avatar processor listen to -this event. Additional signup-related work can be added by registering -another listener. +Um fluxo mais limpo é disparar um evento `UserSignedUp` a partir do +`SignupService`. O remetente do e-mail de boas-vindas e o processador de +avatar escutam esse evento. Trabalho adicional relacionado ao cadastro pode +ser incluído registrando outro listener. -Yii uses [yiisoft/yii-event](https://github.com/yiisoft/yii-event) for -application event configuration. It builds on the -[yiisoft/event-dispatcher](https://github.com/yiisoft/event-dispatcher) -package, which provides a [PSR-14](https://www.php-fig.org/psr/psr-14/) -compatible event dispatcher. +O Yii usa o [yiisoft/yii-event](https://github.com/yiisoft/yii-event) para a +configuração de eventos da aplicação. Ele é construído sobre o pacote +[yiisoft/event-dispatcher](https://github.com/yiisoft/event-dispatcher), que +fornece um event dispatcher compatível com +[PSR-14](https://www.php-fig.org/psr/psr-14/). -## Event classes +## Classes de evento -An event is an object. It usually contains data that listeners need: +Um evento é um objeto. Normalmente ele contém os dados de que os listeners +precisam: ```php final readonly class UserSignedUp @@ -33,40 +35,40 @@ final readonly class UserSignedUp } ``` -## Event listeners +## Listeners de eventos -An event listener is a [PHP -callable](https://www.php.net/manual/en/language.types.callable.php) that -receives an event: +Um listener de evento é um [callable do +PHP](https://www.php.net/manual/en/language.types.callable.php) que recebe +um evento: ```php static function (UserSignedUp $event): void { - // Send a welcome email. + // Envia um e-mail de boas-vindas. } ``` -You can also use an invokable class: +Você também pode usar uma classe invocável: ```php final readonly class WelcomeEmailSender { public function __invoke(UserSignedUp $event): void { - // Send a welcome email. + // Envia um e-mail de boas-vindas. } } ``` -## Configuring event listeners +## Configurando listeners de eventos -In an application, configure listeners in: +Em uma aplicação, configure os listeners em: -- `config/events.php` for all application types. -- `config/events-web.php` for web application events. -- `config/events-console.php` for console application events. +- `config/events.php` para todos os tipos de aplicação. +- `config/events-web.php` para eventos da aplicação web. +- `config/events-console.php` para eventos da aplicação de console. -The configuration is an array where keys are event class names and values -are lists of listeners: +A configuração é um array em que as chaves são os nomes das classes de +evento e os valores são listas de listeners: ```php eventDispatcher->dispatch(new UserSignedUp($form)); } } ``` -The dispatcher asks a listener provider for listeners that match the event -and calls them one by one. +O dispatcher pede a um listener provider os listeners que correspondem ao +evento e os chama um por um. -## Event listener order +## Ordem dos listeners -When several listeners are configured for the same event, they are called in -the order they are listed in the config. If an event implements -`Psr\EventDispatcher\StoppableEventInterface`, the dispatcher checks -`isPropagationStopped()` before calling the next listener. When it returns -`true`, the dispatcher stops processing the event. +Quando vários listeners são configurados para o mesmo evento, eles são +chamados na ordem em que aparecem na configuração. Se um evento implementa +`Psr\EventDispatcher\StoppableEventInterface`, o dispatcher verifica +`isPropagationStopped()` antes de chamar o próximo listener. Quando ele +retorna `true`, o dispatcher para de processar o evento. -Keep listeners independent where possible. Ordering is useful for technical -needs, but business logic is usually easier to maintain when each listener -can run on its own. +Mantenha os listeners independentes sempre que possível. A ordem é útil para +necessidades técnicas, mas a lógica de negócio costuma ser mais fácil de +manter quando cada listener consegue rodar sozinho. -## Event hierarchy +## Hierarquia de eventos -Events don't have names or wildcard matching. Event class names, interfaces, -and inheritance can be used when one listener should handle several related -events: +Eventos não têm nomes nem correspondência por curinga. Nomes de classes de +evento, interfaces e herança podem ser usados quando um listener precisa +tratar vários eventos relacionados: ```php interface DocumentEvent @@ -149,7 +152,8 @@ final readonly class AfterDocumentProcessed implements DocumentEvent } ``` -With the interface, you can listen to all document-related events: +Com a interface, você pode escutar todos os eventos relacionados a +documentos: ```php use Yiisoft\EventDispatcher\Provider\ListenerCollection; @@ -157,16 +161,16 @@ use Yiisoft\EventDispatcher\Provider\Provider; $listeners = (new ListenerCollection()) ->add(static function (DocumentEvent $event): void { - // Log document events. + // Registra em log os eventos de documentos. }); $provider = new Provider($listeners); ``` -## Manual listener provider setup +## Configuração manual do listener provider -In an application, use event configuration. For package-level code or tests, -you can create a listener provider manually: +Em uma aplicação, use a configuração de eventos. Para código de pacotes ou +testes, você pode criar um listener provider manualmente: ```php use Yiisoft\EventDispatcher\Dispatcher\Dispatcher; @@ -175,7 +179,7 @@ use Yiisoft\EventDispatcher\Provider\Provider; $listeners = (new ListenerCollection()) ->add(static function (UserSignedUp $event): void { - // Send a welcome email. + // Envia um e-mail de boas-vindas. }); $provider = new Provider($listeners); @@ -184,13 +188,13 @@ $dispatcher = new Dispatcher($provider); $dispatcher->dispatch(new UserSignedUp($form)); ``` -`ListenerCollection::add()` returns a new collection instance. Assign the result when building a collection step by step: +`ListenerCollection::add()` retorna uma nova instância da coleção. Atribua o resultado ao montar uma coleção passo a passo: ```php $listeners = new ListenerCollection(); $listeners = $listeners->add( static function (UserSignedUp $event): void { - // Send a welcome email. + // Envia um e-mail de boas-vindas. }, UserSignedUp::class, ); diff --git a/src/pt-BR/guide/concept/immutability.md b/src/pt-BR/guide/concept/immutability.md index f1faeeed..0094f2c3 100644 --- a/src/pt-BR/guide/concept/immutability.md +++ b/src/pt-BR/guide/concept/immutability.md @@ -1,31 +1,31 @@ -# Immutability +# Imutabilidade -Immutability means an object's state cannot change after it has been -created. Instead of modifying an instance, you create a new instance with -the desired changes. This approach is common for value objects such as -Money, IDs, and DTOs. It helps to avoid accidental side effects: methods -cannot silently change shared state, which makes code easier to reason -about. +Imutabilidade significa que o estado de um objeto não pode mudar depois que +ele é criado. Em vez de modificar uma instância, você cria uma nova +instância com as mudanças desejadas. Essa abordagem é comum em value +objects como Money, IDs e DTOs. Ela ajuda a evitar efeitos colaterais +acidentais: os métodos não conseguem alterar silenciosamente um estado +compartilhado, o que torna o código mais fácil de entender. -## Mutable pitfalls (what we avoid) +## Armadilhas da mutabilidade (o que evitamos) ```php -// A shared base query built once and reused: +// Uma query base compartilhada, montada uma vez e reutilizada: $base = Post::find()->where(['status' => Post::STATUS_PUBLISHED]); -// Somewhere deep in the code we only need one post: -$one = $base->limit(1)->one(); // mutates the underlying builder (sticky limit!) +// Em algum lugar profundo do código, precisamos de um só post: +$one = $base->limit(1)->one(); // altera o builder subjacente (o limit fica grudado!) -// Later we reuse the same $base expecting a full list: +// Depois reutilizamos o mesmo $base esperando a lista completa: $list = $base->orderBy(['created_at' => SORT_DESC])->all(); -// Oops: still limited to 1 because the previous limit(1) modified $base. +// Ops: continua limitado a 1, porque o limit(1) anterior modificou $base. ``` -## Creating an immutable object in PHP +## Criando um objeto imutável em PHP -There is no direct way to modify an instance, but you can use clone to -create a new instance with the desired changes. That is what `with*` -methods do. +Não há como modificar uma instância diretamente, mas você pode usar clone +para criar uma nova instância com as mudanças desejadas. É isso que os +métodos `with*` fazem. ```php final class Money @@ -99,27 +99,27 @@ final class Money $price = new Money(1000, 'USD'); $discounted = $price->withAmount(800); -// $price is still 1000 USD, $discounted is 800 USD +// $price continua 1000 USD, $discounted é 800 USD ``` -- We mark the class `final` to prevent subclass mutations; alternatively, - design for extension carefully. -- Validate in the constructor and `with*` methods so every instance is - always valid. +- Marcamos a classe como `final` para impedir mutações por subclasses; como + alternativa, projete a extensão com cuidado. +- Valide no construtor e nos métodos `with*`, para que toda instância seja + sempre válida. > [!TIP] -> If you define a simple DTO, you can use modern PHP `readonly` and leave properties `public`. The `readonly` keyword -> would ensure that the properties cannot be modified after the object is created. +> Se você define um DTO simples, pode usar o `readonly` do PHP moderno e deixar as propriedades `public`. A palavra-chave `readonly` +> garante que as propriedades não possam ser modificadas depois que o objeto é criado. -## Using clone (and why it is inexpensive) +## Usando clone (e por que é barato) -PHP's clone performs a shallow copy of the object. For immutable value -objects that contain only scalars or other immutable objects, shallow -cloning is enough and fast. In modern PHP, cloning small value objects is -inexpensive in both time and memory. +O clone do PHP faz uma cópia rasa do objeto. Para value objects imutáveis +que contêm apenas escalares ou outros objetos imutáveis, a clonagem rasa é +suficiente e rápida. No PHP moderno, clonar value objects pequenos é barato +em tempo e em memória. -If your object holds mutable sub-objects that must also be copied, implement -`__clone` to deep-clone them: +Se o seu objeto guarda subobjetos mutáveis que também precisam ser copiados, +implemente `__clone` para fazer a clonagem profunda deles: ```php final class Order @@ -135,8 +135,8 @@ final class Order public function __clone(): void { - // Money is immutable in our example, so a deep clone is not required. - // If it were mutable, you could do: $this->total = clone $this->total; + // Money é imutável no nosso exemplo, então a clonagem profunda não é necessária. + // Se fosse mutável, você poderia fazer: $this->total = clone $this->total; } public function withTotal(Money $total): self @@ -148,13 +148,14 @@ final class Order } ``` -## Usage style +## Estilo de uso -- Build a value object once and pass it around. If you need a change, use a - `with*` method that returns a new instance. -- Prefer scalar/immutable fields inside immutable objects; if a field can - mutate, isolate it and deep-clone in `__clone` when needed. +- Crie um value object uma vez e passe-o adiante. Se precisar de uma + mudança, use um método `with*` que retorna uma nova instância. +- Prefira campos escalares/imutáveis dentro de objetos imutáveis; se um + campo puder mudar, isole-o e faça a clonagem profunda em `__clone` quando + necessário. -Immutability aligns well with Yii's preference for predictable, -side-effect-free code and makes services, caching, and configuration more -robust. +A imutabilidade combina bem com a preferência do Yii por código previsível e +sem efeitos colaterais, e torna serviços, cache e configuração mais +robustos. diff --git a/src/pt-BR/guide/structure/action.md b/src/pt-BR/guide/structure/action.md index a377ae66..a94bb4d0 100644 --- a/src/pt-BR/guide/structure/action.md +++ b/src/pt-BR/guide/structure/action.md @@ -1,12 +1,13 @@ # Actions -In a web application, the request URL determines what's executed. Matching -is made by a router configured with multiple routes. Each route can be -attached to a middleware that, given request, produces a response. Since -middleware overall could be chained and can pass actual handling to the next -middleware, we call the middleware actually doing the job an action. - -There are multiple ways to describe an action. The simplest one is using a +Em uma aplicação web, a URL da requisição determina o que é executado. A +correspondência é feita por um router configurado com várias rotas. Cada +rota pode ser associada a um middleware que, dada a requisição, produz uma +resposta. Como os middlewares podem ser encadeados e podem passar o +tratamento efetivo para o próximo middleware, chamamos de action o +middleware que realmente faz o trabalho. + +Há várias formas de descrever uma action. A mais simples é usando uma closure: ```php @@ -21,9 +22,10 @@ Route::get('/')->action(function (ServerRequestInterface $request) use ($respons }); ``` -It's fine for simple handling since any more complicated one would require -getting dependencies, so a good idea would be moving the handling to a class -method. Callback middleware could be used for the purpose: +Isso funciona bem para um tratamento simples, já que qualquer coisa mais +complicada exigiria obter dependências; então, uma boa ideia é mover o +tratamento para um método de classe. Um middleware de callback pode ser +usado para isso: ```php use Yiisoft\Router\Route; @@ -31,7 +33,7 @@ use Yiisoft\Router\Route; Route::get('/')->action(FrontPageAction::class), ``` -The class itself would be like: +A classe em si seria assim: ```php use \Psr\Http\Message\ServerRequestInterface; @@ -41,13 +43,13 @@ final readonly class FrontPageAction { public function __invoke(ServerRequestInterface $request): ResponseInterface { - // build response for a front page + // monta a resposta para a página inicial } } ``` -For many cases, it makes sense to group handling for many routes into a -single class: +Em muitos casos, faz sentido agrupar o tratamento de várias rotas em uma +única classe: ```php @@ -57,7 +59,7 @@ Route::get('/post/index')->action([PostController::class, 'actionIndex']), Route::get('/post/view/{id:\d+}')->action([PostController::class, 'actionView']), ``` -The class itself would look like the following: +A classe em si ficaria assim: ```php use \Psr\Http\Message\ServerRequestInterface; @@ -68,7 +70,7 @@ final readonly class PostController { public function actionIndex(ServerRequestInterface $request): ResponseInterface { - // render posts list + // renderiza a lista de posts } @@ -78,23 +80,23 @@ final readonly class PostController int $id, ): ResponseInterface { - // render a single post by $id + // renderiza um único post pelo $id } } ``` -We usually call such a class "controller." +Normalmente chamamos uma classe assim de "controller". -The `{id}` part of the `/post/view/{id:\d+}` route is a named route -parameter. Route parameters are available from -`Yiisoft\Router\CurrentRoute`. To receive one as an action argument, add the -`RouteArgument` attribute to the corresponding parameter. The attribute name -should match the route parameter name. +A parte `{id}` da rota `/post/view/{id:\d+}` é um parâmetro de rota +nomeado. Os parâmetros de rota estão disponíveis em +`Yiisoft\Router\CurrentRoute`. Para recebê-lo como argumento da action, +adicione o atributo `RouteArgument` ao parâmetro correspondente. O nome no +atributo deve corresponder ao nome do parâmetro de rota. ## Autowiring -Both constructors of action-classes and action-methods are automatically getting services from - the dependency injection container: +Tanto os construtores das classes de action quanto os métodos de action recebem automaticamente serviços do + container de injeção de dependência: ```php use \Psr\Http\Message\ServerRequestInterface; @@ -112,17 +114,17 @@ final readonly class PostController public function actionIndex(ServerRequestInterface $request, LoggerInterface $logger): ResponseInterface { $logger->debug('Rendering posts list'); - // render posts list + // renderiza a lista de posts } public function actionView(ServerRequestInterface $request): ResponseInterface { - // render a single post + // renderiza um único post } } ``` -In the above example `PostRepository` is injected automatically via -constructor. That means it is available in every action. Logger is injected -into `index` action only. +No exemplo acima, `PostRepository` é injetado automaticamente pelo +construtor. Isso significa que ele fica disponível em todas as actions. O +logger é injetado apenas na action `index`. diff --git a/src/pt-BR/guide/structure/application.md b/src/pt-BR/guide/structure/application.md index 3fff6311..b8122cff 100644 --- a/src/pt-BR/guide/structure/application.md +++ b/src/pt-BR/guide/structure/application.md @@ -1,18 +1,19 @@ -# Application +# Aplicação -The primary purpose of the web application and its runner in Yii3 is to -process requests to get responses. +O principal propósito da aplicação web e do seu runner no Yii3 é processar +requisições para obter respostas. -Typically, the runtime consists of: +Normalmente, o ciclo de execução consiste em: -1. Startup. Get config, create an instance of container and do additional - environment initialization such as registering error handler, so it can - handle errors occurring. Fire `ApplicationStartup` event. -2. Handle requests via passing request objects to middleware dispatcher to - execute [middleware stack](middleware.md) and get a response object. In - usual PHP applications, it's done once. In [environments such as - RoadRunner](../tutorial/using-with-event-loop.md), it could be done - multiple times with the same application instance. Response object is - converted into an actual HTTP response by using emitter. Fire - `AfterEmit` event. -3. Shutdown. Fire `ApplicationShutdown` event. +1. Inicialização. Obter a configuração, criar uma instância do container e + fazer a inicialização adicional do ambiente, como registrar o error + handler para que ele possa tratar os erros que ocorrerem. Disparar o + evento `ApplicationStartup`. +2. Tratar requisições passando os objetos de requisição para o dispatcher de + middlewares, que executa a [pilha de middlewares](middleware.md) e obtém + um objeto de resposta. Em aplicações PHP comuns, isso é feito uma vez. Em + [ambientes como o RoadRunner](../tutorial/using-with-event-loop.md), pode + ser feito várias vezes com a mesma instância da aplicação. O objeto de + resposta é convertido em uma resposta HTTP real usando o emitter. + Disparar o evento `AfterEmit`. +3. Encerramento. Disparar o evento `ApplicationShutdown`. diff --git a/src/pt-BR/guide/structure/designing-packages.md b/src/pt-BR/guide/structure/designing-packages.md index 513245d9..7ca99335 100644 --- a/src/pt-BR/guide/structure/designing-packages.md +++ b/src/pt-BR/guide/structure/designing-packages.md @@ -1,20 +1,20 @@ -# Designing packages for Yii applications +# Projetando pacotes para aplicações Yii -This page describes how to design a Composer package that adds behavior to a -Yii application through configuration. Use it when your package needs to -register services, routes, events, commands, assets, migrations, -translations, or a theme. +Esta página descreve como projetar um pacote Composer que acrescenta +comportamento a uma aplicação Yii por meio de configuração. Use-a quando o +seu pacote precisar registrar serviços, rotas, eventos, comandos, assets, +migrations, traduções ou um tema. -For installing and updating packages in an application, see [Using -packages](package.md). +Para instalar e atualizar pacotes em uma aplicação, veja [Usando +pacotes](package.md). -## Composer metadata +## Metadados do Composer -Each package must have a `composer.json` file in its root directory. At -minimum, define a package name, dependencies, autoloading, and Yii config -metadata when the package integrates with a Yii application. +Todo pacote precisa ter um arquivo `composer.json` na pasta raiz. No mínimo, +defina o nome do pacote, as dependências, o autoload e os metadados de +configuração do Yii quando o pacote se integra a uma aplicação Yii. -Use a package name in the `vendor-name/project-name` format: +Use um nome de pacote no formato `vendor-name/project-name`: ```json { @@ -33,17 +33,19 @@ Use a package name in the `vendor-name/project-name` format: } ``` -Use stable dependency constraints for stable releases. Avoid using `yiisoft` -as your vendor name because it is reserved for Yii packages. +Use restrições de dependência estáveis em releases estáveis. Evite usar +`yiisoft` como nome de vendor, porque ele é reservado para os pacotes do +Yii. -If your package requires a Yii application, prefixing the project name with -`yii-` can make that clear on Packagist. +Se o seu pacote exige uma aplicação Yii, prefixar o nome do projeto com +`yii-` pode deixar isso claro no Packagist. -## Package layout +## Estrutura do pacote -A Yii-aware package is a regular Composer package with PHP classes, optional -resource files, and optional config files. Keep the configuration in a -predictable directory and make the public API explicit: +Um pacote compatível com o Yii é um pacote Composer comum, com classes PHP, +arquivos de recursos opcionais e arquivos de configuração opcionais. +Mantenha a configuração em uma pasta previsível e deixe a API pública +explícita: ``` composer.json @@ -68,14 +70,14 @@ views/ ... ``` -Use only the files your package needs. For example, a package with console -commands but no web routes does not need `routes.php`. +Use apenas os arquivos de que o seu pacote precisa. Por exemplo, um pacote +com comandos de console, mas sem rotas web, não precisa de `routes.php`. -## Config plugin metadata +## Metadados do plugin de configuração -Yii applications use [yiisoft/config](https://github.com/yiisoft/config) to -discover package configuration. Declare package config files in the -`extra.config-plugin` section of `composer.json`: +Aplicações Yii usam o [yiisoft/config](https://github.com/yiisoft/config) +para descobrir a configuração dos pacotes. Declare os arquivos de +configuração do pacote na seção `extra.config-plugin` do `composer.json`: ```json { @@ -101,35 +103,36 @@ discover package configuration. Declare package config files in the } ``` -Each `config-plugin` key is a config group name and each value is a path -relative to the package root. +Cada chave de `config-plugin` é o nome de um grupo de configuração, e cada +valor é um caminho relativo à raiz do pacote. -Use the common, web, and console groups consistently: +Use os grupos comuns, web e de console de forma consistente: -- `params`, `di`, `di-providers`, `di-delegates`, `events`, and `bootstrap` - apply to both web and console entry points. -- `params-web`, `di-web`, `di-providers-web`, `events-web`, `bootstrap-web`, - and `routes` apply to web entry points. -- `params-console`, `di-console`, `di-providers-console`, `events-console`, - and `bootstrap-console` apply to console entry points. +- `params`, `di`, `di-providers`, `di-delegates`, `events` e `bootstrap` + valem para os pontos de entrada web e de console. +- `params-web`, `di-web`, `di-providers-web`, `events-web`, `bootstrap-web` + e `routes` valem para os pontos de entrada web. +- `params-console`, `di-console`, `di-providers-console`, `events-console` e + `bootstrap-console` valem para os pontos de entrada de console. -If your package defines a new config group, document how an application -should load that group. Prefer the standard groups when you integrate with -Yii services because application templates and Yii packages already use -these names. +Se o seu pacote define um novo grupo de configuração, documente como a +aplicação deve carregar esse grupo. Prefira os grupos padrão ao se integrar +com serviços do Yii, porque os templates de aplicação e os pacotes do Yii já +usam esses nomes. -After users install, update, remove, or dump Composer autoload files, the -config plugin rebuilds the merge plan that Yii reads at runtime. If users -edit their root package configuration manually, ask them to run: +Depois que os usuários instalam, atualizam, removem ou fazem dump dos +arquivos de autoload do Composer, o plugin de configuração reconstrói o +merge plan que o Yii lê em tempo de execução. Se os usuários editarem +manualmente a configuração do pacote raiz, peça que executem: ```sh composer yii-config-rebuild ``` -## Parameters +## Parâmetros -Put default options in `config/params.php`. Group package parameters under -the Composer package name to avoid collisions: +Coloque as opções padrão em `config/params.php`. Agrupe os parâmetros do +pacote sob o nome do pacote no Composer para evitar colisões: ```php register(BlogAsset::class); ``` -Use `$sourcePath` for files shipped inside the package. Use `$basePath` and -`$baseUrl` as the public target where the asset manager publishes them. +Use `$sourcePath` para os arquivos que vêm dentro do pacote. Use `$basePath` +e `$baseUrl` como o destino público onde o asset manager os publica. ## Migrations -Packages that need database schema changes should ship migrations and add -their namespace or path to `yiisoft/db-migration` parameters. +Pacotes que precisam de mudanças no esquema do banco de dados devem trazer +migrations e adicionar o namespace ou o caminho delas aos parâmetros do +`yiisoft/db-migration`. -For namespaced migrations: +Para migrations com namespace: ```php translate('post.created', category: 'vendor-blog'); ``` -## Themes +## Temas -A package can ship view files and assets for a theme. Do not activate it -from vendor package configuration. Instead, document the root application -configuration needed to enable it. For the application template, this -belongs in `config/web/params.php`: +Um pacote pode trazer arquivos de view e assets para um tema. Não o ative +pela configuração do pacote em vendor. Em vez disso, documente a +configuração da aplicação raiz necessária para habilitá-lo. No template de +aplicação, isso fica em `config/web/params.php`: ```php debug(); -// Run application: +// Executa a aplicação: $runner->run(); ``` -## Console Applications +## Aplicações de console -Similarly, the following is the code for the entry script of a console -application: +Da mesma forma, este é o código do script de entrada de uma aplicação de +console: ```php #!/usr/bin/env php @@ -105,12 +106,12 @@ try { } ``` -## Alternative runtimes +## Runtimes alternativos -For alternative runtimes such as FrankenPHP, Rapira, RoadRunner, or Swoole, -special entry scripts should be used. See: +Para runtimes alternativos como FrankenPHP, Rapira, RoadRunner ou Swoole, +devem ser usados scripts de entrada especiais. Veja: -- [Using Yii with FrankenPHP](../tutorial/using-yii-with-frankenphp.md) -- [Using Yii with Rapira](../tutorial/using-yii-with-rapira.md) -- [Using Yii with RoadRunner](../tutorial/using-yii-with-roadrunner.md) -- [Using Yii with Swoole](../tutorial/using-yii-with-swoole.md) +- [Usando o Yii com FrankenPHP](../tutorial/using-yii-with-frankenphp.md) +- [Usando o Yii com Rapira](../tutorial/using-yii-with-rapira.md) +- [Usando o Yii com RoadRunner](../tutorial/using-yii-with-roadrunner.md) +- [Usando o Yii com Swoole](../tutorial/using-yii-with-swoole.md) diff --git a/src/pt-BR/guide/structure/middleware.md b/src/pt-BR/guide/structure/middleware.md index 46fbc188..1ea6d5d8 100644 --- a/src/pt-BR/guide/structure/middleware.md +++ b/src/pt-BR/guide/structure/middleware.md @@ -1,39 +1,43 @@ # Middleware -Yii works with HTTP using the abstraction layer built around [PSR-7 HTTP -message interfaces](https://www.php-fig.org/psr/psr-7/) and [PSR-15 request -handler/middleware interfaces](https://www.php-fig.org/psr/psr-15/). +O Yii trabalha com HTTP usando a camada de abstração construída em torno das +[interfaces de mensagens HTTP da PSR-7](https://www.php-fig.org/psr/psr-7/) +e das [interfaces de request handler/middleware da +PSR-15](https://www.php-fig.org/psr/psr-15/). -The application is composed of one or several middleware. Middleware runs -between request and response. When the URL is requested, the request object -is passed to the middleware dispatcher that starts executing middleware one -after another. Each middleware, given the request, can: +A aplicação é composta por um ou vários middlewares. O middleware roda entre +a requisição e a resposta. Quando a URL é requisitada, o objeto de +requisição é passado para o dispatcher de middlewares, que começa a executar +os middlewares um após o outro. Cada middleware, dada a requisição, pode: -- Pass the request to the next middleware performing some work before / - after it. -- Form the response and return it. +- Passar a requisição para o próximo middleware, fazendo algum trabalho + antes / depois dele. +- Montar a resposta e devolvê-la. -Depending on middleware used, application behavior may vary significantly. +Dependendo dos middlewares usados, o comportamento da aplicação pode variar +bastante. ![Middleware](/images/guide/middleware.svg) -In the above each next middleware wraps the previous -middleware. Alternatively, it could be presented as follows: +Acima, cada middleware seguinte envolve o anterior. Também é possível +representar assim: ![Middleware](/images/guide/middleware_alternative.svg) -## Using middleware +## Usando middlewares -Any [PSR-15](https://www.php-fig.org/psr/psr-15/) compatible middleware -could be used with Yii, and there are many. Say, you need to add basic -authentication to one of the application URLs. URL-dependent middleware is -configured using router, so you need to change the router factory. +Qualquer middleware compatível com a +[PSR-15](https://www.php-fig.org/psr/psr-15/) pode ser usado com o Yii, e +existem muitos. Digamos que você precise adicionar autenticação básica a +uma das URLs da aplicação. Middlewares que dependem da URL são configurados +pelo router, então você precisa alterar a router factory. -Authentication middleware is implemented by -`middlewares/http-authentication` package so execute `composer require -middlewares/http-authentication` in the application root directory. +O middleware de autenticação é implementado pelo pacote +`middlewares/http-authentication`, então execute `composer require +middlewares/http-authentication` na pasta raiz da aplicação. -Now register the middleware in DI container configuration `config/web.php`: +Agora registre o middleware na configuração do container de DI, +`config/web.php`: ```php withAttribute('answer', 42); return $handler->handle($request); ``` -To get it in the next middleware: +Para obtê-los no próximo middleware: ```php $answer = $request->getAttribute('answer'); ``` -### Capturing response to manipulate it +### Capturando a resposta para manipulá-la -You may want to capture the response to manipulate it. It could be useful -for adding CORS headers, gzipping content, etc. +Você pode querer capturar a resposta para manipulá-la. Isso pode ser útil +para adicionar headers CORS, compactar o conteúdo com gzip etc. ```php $response = $handler->handle($request); -// extra handing +// tratamento extra return $response; ``` diff --git a/src/pt-BR/guide/structure/module.md b/src/pt-BR/guide/structure/module.md index 6cb01de4..5e487a81 100644 --- a/src/pt-BR/guide/structure/module.md +++ b/src/pt-BR/guide/structure/module.md @@ -1,18 +1,18 @@ -# Modules +# Módulos -A module is an application part grouped around a business context or a -reusable feature. In Yii, this is a design boundary, not a required base -class. A module can be: +Um módulo é uma parte da aplicação agrupada em torno de um contexto de +negócio ou de um recurso reutilizável. No Yii, isso é uma fronteira de +design, não uma classe base obrigatória. Um módulo pode ser: -- application code under the `App\` namespace; -- a [Composer package](package.md) installed into `vendor/`; -- code that starts in the application and is later extracted into a package. +- código da aplicação no namespace `App\`; +- um [pacote Composer](package.md) instalado em `vendor/`; +- código que começa na aplicação e depois é extraído para um pacote. -Use a module when a group of actions, domain services, repositories, event -handlers, views, assets, commands, and related configuration changes -together and has a name that makes sense to the business. +Use um módulo quando um grupo de actions, serviços de domínio, repositórios, +handlers de eventos, views, assets, comandos e a configuração relacionada +mudam juntos e têm um nome que faz sentido para o negócio. -For example, a blog module can live in an application as: +Por exemplo, um módulo de blog pode ficar na aplicação assim: ``` src/ @@ -26,51 +26,55 @@ src/ index.php ``` -The same structure can later become a Composer package by changing the -namespace and adding package metadata and configuration files. See -[Designing packages](designing-packages.md) for package-specific details. +A mesma estrutura pode virar um pacote Composer mais tarde, mudando o +namespace e adicionando os metadados e os arquivos de configuração do +pacote. Veja [Projetando pacotes](designing-packages.md) para os detalhes +específicos de pacotes. -## Module boundaries +## Fronteiras de módulos -Keep module code together by context first and by technical type -second. This is close to the [vertical -slices](../../cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md) -approach, but at a larger application-structure boundary. Prefer -`App\Blog\Post\PostRepositoryInterface` over a global -`App\Repository\PostRepositoryInterface` when the repository belongs to blog -posts only. +Mantenha o código do módulo agrupado primeiro por contexto e depois por tipo +técnico. Isso se aproxima da abordagem de [vertical +slices](../../cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md), +mas numa fronteira maior da estrutura da aplicação. Prefira +`App\Blog\Post\PostRepositoryInterface` a um +`App\Repository\PostRepositoryInterface` global quando o repositório +pertence apenas aos posts do blog. -Treat module classes as a public API only when another module is expected to -use them. Good public API classes are usually: +Trate as classes de um módulo como API pública apenas quando se espera que +outro módulo as use. Boas classes de API pública normalmente são: -- commands or queries that express a use case; -- DTOs or value objects passed between modules; -- interfaces for services another module may call; -- events emitted by the module. +- comandos ou queries que expressam um caso de uso; +- DTOs ou value objects trocados entre módulos; +- interfaces de serviços que outro módulo pode chamar; +- eventos emitidos pelo módulo. -Keep implementation classes private to the module namespace. Other modules -should not depend on `App\Blog\Post\InMemoryPostRepository` or a controller -action directly. They should depend on an interface, a use case class, or an -event. +Mantenha as classes de implementação privadas ao namespace do módulo. Outros +módulos não devem depender diretamente de +`App\Blog\Post\InMemoryPostRepository` ou de uma action de controller. Eles +devem depender de uma interface, de uma classe de caso de uso ou de um +evento. -## Interfaces between modules +## Interfaces entre módulos -Put an interface where the contract belongs: +Coloque a interface onde o contrato pertence: -- If the interface describes a capability provided by a module, place it in - that module. For example, `App\Blog\Post\PostRepositoryInterface` belongs - to the blog module because it describes how blog posts are read. -- If the interface describes what a module needs from the outside world, - place it in the consuming module. For example, - `App\Order\Customer\CustomerVerifierInterface` belongs to the order module - if orders only need a yes-or-no customer check. The customer module, an - application adapter, or a package can provide the implementation. +- Se a interface descreve uma capacidade fornecida por um módulo, coloque-a + nesse módulo. Por exemplo, `App\Blog\Post\PostRepositoryInterface` + pertence ao módulo de blog porque descreve como os posts do blog são + lidos. +- Se a interface descreve o que um módulo precisa do mundo externo, + coloque-a no módulo consumidor. Por exemplo, + `App\Order\Customer\CustomerVerifierInterface` pertence ao módulo de + pedidos se os pedidos só precisam de uma verificação de cliente do tipo + sim ou não. O módulo de clientes, um adaptador da aplicação ou um pacote + pode fornecer a implementação. -This keeps dependencies explicit. A module can depend on another module's -public contract, but it should not reach into another module's internal -implementation classes. +Isso mantém as dependências explícitas. Um módulo pode depender do contrato +público de outro módulo, mas não deve acessar as classes de implementação +internas de outro módulo. -First, define the interface in the module: +Primeiro, defina a interface no módulo: ```php [ @@ -188,7 +196,7 @@ config file. Change the `routes` group in `config/configuration.php`: ], ``` -Then create `config/common/routes/blog.php`: +Depois crie `config/common/routes/blog.php`: ```php [!WARNING] -> Never edit files in `vendor/` directly. Change application configuration, extend classes, decorate services, or -> contribute fixes to the package instead. +> Nunca edite arquivos em `vendor/` diretamente. Em vez disso, altere a configuração da aplicação, estenda classes, decore serviços ou +> contribua com correções para o pacote. -Package classes are available through Composer autoloading after -installation. See [Autoloading](../concept/autoloading.md) for details. +As classes dos pacotes ficam disponíveis pelo autoload do Composer após a +instalação. Veja [Autoload](../concept/autoloading.md) para mais detalhes. -## Updating packages +## Atualizando pacotes -Update a package within the version constraint recorded in `composer.json`: +Atualize um pacote dentro da restrição de versão registrada no +`composer.json`: ```sh composer update vendor-name/package-name ``` -Change the accepted version constraint with `composer require`: +Altere a restrição de versão aceita com `composer require`: ```sh composer require vendor-name/package-name:^2.0 ``` -After updating a Yii-aware package, Composer rebuilds Yii's configuration -merge plan. If you changed configuration group mappings manually, rebuild it -explicitly: +Depois de atualizar um pacote compatível com o Yii, o Composer reconstrói o +merge plan de configuração do Yii. Se você alterou manualmente os +mapeamentos de grupos de configuração, reconstrua-o explicitamente: ```sh composer yii-config-rebuild ``` -## Removing packages +## Removendo pacotes -Remove a package with: +Remova um pacote com: ```sh composer remove vendor-name/package-name ``` -Then remove application code and configuration that referenced classes, -services, routes, commands, assets, migrations, or translations from that -package. +Em seguida, remova o código e a configuração da aplicação que referenciavam +classes, serviços, rotas, comandos, assets, migrations ou traduções desse +pacote. -## Private packages +## Pacotes privados -For private code, configure Composer repositories in the application -`composer.json`. Common options are: +Para código privado, configure repositórios do Composer no `composer.json` +da aplicação. As opções mais comuns são: -- `vcs` for a Git repository. -- `path` for a local package during development. -- `composer` for a private Composer repository. +- `vcs` para um repositório Git. +- `path` para um pacote local durante o desenvolvimento. +- `composer` para um repositório Composer privado. -For example, to work with a package located next to the application: +Por exemplo, para trabalhar com um pacote localizado ao lado da aplicação: ```json { @@ -94,25 +96,26 @@ For example, to work with a package located next to the application: } ``` -Then install it normally: +Depois, instale-o normalmente: ```sh composer require vendor/blog ``` -Read more in the [Composer repository -documentation](https://getcomposer.org/doc/05-repositories.md). +Leia mais na [documentação de repositórios do +Composer](https://getcomposer.org/doc/05-repositories.md). -## Package configuration +## Configuração de pacotes -Some Yii packages provide default configuration through -[yiisoft/config](https://github.com/yiisoft/config). After installation, -the package configuration becomes part of the vendor layer and the -application can override it in the root package configuration. +Alguns pacotes Yii fornecem configuração padrão por meio do +[yiisoft/config](https://github.com/yiisoft/config). Após a instalação, a +configuração do pacote passa a fazer parte da camada vendor, e a aplicação +pode sobrescrevê-la na configuração do pacote raiz. -Prefer partial overrides in application config files over copying whole -package config files. For example, override only the parameter or service -definition you need. +Prefira sobrescritas parciais nos arquivos de configuração da aplicação em +vez de copiar arquivos de configuração inteiros do pacote. Por exemplo, +sobrescreva apenas o parâmetro ou a definição de serviço de que você +precisa. -For more details, see [Configuration](../concept/configuration.md) and -[Designing packages for Yii applications](designing-packages.md). +Para mais detalhes, veja [Configuração](../concept/configuration.md) e +[Projetando pacotes para aplicações Yii](designing-packages.md). From 261668f583556271c56bf7700e9b8d4183aec757 Mon Sep 17 00:00:00 2001 From: Yuri Neves Date: Fri, 23 Oct 2026 14:18:13 -0300 Subject: [PATCH 05/11] Translate guide requests, security, caching, databases and REST to Brazilian Portuguese --- .../po/pt-BR/guide_caching_data.md.po | 140 +++-- .../po/pt-BR/guide_caching_overview.md.po | 18 +- .../pt-BR/guide_databases_db-migrations.md.po | 408 ++++++++++----- .../po/pt-BR/guide_rest_quick-start.md.po | 291 +++++++++-- .../po/pt-BR/guide_runtime_logging.md.po | 2 +- .../pt-BR/guide_security_authentication.md.po | 205 ++++++-- .../pt-BR/guide_security_authorization.md.po | 494 +++++++++++++++--- .../pt-BR/guide_security_best-practices.md.po | 198 ++++--- .../pt-BR/guide_security_cryptography.md.po | 88 ++-- .../po/pt-BR/guide_security_overview.md.po | 22 +- .../po/pt-BR/guide_security_passwords.md.po | 30 +- .../guide_security_trusted-request.md.po | 30 +- src/pt-BR/guide/caching/data.md | 250 ++++----- src/pt-BR/guide/caching/overview.md | 33 +- src/pt-BR/guide/databases/db-migrations.md | 390 +++++++------- src/pt-BR/guide/rest/quick-start.md | 143 ++--- src/pt-BR/guide/runtime/logging.md | 2 +- src/pt-BR/guide/security/authentication.md | 148 +++--- src/pt-BR/guide/security/authorization.md | 355 +++++++------ src/pt-BR/guide/security/best-practices.md | 290 +++++----- src/pt-BR/guide/security/cryptography.md | 92 ++-- src/pt-BR/guide/security/overview.md | 28 +- src/pt-BR/guide/security/passwords.md | 40 +- src/pt-BR/guide/security/trusted-request.md | 39 +- 24 files changed, 2350 insertions(+), 1386 deletions(-) diff --git a/_translations/po/pt-BR/guide_caching_data.md.po b/_translations/po/pt-BR/guide_caching_data.md.po index ff3656c5..8fc3625c 100644 --- a/_translations/po/pt-BR/guide_caching_data.md.po +++ b/_translations/po/pt-BR/guide_caching_data.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2025-09-11 10:15+0500\n" "PO-Revision-Date: 2025-09-11 10:15+0500\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,28 +19,28 @@ msgstr "" #: ../../guide/en/caching/data.md #, no-wrap msgid "Data caching" -msgstr "" +msgstr "Cache de dados" #. type: Plain text #: ../../guide/en/caching/data.md msgid "Data caching is about storing some PHP variables in a cache and retrieving them later from the cache. It's also the foundation for more advanced caching features, such as [page caching](page.md)." -msgstr "" +msgstr "O cache de dados consiste em guardar algumas variáveis PHP no cache e recuperá-las dele mais tarde. Ele também é a base para recursos de cache mais avançados, como o [cache de páginas](page.md)." #. type: Plain text #: ../../guide/en/caching/data.md msgid "To use cache, install [yiisoft/cache](https://github.com/yiisoft/cache) package:" -msgstr "" +msgstr "Para usar o cache, instale o pacote [yiisoft/cache](https://github.com/yiisoft/cache):" #. type: Fenced code block (shell) #: ../../guide/en/caching/data.md #, no-wrap msgid "composer require yiisoft/cache\n" -msgstr "" +msgstr "composer require yiisoft/cache\n" #. type: Plain text #: ../../guide/en/caching/data.md msgid "The following code is a typical usage pattern of data caching, where `$cache` refers to a `Cache` instance from the package:" -msgstr "" +msgstr "O código a seguir é um padrão típico de uso do cache de dados, em que `$cache` se refere a uma instância de `Cache` do pacote:" #. type: Fenced code block (php) #: ../../guide/en/caching/data.md @@ -59,62 +59,74 @@ msgid "" " return $data;\n" "}\n" msgstr "" +"public function getTopProducts(\\Yiisoft\\Cache\\CacheInterface $cache): array\n" +"{\n" +" $key = ['top-products', $count = 10];\n" +" \n" +" // Tenta recuperar $data do cache.\n" +" $data = $cache->getOrSet($key, function (\\Psr\\SimpleCache\\CacheInterface $cache) use ($count) {\n" +" // $data não está no cache, então calcula do zero.\n" +" return getTopProductsFromDatabase($count);\n" +" }, 3600);\n" +" \n" +" return $data;\n" +"}\n" #. type: Plain text #: ../../guide/en/caching/data.md msgid "When cache has data associated with the `$key`, it returns the cached value. Otherwise, it executes the passed anonymous function to calculate the value to cache and return." -msgstr "" +msgstr "Quando o cache tem dados associados à `$key`, ele retorna o valor em cache. Caso contrário, executa a função anônima passada para calcular o valor a ser guardado no cache e retornado." #. type: Plain text #: ../../guide/en/caching/data.md msgid "If the anonymous function requires some data from the outer scope, you can pass it with the `use` statement." -msgstr "" +msgstr "Se a função anônima precisar de dados do escopo externo, você pode passá-los com a instrução `use`." #. type: Title ## #: ../../guide/en/caching/data.md #, no-wrap msgid "Cache handlers" -msgstr "" +msgstr "Drivers de cache" #. type: Plain text #: ../../guide/en/caching/data.md msgid "The cache service uses [PSR-16](https://www.php-fig.org/psr/psr-16/) compatible cache handlers which represent various cache storages, such as memory, files, and databases." -msgstr "" +msgstr "O serviço de cache usa drivers de cache compatíveis com a [PSR-16](https://www.php-fig.org/psr/psr-16/), que representam vários tipos de armazenamento, como memória, arquivos e bancos de dados." #. type: Plain text #: ../../guide/en/caching/data.md msgid "Yii provides the following handlers:" -msgstr "" +msgstr "O Yii fornece os seguintes drivers:" #. type: Bullet: '- ' #: ../../guide/en/caching/data.md msgid "`NullCache` — a cache placeholder which does no real caching. The purpose of this handler is to simplify the code that needs to check the availability of cache. For example, during development or if the server doesn't have actual cache support, you may configure a cache service to use this handler. When you enable actual cache support, you can switch to using the corresponding cache handler. In both cases, you may use the same code without extra checks." -msgstr "" +msgstr "`NullCache` — um substituto de cache que não faz cache de verdade. O objetivo desse driver é simplificar o código que precisa verificar se há cache disponível. Por exemplo, durante o desenvolvimento ou se o servidor não tiver suporte real a cache, você pode configurar o serviço de cache para usar esse driver. Quando você habilitar o suporte real a cache, pode trocar para o driver correspondente. Nos dois casos, você pode usar o mesmo código, sem verificações extras." #. type: Bullet: '- ' #: ../../guide/en/caching/data.md msgid "`ArrayCache` — provides caching for the current request only by storing the values in an array." -msgstr "" +msgstr "`ArrayCache` — faz cache apenas durante a requisição atual, guardando os valores em um array." #. type: Bullet: '- ' #: ../../guide/en/caching/data.md msgid "[APCu](https://github.com/yiisoft/cache-apcu) - uses a PHP [APC](https://secure.php.net/manual/en/book.apc.php) extension. You can consider this option as the fastest one when dealing with cache for a centralized thick application (e.g., one server, no dedicated load balancers, etc.)." -msgstr "" +msgstr "[APCu](https://github.com/yiisoft/cache-apcu) - usa a extensão [APC](https://secure.php.net/manual/en/book.apc.php) do PHP. Você pode considerar esta a opção mais rápida ao lidar com cache em uma aplicação centralizada e robusta (por exemplo, um servidor, sem load balancers dedicados etc.)." #. type: Bullet: '- ' #: ../../guide/en/caching/data.md msgid "[Database](https://github.com/yiisoft/cache-db) — uses a database table to store cached data." -msgstr "" +msgstr "[Banco de dados](https://github.com/yiisoft/cache-db) — usa uma tabela do banco de dados para guardar os dados em cache." #. type: Bullet: '- ' #: ../../guide/en/caching/data.md msgid "[File](https://github.com/yiisoft/cache-file) — uses standard files to store cached data. This is particularly suitable to cache large chunks of data, such as page content." -msgstr "" +msgstr "[Arquivo](https://github.com/yiisoft/cache-file) — usa arquivos comuns para guardar os dados em cache. É especialmente adequado para guardar grandes blocos de dados, como o conteúdo de páginas." #. type: Bullet: '- ' #: ../../guide/en/caching/data.md msgid "[Memcached](https://github.com/yiisoft/cache-memcached) — uses a PHP [memcached](https://secure.php.net/manual/en/book.memcached.php) extension. You can consider this option as the fastest one when dealing with cache in a distributed application" -msgstr "" +msgstr "[Memcached](https://github.com/yiisoft/cache-memcached) — usa a extensão [memcached](https://secure.php.net/manual/en/book.memcached.php) do PHP. Você pode considerar esta a opção mais rápida ao lidar com cache em uma aplicação distribuída" #. type: Plain text #: ../../guide/en/caching/data.md @@ -124,11 +136,14 @@ msgid "" "- [Wincache](https://github.com/yiisoft/cache-wincache) — uses PHP [WinCache](https://iis.net/downloads/microsoft/wincache-extension)\n" " ([see also](https://secure.php.net/manual/en/book.wincache.php)) extension.\n" msgstr "" +" (por exemplo, com vários servidores, load balancers etc.)\n" +"- [Wincache](https://github.com/yiisoft/cache-wincache) — usa a extensão [WinCache](https://iis.net/downloads/microsoft/wincache-extension)\n" +" ([veja também](https://secure.php.net/manual/en/book.wincache.php)) do PHP.\n" #. type: Plain text #: ../../guide/en/caching/data.md msgid "[You could find more handlers at packagist.org](https://packagist.org/providers/psr/simple-cache-implementation)." -msgstr "" +msgstr "[Você encontra mais drivers no packagist.org](https://packagist.org/providers/psr/simple-cache-implementation)." #. type: Plain text #: ../../guide/en/caching/data.md @@ -139,42 +154,46 @@ msgid "" "> - To use memory-based cache storage to store small but constantly used data (e.g., statistics)\n" "> - To use file-based or database-based cache storage to store big and less often used data (e.g., page content)\n" msgstr "" +"> [!TIP]\n" +"> Você pode usar armazenamentos de cache diferentes na mesma aplicação. Uma estratégia comum é:\n" +"> - Usar armazenamento de cache em memória para dados pequenos, mas usados constantemente (por exemplo, estatísticas)\n" +"> - Usar armazenamento de cache em arquivo ou em banco de dados para dados grandes e usados com menos frequência (por exemplo, conteúdo de páginas)\n" #. type: Plain text #: ../../guide/en/caching/data.md msgid "Cache handlers are usually set up in a [dependency injection container](../concept/di-container.md) so that they can be globally configurable and accessible." -msgstr "" +msgstr "Os drivers de cache normalmente são configurados em um [container de injeção de dependência](../concept/di-container.md), para que possam ser configurados e acessados globalmente." #. type: Plain text #: ../../guide/en/caching/data.md msgid "Because all cache handlers support the same set of APIs, you can swap the underlying cache handler with a different one. You can do it by reconfiguring the application without modifying the code that uses the cache." -msgstr "" +msgstr "Como todos os drivers de cache suportam o mesmo conjunto de APIs, você pode trocar o driver de cache subjacente por outro. Basta reconfigurar a aplicação, sem modificar o código que usa o cache." #. type: Title ### #: ../../guide/en/caching/data.md #, no-wrap msgid "Cache keys" -msgstr "" +msgstr "Chaves de cache" #. type: Plain text #: ../../guide/en/caching/data.md msgid "A key uniquely identifies each data item stored in the cache. When you store a data item, you have to specify a key for it. Later, when you retrieve the data item, you should give the corresponding key." -msgstr "" +msgstr "Uma chave identifica de forma única cada item de dados guardado no cache. Ao guardar um item, você precisa especificar uma chave para ele. Depois, ao recuperar o item, você deve informar a chave correspondente." #. type: Plain text #: ../../guide/en/caching/data.md msgid "You may use a string or an arbitrary value as a cache key. When a key isn't a string, it will be automatically serialized into a string." -msgstr "" +msgstr "Você pode usar uma string ou um valor arbitrário como chave de cache. Quando a chave não é uma string, ela é serializada automaticamente em uma string." #. type: Plain text #: ../../guide/en/caching/data.md msgid "A common strategy of defining a cache key is to include all determining factors in terms of an array." -msgstr "" +msgstr "Uma estratégia comum para definir uma chave de cache é incluir todos os fatores determinantes em um array." #. type: Plain text #: ../../guide/en/caching/data.md msgid "When different applications use the same cache storage, you should specify a unique cache key prefix for each application to avoid conflicts of cache keys. You can do this by using `\\Yiisoft\\Cache\\PrefixedCache` decorator:" -msgstr "" +msgstr "Quando aplicações diferentes usam o mesmo armazenamento de cache, você deve especificar um prefixo de chave de cache único para cada aplicação, para evitar conflitos de chaves. Você pode fazer isso usando o decorator `\\Yiisoft\\Cache\\PrefixedCache`:" #. type: Fenced code block (php) #: ../../guide/en/caching/data.md @@ -183,17 +202,19 @@ msgid "" "$arrayCacheWithPrefix = new \\Yiisoft\\Cache\\PrefixedCache(new \\Yiisoft\\Cache\\ArrayCache(), 'myapp_');\n" "$cache = new \\Yiisoft\\Cache\\Cache($arrayCacheWithPrefix);\n" msgstr "" +"$arrayCacheWithPrefix = new \\Yiisoft\\Cache\\PrefixedCache(new \\Yiisoft\\Cache\\ArrayCache(), 'myapp_');\n" +"$cache = new \\Yiisoft\\Cache\\Cache($arrayCacheWithPrefix);\n" #. type: Title ### #: ../../guide/en/caching/data.md #, no-wrap msgid "Cache expiration" -msgstr "" +msgstr "Expiração do cache" #. type: Plain text #: ../../guide/en/caching/data.md msgid "A data item stored in a cache will remain there forever unless it's removed because of some caching policy enforcement. For example, caching space is full and cache storage removes the oldest data. To change this behavior, you can set a TTL parameter when calling a method to store a data item:" -msgstr "" +msgstr "Um item de dados guardado no cache fica lá para sempre, a menos que seja removido por alguma política de cache. Por exemplo, o espaço do cache fica cheio e o armazenamento remove os dados mais antigos. Para mudar esse comportamento, você pode definir um parâmetro TTL ao chamar um método que guarda um item:" #. type: Fenced code block (php) #: ../../guide/en/caching/data.md @@ -204,49 +225,53 @@ msgid "" "return getTopProductsFromDatabase($count);\n" "}, $ttl);\n" msgstr "" +"$ttl = 3600;\n" +"$data = $cache->getOrSet($key, function (\\Psr\\SimpleCache\\CacheInterface $cache) use ($count) {\n" +"return getTopProductsFromDatabase($count);\n" +"}, $ttl);\n" #. type: Plain text #: ../../guide/en/caching/data.md msgid "The `$ttl` parameter indicates for how many seconds the data item can remain valid in the cache. When you retrieve the data item, if it has passed the expiration time, the method will execute the function and set the resulting value into cache." -msgstr "" +msgstr "O parâmetro `$ttl` indica por quantos segundos o item pode continuar válido no cache. Ao recuperar o item, se o tempo de expiração já tiver passado, o método executa a função e grava o valor resultante no cache." #. type: Plain text #: ../../guide/en/caching/data.md msgid "You may set the default TTL for the cache:" -msgstr "" +msgstr "Você pode definir o TTL padrão do cache:" #. type: Fenced code block (php) #: ../../guide/en/caching/data.md #, no-wrap msgid "$cache = new \\Yiisoft\\Cache\\Cache($arrayCache, 60 * 60); // 1 hour\n" -msgstr "" +msgstr "$cache = new \\Yiisoft\\Cache\\Cache($arrayCache, 60 * 60); // 1 hora\n" #. type: Plain text #: ../../guide/en/caching/data.md msgid "Additionally, you can invalidate a cache key explicitly:" -msgstr "" +msgstr "Além disso, você pode invalidar uma chave de cache explicitamente:" #. type: Fenced code block (php) #: ../../guide/en/caching/data.md #, no-wrap msgid "$cache->remove($key);\n" -msgstr "" +msgstr "$cache->remove($key);\n" #. type: Title ### #: ../../guide/en/caching/data.md #, no-wrap msgid "Invalidation dependencies" -msgstr "" +msgstr "Dependências de invalidação" #. type: Plain text #: ../../guide/en/caching/data.md msgid "Besides the expiration setting, changes of the so-called **invalidation dependencies** may also invalidate cached data item. For example, `\\Yiisoft\\Cache\\Dependency\\FileDependency` represents the dependency of a file's modification time. When this dependency changes, it means something modifying the corresponding file. As a result, any outdated file content found in the cache should invalidate." -msgstr "" +msgstr "Além da configuração de expiração, mudanças nas chamadas **dependências de invalidação** também podem invalidar um item em cache. Por exemplo, `\\Yiisoft\\Cache\\Dependency\\FileDependency` representa a dependência da data de modificação de um arquivo. Quando essa dependência muda, significa que algo modificou o arquivo correspondente. Como resultado, qualquer conteúdo desatualizado do arquivo encontrado no cache deve ser invalidado." #. type: Plain text #: ../../guide/en/caching/data.md msgid "Cache dependencies are objects of `\\Yiisoft\\Cache\\Dependency\\Dependency` descendant classes. When you store a data item in the cache, you can pass along an associated cache dependency object. For example," -msgstr "" +msgstr "As dependências de cache são objetos de classes descendentes de `\\Yiisoft\\Cache\\Dependency\\Dependency`. Ao guardar um item no cache, você pode passar junto um objeto de dependência de cache associado. Por exemplo," #. type: Fenced code block (php) #: ../../guide/en/caching/data.md @@ -266,57 +291,70 @@ msgid "" "// Trigger invalidation by tag.\n" "TagDependency::invalidate($cache, 'item_42');\n" msgstr "" +"/**\n" +" * @var callable $callable\n" +" * @var \\Yiisoft\\Cache\\CacheInterface $cache\n" +" */\n" +"\n" +"use Yiisoft\\Cache\\Dependency\\TagDependency;\n" +"\n" +"// Grava vários valores no cache, marcando ambos com uma tag.\n" +"$cache->getOrSet('item_42_price', $callable, null, new TagDependency('item_42'));\n" +"$cache->getOrSet('item_42_total', $callable, 3600, new TagDependency('item_42'));\n" +"\n" +"// Dispara a invalidação pela tag.\n" +"TagDependency::invalidate($cache, 'item_42');\n" #. type: Plain text #: ../../guide/en/caching/data.md msgid "Below is a summary of the available cache dependencies:" -msgstr "" +msgstr "Veja um resumo das dependências de cache disponíveis:" #. type: Bullet: '- ' #: ../../guide/en/caching/data.md msgid "`\\Yiisoft\\Cache\\Dependency\\ValueDependency`: invalidates the cache when specified value changes." -msgstr "" +msgstr "`\\Yiisoft\\Cache\\Dependency\\ValueDependency`: invalida o cache quando o valor especificado muda." #. type: Bullet: '- ' #: ../../guide/en/caching/data.md msgid "`\\Yiisoft\\Cache\\Dependency\\CallbackDependency`: invalidates the cache when the result of the specified PHP callback is different." -msgstr "" +msgstr "`\\Yiisoft\\Cache\\Dependency\\CallbackDependency`: invalida o cache quando o resultado do callback PHP especificado é diferente." #. type: Bullet: '- ' #: ../../guide/en/caching/data.md msgid "`\\Yiisoft\\Cache\\Dependency\\FileDependency`: invalidates the cache when the file's last modification time is different." -msgstr "" +msgstr "`\\Yiisoft\\Cache\\Dependency\\FileDependency`: invalida o cache quando a data da última modificação do arquivo é diferente." #. type: Bullet: '- ' #: ../../guide/en/caching/data.md msgid "`\\Yiisoft\\Cache\\Dependency\\TagDependency`: associates a cached data item with one or many tags. You may invalidate the cached data items with the specified tag(s) by calling `TagDependency::invalidate()`." -msgstr "" +msgstr "`\\Yiisoft\\Cache\\Dependency\\TagDependency`: associa um item em cache a uma ou várias tags. Você pode invalidar os itens em cache com as tags especificadas chamando `TagDependency::invalidate()`." #. type: Plain text #: ../../guide/en/caching/data.md msgid "You may combine many dependencies using `\\Yiisoft\\Cache\\Dependency\\AnyDependency` or `\\Yiisoft\\Cache\\Dependency\\AllDependencies`." -msgstr "" +msgstr "Você pode combinar várias dependências usando `\\Yiisoft\\Cache\\Dependency\\AnyDependency` ou `\\Yiisoft\\Cache\\Dependency\\AllDependencies`." #. type: Plain text #: ../../guide/en/caching/data.md msgid "To implement your own dependency, extend from `\\Yiisoft\\Cache\\Dependency\\Dependency`." -msgstr "" +msgstr "Para implementar a sua própria dependência, estenda `\\Yiisoft\\Cache\\Dependency\\Dependency`." #. type: Title ### #: ../../guide/en/caching/data.md #, no-wrap msgid "Cache stampede prevention" -msgstr "" +msgstr "Prevenção do efeito manada" #. type: Plain text #: ../../guide/en/caching/data.md msgid "[A cache stampede](https://en.wikipedia.org/wiki/Cache_stampede) is a type of cascading failure that can occur when massively parallel computing systems with caching mechanisms come under a high load. This behavior is sometimes also called dog-piling." -msgstr "" +msgstr "O [efeito manada (cache stampede)](https://en.wikipedia.org/wiki/Cache_stampede) é um tipo de falha em cascata que pode ocorrer quando sistemas de computação massivamente paralelos com mecanismos de cache ficam sob carga alta. Esse comportamento às vezes também é chamado de dog-piling." #. type: Plain text #: ../../guide/en/caching/data.md msgid "The `\\Yiisoft\\Cache\\Cache` uses a built-in \"Probably early expiration\" algorithm that prevents cache stampede. This algorithm randomly fakes a cache miss for one user while others are still served the cached value. You can control its behavior with the fifth optional parameter of `getOrSet()`, which is a float value called `$beta`. By default, beta is `1.0`, which is usually enough. The higher the value, the earlier cache will be re-created." -msgstr "" +msgstr "O `\\Yiisoft\\Cache\\Cache` usa um algoritmo embutido de \"expiração antecipada probabilística\" (\"Probably early expiration\") que evita o efeito manada. Esse algoritmo simula aleatoriamente um cache miss para um usuário enquanto os outros continuam recebendo o valor em cache. Você pode controlar o comportamento dele com o quinto parâmetro opcional de `getOrSet()`, um valor float chamado `$beta`. Por padrão, beta é `1.0`, o que costuma ser suficiente. Quanto maior o valor, mais cedo o cache será recriado." #. type: Fenced code block (php) #: ../../guide/en/caching/data.md @@ -333,3 +371,13 @@ msgid "" "$beta = 2.0;\n" "$cache->getOrSet($key, $callable, $ttl, $dependency, $beta);\n" msgstr "" +"/**\n" +" * @var mixed $key\n" +" * @var callable $callable\n" +" * @var \\DateInterval $ttl\n" +" * @var \\Yiisoft\\Cache\\CacheInterface $cache\n" +" * @var \\Yiisoft\\Cache\\Dependency\\Dependency $dependency\n" +" */\n" +"\n" +"$beta = 2.0;\n" +"$cache->getOrSet($key, $callable, $ttl, $dependency, $beta);\n" diff --git a/_translations/po/pt-BR/guide_caching_overview.md.po b/_translations/po/pt-BR/guide_caching_overview.md.po index 14eb082d..86faf8a7 100644 --- a/_translations/po/pt-BR/guide_caching_overview.md.po +++ b/_translations/po/pt-BR/guide_caching_overview.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2025-12-24 08:23+0000\n" "PO-Revision-Date: 2025-12-24 08:23+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -24,34 +24,34 @@ msgstr "Cache" #. type: Plain text #: ../src/guide/caching/overview.md msgid "Caching is an inexpensive and effective way to improve the performance of an application. By storing relatively static data in cache and serving it from cache when requested, the application saves the time that it otherwise would require to generate the data from scratch every time." -msgstr "" +msgstr "O cache é uma forma barata e eficaz de melhorar o desempenho de uma aplicação. Ao armazenar dados relativamente estáticos no cache e servi-los a partir dele quando solicitados, a aplicação economiza o tempo que, de outra forma, precisaria para gerar os dados do zero a cada vez." #. type: Plain text #: ../src/guide/caching/overview.md msgid "Caching can occur at different levels and places in an application. On the server-side, at the lower level, cache may be used to store basic data, such as a list of most recent article information fetched from the database; and at the higher level, cache may be used to store fragments or whole of Web pages, such as the rendering result of the most recent articles. On the client-side, you may use HTTP caching to keep most recently visited page content in the browser cache." -msgstr "" +msgstr "O cache pode ocorrer em diferentes níveis e lugares de uma aplicação. No lado do servidor, no nível mais baixo, o cache pode ser usado para armazenar dados básicos, como uma lista com as informações dos artigos mais recentes obtida do banco de dados; e, no nível mais alto, o cache pode ser usado para armazenar fragmentos ou páginas web inteiras, como o resultado da renderização dos artigos mais recentes. No lado do cliente, você pode usar o cache HTTP para manter o conteúdo das páginas visitadas mais recentemente no cache do navegador." #. type: Plain text #: ../src/guide/caching/overview.md msgid "Yii supports all these caching mechanisms:" -msgstr "" +msgstr "O Yii suporta todos estes mecanismos de cache:" #. type: Bullet: '* ' #: ../src/guide/caching/overview.md msgid "[Data caching](data.md)" -msgstr "" +msgstr "[Cache de dados](data.md)" #. type: Bullet: '* ' #: ../src/guide/caching/overview.md msgid "[Fragment caching](fragment.md)" -msgstr "" +msgstr "[Cache de fragmentos](fragment.md)" #. type: Bullet: '* ' #: ../src/guide/caching/overview.md msgid "[Page caching](page.md)" -msgstr "" +msgstr "[Cache de páginas](page.md)" #. type: Bullet: '* ' #: ../src/guide/caching/overview.md msgid "[HTTP caching](http.md)" -msgstr "" +msgstr "[Cache HTTP](http.md)" diff --git a/_translations/po/pt-BR/guide_databases_db-migrations.md.po b/_translations/po/pt-BR/guide_databases_db-migrations.md.po index d0a1621d..cef03b0d 100644 --- a/_translations/po/pt-BR/guide_databases_db-migrations.md.po +++ b/_translations/po/pt-BR/guide_databases_db-migrations.md.po @@ -8,69 +8,68 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-06-05 20:33+0000\n" "PO-Revision-Date: 2026-06-05 20:33+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/guide/databases/db-migrations.md -#: ../src/guide/structure/designing-packages.md +#: ../src/guide/databases/db-migrations.md ../src/guide/structure/designing-packages.md #, no-wrap msgid "Migrations" -msgstr "" +msgstr "Migrations" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "During the course of developing and maintaining a database-driven application, the structure of the database being used evolves just like the source code does. For example, during the development of an application, a new table may be found necessary; after the application is deployed to production, it may be discovered that an index should be created to improve the query performance; and so on. Because a database structure change often requires some source code changes, Yii supports the so-called *database migration* feature that allows you to keep track of database changes in terms of *database migrations* which are version-controlled together with the source code." -msgstr "" +msgstr "Ao longo do desenvolvimento e da manutenção de uma aplicação que usa banco de dados, a estrutura do banco evolui assim como o código-fonte. Por exemplo, durante o desenvolvimento de uma aplicação, pode surgir a necessidade de uma nova tabela; depois que a aplicação vai para produção, pode-se descobrir que é preciso criar um índice para melhorar o desempenho de uma consulta; e assim por diante. Como uma mudança na estrutura do banco de dados muitas vezes exige mudanças no código-fonte, o Yii oferece o recurso chamado *migration de banco de dados*, que permite acompanhar as mudanças no banco em forma de *migrations*, versionadas junto com o código-fonte." #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "The following steps show how database migration can be used by a team during development:" -msgstr "" +msgstr "Os passos a seguir mostram como uma equipe pode usar migrations durante o desenvolvimento:" #. type: Bullet: '1. ' #: ../src/guide/databases/db-migrations.md msgid "Tim creates a new migration (e.g. creates a new table, changes a column definition, etc.)." -msgstr "" +msgstr "Tim cria uma nova migration (por exemplo, cria uma nova tabela, altera a definição de uma coluna etc.)." #. type: Bullet: '2. ' #: ../src/guide/databases/db-migrations.md msgid "Tim commits the new migration into the source control system (e.g. Git, Mercurial)." -msgstr "" +msgstr "Tim faz o commit da nova migration no sistema de controle de versão (por exemplo, Git, Mercurial)." #. type: Bullet: '3. ' #: ../src/guide/databases/db-migrations.md msgid "Doug updates his repository from the source control system and receives the new migration." -msgstr "" +msgstr "Doug atualiza o repositório dele a partir do sistema de controle de versão e recebe a nova migration." #. type: Bullet: '4. ' #: ../src/guide/databases/db-migrations.md msgid "Doug applies the migration to his local development database, thereby synchronizing his database to reflect the changes that Tim has made." -msgstr "" +msgstr "Doug aplica a migration ao banco de dados local de desenvolvimento, sincronizando o banco dele com as mudanças que Tim fez." #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "And the following steps show how to deploy a new release with database migrations to production:" -msgstr "" +msgstr "E os passos a seguir mostram como fazer o deploy de uma nova release com migrations para produção:" #. type: Bullet: '1. ' #: ../src/guide/databases/db-migrations.md msgid "Scott creates a release tag for the project repository that contains some new database migrations." -msgstr "" +msgstr "Scott cria uma tag de release no repositório do projeto que contém algumas migrations novas." #. type: Bullet: '2. ' #: ../src/guide/databases/db-migrations.md msgid "Scott updates the source code on the production server to the release tag." -msgstr "" +msgstr "Scott atualiza o código-fonte no servidor de produção para a tag da release." #. type: Bullet: '3. ' #: ../src/guide/databases/db-migrations.md msgid "Scott applies any accumulated database migrations to the production database." -msgstr "" +msgstr "Scott aplica todas as migrations acumuladas ao banco de dados de produção." #. type: Fenced code block (mermaid) #: ../src/guide/databases/db-migrations.md @@ -94,41 +93,58 @@ msgid "" " Scott->>ProdServer: Updates source code to the release tag\n" " Scott->>ProdDB: Applies accumulated migrations\n" msgstr "" +"sequenceDiagram\n" +" participant Tim\n" +" participant VCS as Controle de versão\n" +" participant Doug\n" +" participant LocalDB as Banco de dados local de desenvolvimento\n" +" participant Scott\n" +" participant ProdServer as Servidor de produção\n" +" participant ProdDB as Banco de dados de produção\n" +"\n" +" Tim->>Tim: Cria uma nova migration\n" +" Tim->>VCS: Faz o commit da nova migration\n" +" Doug->>VCS: Atualiza o repositório e recebe a nova migration\n" +" Doug->>LocalDB: Aplica a migration localmente\n" +"\n" +" Scott->>VCS: Cria uma tag de release com as novas migrations\n" +" Scott->>ProdServer: Atualiza o código-fonte para a tag da release\n" +" Scott->>ProdDB: Aplica as migrations acumuladas\n" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "Yii provides a set of migration command line tools that allow you to:" -msgstr "" +msgstr "O Yii fornece um conjunto de ferramentas de linha de comando para migrations que permitem:" #. type: Bullet: '* ' #: ../src/guide/databases/db-migrations.md msgid "create new migrations;" -msgstr "" +msgstr "criar novas migrations;" #. type: Bullet: '* ' #: ../src/guide/databases/db-migrations.md msgid "apply migrations;" -msgstr "" +msgstr "aplicar migrations;" #. type: Bullet: '* ' #: ../src/guide/databases/db-migrations.md msgid "revert migrations;" -msgstr "" +msgstr "reverter migrations;" #. type: Bullet: '* ' #: ../src/guide/databases/db-migrations.md msgid "re-apply migrations;" -msgstr "" +msgstr "reaplicar migrations;" #. type: Bullet: '* ' #: ../src/guide/databases/db-migrations.md msgid "show migration history and status." -msgstr "" +msgstr "mostrar o histórico e o status das migrations." #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "All these tools are accessible through the command `yii migrate`. In this section we will describe in detail how to accomplish various tasks using these tools." -msgstr "" +msgstr "Todas essas ferramentas são acessíveis pelo comando `yii migrate`. Nesta seção, vamos descrever em detalhes como realizar várias tarefas usando essas ferramentas." #. type: Plain text #: ../src/guide/databases/db-migrations.md @@ -138,6 +154,9 @@ msgid "" "> Migrations could affect not only database schema but adjust existing data to fit new schema, create RBAC\n" "hierarchy or clean up cache.\n" msgstr "" +"> [!TIP]\n" +"> Migrations podem afetar não só o schema do banco de dados, mas também ajustar dados existentes ao novo schema, criar a hierarquia\n" +"de RBAC ou limpar o cache.\n" #. type: Plain text #: ../src/guide/databases/db-migrations.md @@ -151,33 +170,40 @@ msgid "" "> may accidentally break the existing migrations. For this reason migration code should be kept independent of other\n" "> application logic such.\n" msgstr "" +"> [!NOTE]\n" +"> Ao manipular dados em uma migration, pode parecer útil usar suas classes Active Record ou de entidade,\n" +"> já que parte da lógica já está implementada nelas. Lembre-se, porém, de que, ao contrário\n" +"> do código escrito nas migrations, que por natureza deve permanecer constante para sempre, a lógica da aplicação está sujeita a mudanças.\n" +"> Então, ao usar classes Active Record ou de entidade no código de migrations, mudanças na lógica do código-fonte\n" +"> podem quebrar acidentalmente as migrations existentes. Por isso, o código das migrations deve ser mantido independente do restante\n" +"> da lógica da aplicação.\n" #. type: Title ## #: ../src/guide/databases/db-migrations.md #, no-wrap msgid "Initial configuration" -msgstr "" +msgstr "Configuração inicial" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "To use migrations, install [yiisoft/db-migration](https://github.com/yiisoft/db-migration/) package:" -msgstr "" +msgstr "Para usar migrations, instale o pacote [yiisoft/db-migration](https://github.com/yiisoft/db-migration/):" #. type: Fenced code block (sh) #: ../src/guide/databases/db-migrations.md ../src/guide/start/databases.md #, no-wrap msgid "make composer require yiisoft/db-migration\n" -msgstr "" +msgstr "make composer require yiisoft/db-migration\n" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "Create a directory to store migrations `src/Migration` right in the project root." -msgstr "" +msgstr "Crie um diretório `src/Migration` para armazenar as migrations, diretamente na raiz do projeto." #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "Add the following configuration to `config/common/params.php`:" -msgstr "" +msgstr "Adicione a seguinte configuração em `config/common/params.php`:" #. type: Fenced code block (php) #: ../src/guide/databases/db-migrations.md ../src/guide/start/databases.md @@ -188,27 +214,31 @@ msgid "" " 'sourceNamespaces' => ['App\\\\Migration'],\n" "],\n" msgstr "" +"'yiisoft/db-migration' => [\n" +" 'newMigrationNamespace' => 'App\\\\Migration',\n" +" 'sourceNamespaces' => ['App\\\\Migration'],\n" +"],\n" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "If you want to place migrations elsewhere, you can define the path in `newMigrationPath`. If your migrations to be applied are from multiple sources, such as external modules, `sourcePaths` could be used to define these." -msgstr "" +msgstr "Se você quiser colocar as migrations em outro lugar, pode definir o caminho em `newMigrationPath`. Se as migrations a aplicar vêm de várias fontes, como módulos externos, você pode usar `sourcePaths` para defini-las." #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "You need a database connection configured as well. See [Working with databases](../start/databases.md) for an example of configuring it for PostgreSQL." -msgstr "" +msgstr "Você também precisa de uma conexão com o banco de dados configurada. Veja [Trabalhando com banco de dados](../start/databases.md) para um exemplo de configuração com PostgreSQL." #. type: Title ## #: ../src/guide/databases/db-migrations.md #, no-wrap msgid "Creating a migration" -msgstr "" +msgstr "Criando uma migration" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "To create a new empty migration, run the following command:" -msgstr "" +msgstr "Para criar uma nova migration vazia, execute o seguinte comando:" #. type: Fenced code block (sh) #: ../src/guide/databases/db-migrations.md @@ -217,11 +247,13 @@ msgid "" "make shell\n" "./yii migrate:create \n" msgstr "" +"make shell\n" +"./yii migrate:create \n" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "The required `name` argument gives a brief description about the new migration. For example, if the migration is about creating a new table named *news*, you may use the name `create_news_table` and run the following command:" -msgstr "" +msgstr "O argumento obrigatório `name` dá uma breve descrição da nova migration. Por exemplo, se a migration cria uma nova tabela chamada *news*, você pode usar o nome `create_news_table` e executar o seguinte comando:" #. type: Fenced code block #: ../src/guide/databases/db-migrations.md @@ -230,6 +262,8 @@ msgid "" "make shell\n" "./yii migrate:create create_news_table\n" msgstr "" +"make shell\n" +"./yii migrate:create create_news_table\n" #. type: Plain text #: ../src/guide/databases/db-migrations.md @@ -239,11 +273,14 @@ msgid "" "> Because the `name` argument will be used as part of the generated migration class name,\n" "> it should only contain letters, digits, and/or underscore characters.\n" msgstr "" +"> [!NOTE]\n" +"> Como o argumento `name` é usado como parte do nome da classe de migration gerada,\n" +"> ele deve conter apenas letras, dígitos e/ou underscores.\n" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "The above command will create a new PHP class file named `src/Migration/M251225221906CreateNewsTable.php`. The file contains the following code which mainly declares a migration class with the skeleton code:" -msgstr "" +msgstr "O comando acima cria um novo arquivo de classe PHP chamado `src/Migration/M251225221906CreateNewsTable.php`. O arquivo contém o código a seguir, que basicamente declara uma classe de migration com o esqueleto do código:" #. type: Fenced code block (php) #: ../src/guide/databases/db-migrations.md @@ -271,11 +308,32 @@ msgid "" " }\n" "}\n" msgstr "" +"columnBuilder();\n" +"\n" +" $b->createTable('news', [\n" +" 'id' => $cb::uuidPrimaryKey(),\n" +" 'title' => $cb::string()->notNull(),\n" +" 'content' => $cb::text(),\n" +" ]);\n" +" }\n" +"\n" +" public function down(MigrationBuilder $b): void\n" +" {\n" +" $b->dropTable('news');\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "Migration builder `$b` in the above manages database schema while the column builder `$cb` manages column types. Both allow using *abstract types*. When a migration is applied to a particular database, the abstract types will be translated into the corresponding database physical types and corresponding SQL to define them." -msgstr "" +msgstr "No exemplo acima, o migration builder `$b` gerencia o schema do banco de dados, enquanto o column builder `$cb` gerencia os tipos de coluna. Ambos permitem usar *tipos abstratos*. Quando uma migration é aplicada a um banco de dados específico, os tipos abstratos são traduzidos para os tipos físicos correspondentes do banco e para o SQL correspondente que os define." #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "Methods available in migration builder belong to the following types:" -msgstr "" +msgstr "Os métodos disponíveis no migration builder se dividem nos seguintes tipos:" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "Raw queries" -msgstr "" +msgstr "Consultas SQL puras" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "getDb — to get database connection instance." -msgstr "" +msgstr "getDb — para obter a instância da conexão com o banco de dados." #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "execute — to execute raw SQL query." -msgstr "" +msgstr "execute — para executar uma consulta SQL pura." #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "Data" -msgstr "" +msgstr "Dados" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "insert / update / delete" -msgstr "" +msgstr "insert / update / delete" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "batchInsert" -msgstr "" +msgstr "batchInsert" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "upsert" -msgstr "" +msgstr "upsert" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "Tables and views" -msgstr "" +msgstr "Tabelas e views" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "createTable / renameTable / dropTable" -msgstr "" +msgstr "createTable / renameTable / dropTable" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "truncateTable" -msgstr "" +msgstr "truncateTable" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "addCommentOnTable / dropCommentFromTable" -msgstr "" +msgstr "addCommentOnTable / dropCommentFromTable" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "createView / dropView" -msgstr "" +msgstr "createView / dropView" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "Columns" -msgstr "" +msgstr "Colunas" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "addColumn / renameColumn / alterColumn / dropColumn" -msgstr "" +msgstr "addColumn / renameColumn / alterColumn / dropColumn" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "addCommentOnColumn / dropCommentFromColumn" -msgstr "" +msgstr "addCommentOnColumn / dropCommentFromColumn" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "Keys and indexes" -msgstr "" +msgstr "Chaves e índices" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "addPrimaryKey / dropPrimaryKey" -msgstr "" +msgstr "addPrimaryKey / dropPrimaryKey" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "addForeignKey / dropForeignKey" -msgstr "" +msgstr "addForeignKey / dropForeignKey" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "createIndex / dropIndex" -msgstr "" +msgstr "createIndex / dropIndex" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "Additionally, there's a `columnBuilder()` which is used to obtain a column builder as in example above. The builder has static methods that define various column types:" -msgstr "" +msgstr "Além disso, há um `columnBuilder()`, usado para obter um column builder como no exemplo acima. O builder tem métodos estáticos que definem vários tipos de coluna:" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "Keys" -msgstr "" +msgstr "Chaves" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "primaryKey" -msgstr "" +msgstr "primaryKey" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "smallPrimaryKey" -msgstr "" +msgstr "smallPrimaryKey" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "bigPrimaryKey" -msgstr "" +msgstr "bigPrimaryKey" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "uuidPrimaryKey" -msgstr "" +msgstr "uuidPrimaryKey" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "Boolean" -msgstr "" +msgstr "Booleano" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "boolean" -msgstr "" +msgstr "boolean" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "Numbers" -msgstr "" +msgstr "Números" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "bit" -msgstr "" +msgstr "bit" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "tinyint" -msgstr "" +msgstr "tinyint" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "smallint" -msgstr "" +msgstr "smallint" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "integer" -msgstr "" +msgstr "integer" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "bigint" -msgstr "" +msgstr "bigint" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "flat" -msgstr "" +msgstr "flat" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "double" -msgstr "" +msgstr "double" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "decimal" -msgstr "" +msgstr "decimal" #. type: Title ## #: ../src/guide/databases/db-migrations.md ../src/internals/010-code-style.md #, no-wrap msgid "Strings" -msgstr "" +msgstr "Strings" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "char" -msgstr "" +msgstr "char" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "string" -msgstr "" +msgstr "string" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "text" -msgstr "" +msgstr "text" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "Date and time" -msgstr "" +msgstr "Data e hora" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "timestamp" -msgstr "" +msgstr "timestamp" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "datetime" -msgstr "" +msgstr "datetime" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "datetimeWithTimezone" -msgstr "" +msgstr "datetimeWithTimezone" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "time" -msgstr "" +msgstr "time" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "timeWithTimezone" -msgstr "" +msgstr "timeWithTimezone" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "date" -msgstr "" +msgstr "date" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "Special types" -msgstr "" +msgstr "Tipos especiais" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "money" -msgstr "" +msgstr "money" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "binary" -msgstr "" +msgstr "binary" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "uuid" -msgstr "" +msgstr "uuid" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "array" -msgstr "" +msgstr "array" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "structured" -msgstr "" +msgstr "structured" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "json" -msgstr "" +msgstr "json" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "enum" -msgstr "" +msgstr "enum" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "All the above methods create a base type which could be adjusted with additional methods:" -msgstr "" +msgstr "Todos os métodos acima criam um tipo base que pode ser ajustado com métodos adicionais:" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "null / notNull" -msgstr "" +msgstr "null / notNull" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "defaultValue" -msgstr "" +msgstr "defaultValue" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "unique" -msgstr "" +msgstr "unique" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "scale / size / unsigned" -msgstr "" +msgstr "scale / size / unsigned" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "primaryKey / autoIncrement" -msgstr "" +msgstr "primaryKey / autoIncrement" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "check" -msgstr "" +msgstr "check" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "comment" -msgstr "" +msgstr "comment" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "computed" -msgstr "" +msgstr "computed" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "extra" -msgstr "" +msgstr "extra" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "reference" -msgstr "" +msgstr "reference" #. type: Title ### #: ../src/guide/databases/db-migrations.md #, no-wrap msgid "Irreversible migrations" -msgstr "" +msgstr "Migrations irreversíveis" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "Not all migrations are reversible. For example, if the `up()` method deletes a row of a table, you may not be able to recover this row in the `down()` method. Sometimes, you may be just too lazy to implement the `down()`, because it is not very common to revert database migrations. In this case, you should implement `Yiisoft\\Db\\Migration\\MigrationInterface` that has `up()` only." -msgstr "" +msgstr "Nem todas as migrations são reversíveis. Por exemplo, se o método `up()` apaga uma linha de uma tabela, talvez você não consiga recuperar essa linha no método `down()`. Às vezes, você pode simplesmente não querer implementar o `down()`, porque não é muito comum reverter migrations. Nesse caso, implemente `Yiisoft\\Db\\Migration\\MigrationInterface`, que tem apenas `up()`." #. type: Title ### #: ../src/guide/databases/db-migrations.md #, no-wrap msgid "Transactional migrations" -msgstr "" +msgstr "Migrations transacionais" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "While performing complex DB migrations, it is important to ensure each migration to either succeed or fail as a whole so that the database can maintain integrity and consistency. To achieve this goal, it is recommended that you may enclose the DB operations of each migration in a transaction automatically by adding `TransactionalMigrationInterface` to `implements` of your migration." -msgstr "" +msgstr "Ao executar migrations complexas, é importante garantir que cada migration tenha sucesso ou falhe por completo, para que o banco de dados mantenha a integridade e a consistência. Para isso, é recomendado envolver automaticamente as operações de banco de cada migration em uma transação, adicionando `TransactionalMigrationInterface` ao `implements` da sua migration." #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "As a result, if any operation in the `up()` or `down()` method fails, all prior operations will be rolled back automatically." -msgstr "" +msgstr "Assim, se qualquer operação no método `up()` ou `down()` falhar, todas as operações anteriores serão desfeitas (rollback) automaticamente." #. type: Plain text #: ../src/guide/databases/db-migrations.md @@ -685,17 +770,19 @@ msgid "" "> Note: Not all DBMS support transactions. And some DB queries cannot be put into a transaction. For some examples,\n" "please refer to [implicit commit](https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html).\n" msgstr "" +"> Nota: nem todo SGBD dá suporte a transações. E algumas consultas não podem ser colocadas em uma transação. Para alguns exemplos,\n" +"consulte [implicit commit](https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html).\n" #. type: Title ## #: ../src/guide/databases/db-migrations.md #, no-wrap msgid "Generating a migration" -msgstr "" +msgstr "Gerando uma migration" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "Instead of writing migrations by hand, the command provides a convenient way generate some of the code." -msgstr "" +msgstr "Em vez de escrever migrations à mão, o comando oferece uma forma prática de gerar parte do código." #. type: Fenced code block (shell) #: ../src/guide/databases/db-migrations.md @@ -704,11 +791,13 @@ msgid "" "make shell\n" "./yii migrate:create -- my_first_table --command=table --fields=name,example --table-comment=my_first_table\n" msgstr "" +"make shell\n" +"./yii migrate:create -- my_first_table --command=table --fields=name,example --table-comment=my_first_table\n" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "That would generate the following:" -msgstr "" +msgstr "Isso geraria o seguinte:" #. type: Fenced code block (php) #: ../src/guide/databases/db-migrations.md @@ -748,91 +837,123 @@ msgid "" " }\n" "}\n" msgstr "" +"columnBuilder();\n" +"\n" +" $b->createTable('my_first_table', [\n" +" 'id' => $columnBuilder::primaryKey(),\n" +" 'name',\n" +" 'example',\n" +" ]);\n" +"\n" +" $b->addCommentOnTable('my_first_table', 'my_first_table');\n" +" }\n" +"\n" +" public function down(MigrationBuilder $b): void\n" +" {\n" +" $b->dropTable('my_first_table');\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "Commands available are:" -msgstr "" +msgstr "Os comandos disponíveis são:" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "create - empty migration." -msgstr "" +msgstr "create - migration vazia." #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "table - creating a table. Use `--fields` specify a list of fields to use. Types could be specified as well such as `id:primaryKey,name:string:defaultValue(\"Alex\"),user_id:integer:foreignKey,category_id2:integer:foreignKey(category id2)`." -msgstr "" +msgstr "table - cria uma tabela. Use `--fields` para especificar a lista de campos. Também é possível especificar os tipos, como em `id:primaryKey,name:string:defaultValue(\"Alex\"),user_id:integer:foreignKey,category_id2:integer:foreignKey(category id2)`." #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "dropTable - dropping a table." -msgstr "" +msgstr "dropTable - remove uma tabela." #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "addColumn - adding a column." -msgstr "" +msgstr "addColumn - adiciona uma coluna." #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "dropColumn - dropping a column." -msgstr "" +msgstr "dropColumn - remove uma coluna." #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "junction - creating a junction table. Use `--and` specify a second table." -msgstr "" +msgstr "junction - cria uma tabela de junção. Use `--and` para especificar a segunda tabela." #. type: Title ## #: ../src/guide/databases/db-migrations.md #, no-wrap msgid "Applying Migrations" -msgstr "" +msgstr "Aplicando migrations" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "To upgrade a database to its latest structure, you should apply all available new migrations using the following command:" -msgstr "" +msgstr "Para atualizar um banco de dados para a estrutura mais recente, aplique todas as migrations novas disponíveis com o seguinte comando:" #. type: Fenced code block -#: ../src/guide/databases/db-migrations.md -#: ../src/guide/security/authorization.md +#: ../src/guide/databases/db-migrations.md ../src/guide/security/authorization.md #, no-wrap msgid "./yii migrate:up\n" -msgstr "" +msgstr "./yii migrate:up\n" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "This command will list all migrations that have not been applied so far. If you confirm that you want to apply these migrations, it will run the `up()` method in every new migration class, one after another, in the order of their timestamp values. If any of the migrations fails, the command will quit without applying the rest of the migrations." -msgstr "" +msgstr "Esse comando lista todas as migrations que ainda não foram aplicadas. Se você confirmar que quer aplicá-las, ele executa o método `up()` de cada nova classe de migration, uma após a outra, na ordem de seus timestamps. Se alguma das migrations falhar, o comando é encerrado sem aplicar as demais." #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "For each migration that has been successfully applied, the command will insert a row into a database table named `migration` to record the successful application of the migration. This will allow the migration tool to identify which migrations have been applied and which have not." -msgstr "" +msgstr "Para cada migration aplicada com sucesso, o comando insere uma linha em uma tabela do banco chamada `migration` para registrar a aplicação bem-sucedida. Isso permite que a ferramenta de migrations identifique quais migrations foram aplicadas e quais não foram." #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "Sometimes, you may only want to apply one or a few new migrations, instead of all available migrations. You can do so by specifying the number of migrations that you want to apply when running the command. For example, the following command will try to apply the next three available migrations:" -msgstr "" +msgstr "Às vezes, você pode querer aplicar apenas uma ou algumas migrations novas, em vez de todas as disponíveis. Você pode fazer isso especificando o número de migrations que quer aplicar ao executar o comando. Por exemplo, o comando a seguir tenta aplicar as próximas três migrations disponíveis:" #. type: Fenced code block #: ../src/guide/databases/db-migrations.md #, no-wrap msgid "./yii migrate:up --limit=3\n" -msgstr "" +msgstr "./yii migrate:up --limit=3\n" #. type: Title ## #: ../src/guide/databases/db-migrations.md #, no-wrap msgid "Reverting Migrations" -msgstr "" +msgstr "Revertendo migrations" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "To revert (undo) one or multiple migrations that have been applied before, you can run the following command:" -msgstr "" +msgstr "Para reverter (desfazer) uma ou várias migrations aplicadas anteriormente, execute o seguinte comando:" #. type: Fenced code block #: ../src/guide/databases/db-migrations.md @@ -842,6 +963,9 @@ msgid "" "./yii migrate:down --limit=3 # revert the most 3 recently applied migrations\n" "./yii migrate:down --all # revert all migrations\n" msgstr "" +"./yii migrate:down # reverte a migration aplicada mais recentemente\n" +"./yii migrate:down --limit=3 # reverte as 3 migrations aplicadas mais recentemente\n" +"./yii migrate:down --all # reverte todas as migrations\n" #. type: Plain text #: ../src/guide/databases/db-migrations.md @@ -850,17 +974,19 @@ msgid "" "> Note: Not all migrations are reversible. Trying to revert such migrations will cause an error and stop the\n" "entire reverting process.\n" msgstr "" +"> Nota: nem todas as migrations são reversíveis. Tentar reverter uma migration assim causa um erro e interrompe\n" +"todo o processo de reversão.\n" #. type: Title ## #: ../src/guide/databases/db-migrations.md #, no-wrap msgid "Redoing Migrations" -msgstr "" +msgstr "Refazendo migrations" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "Redoing migrations means first reverting the specified migrations and then applying again. This can be done as follows:" -msgstr "" +msgstr "Refazer migrations significa primeiro reverter as migrations especificadas e depois aplicá-las novamente. Isso pode ser feito assim:" #. type: Fenced code block #: ../src/guide/databases/db-migrations.md @@ -870,23 +996,26 @@ msgid "" "./yii migrate:redo --limit=3 # redo the last 3 applied migrations\n" "./yii migrate:redo --all # redo all migrations\n" msgstr "" +"./yii migrate:redo # refaz a última migration aplicada\n" +"./yii migrate:redo --limit=3 # refaz as 3 últimas migrations aplicadas\n" +"./yii migrate:redo --all # refaz todas as migrations\n" #. type: Plain text #: ../src/guide/databases/db-migrations.md #, no-wrap msgid "> Note: If a migration is not reversible, you will not be able to redo it.\n" -msgstr "" +msgstr "> Nota: se uma migration não for reversível, você não conseguirá refazê-la.\n" #. type: Title ## #: ../src/guide/databases/db-migrations.md #, no-wrap msgid "Listing Migrations" -msgstr "" +msgstr "Listando migrations" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "To list which migrations have been applied and which are not, you may use the following commands:" -msgstr "" +msgstr "Para listar quais migrations foram aplicadas e quais não foram, use os seguintes comandos:" #. type: Fenced code block #: ../src/guide/databases/db-migrations.md @@ -900,19 +1029,26 @@ msgid "" "./yii migrate:new --limit=5 # showing the first 5 new migrations\n" "./yii migrate:new --all # showing all new migrations\n" msgstr "" +"./yii migrate/history # mostra as 10 últimas migrations aplicadas\n" +"./yii migrate:history --limit=5 # mostra as 5 últimas migrations aplicadas\n" +"./yii migrate:history --all # mostra todas as migrations aplicadas\n" +"\n" +"./yii migrate:new # mostra as 10 primeiras migrations novas\n" +"./yii migrate:new --limit=5 # mostra as 5 primeiras migrations novas\n" +"./yii migrate:new --all # mostra todas as migrations novas\n" #. type: Title ### #: ../src/guide/databases/db-migrations.md #, no-wrap msgid "Upgrading from Yii 2.0" -msgstr "" +msgstr "Migrando do Yii 2.0" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "Migrations in Yii 2.0 and the [yiisoft/db-migration](https://github.com/yiisoft/db-migration/) package are not compatible, and the `migration` table is also not compatible." -msgstr "" +msgstr "As migrations do Yii 2.0 e o pacote [yiisoft/db-migration](https://github.com/yiisoft/db-migration/) não são compatíveis, e a tabela `migration` também não é compatível." #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "A probable solution is to use structure dumps and rename the old `migration` table. Upon the initial execution of migrations, a new `migration` table with new fields will be created. All further changes in the database schema are applied using the new `migration` component and recorded in the new migration table." -msgstr "" +msgstr "Uma solução possível é usar dumps da estrutura e renomear a tabela `migration` antiga. Na primeira execução das migrations, uma nova tabela `migration` com os novos campos será criada. Todas as mudanças seguintes no schema do banco de dados são aplicadas usando o novo componente `migration` e registradas na nova tabela de migrations." diff --git a/_translations/po/pt-BR/guide_rest_quick-start.md.po b/_translations/po/pt-BR/guide_rest_quick-start.md.po index 2175f1c0..5f2339f4 100644 --- a/_translations/po/pt-BR/guide_rest_quick-start.md.po +++ b/_translations/po/pt-BR/guide_rest_quick-start.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-05-29 09:35+0000\n" "PO-Revision-Date: 2026-05-29 09:35+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,53 +19,53 @@ msgstr "" #: ../src/guide/rest/quick-start.md #, no-wrap msgid "Quick start" -msgstr "" +msgstr "Início rápido" #. type: Plain text #: ../src/guide/rest/quick-start.md msgid "Yii works with JSON APIs through the same PSR-7 request and response objects used by web pages. For API endpoints, the usual flow is:" -msgstr "" +msgstr "O Yii trabalha com APIs JSON usando os mesmos objetos de requisição e resposta PSR-7 das páginas web. Para endpoints de API, o fluxo comum é:" #. type: Bullet: '* ' #: ../src/guide/rest/quick-start.md msgid "Parse the request body when the client sends JSON." -msgstr "" +msgstr "Ler o corpo da requisição quando o cliente envia JSON." #. type: Bullet: '* ' #: ../src/guide/rest/quick-start.md msgid "Map request data to a typed input object." -msgstr "" +msgstr "Mapear os dados da requisição para um objeto de entrada tipado." #. type: Bullet: '* ' #: ../src/guide/rest/quick-start.md msgid "Validate the input object." -msgstr "" +msgstr "Validar o objeto de entrada." #. type: Bullet: '* ' #: ../src/guide/rest/quick-start.md msgid "Return a response whose data is formatted as JSON." -msgstr "" +msgstr "Retornar uma resposta cujos dados são formatados como JSON." #. type: Plain text #: ../src/guide/rest/quick-start.md msgid "This guide assumes that you use the [API application template](https://github.com/yiisoft/app-api). It already includes request body parsing, request input resolving, JSON data responses, and presenter examples. For complete applications with different structures, see [Demo applications](../start/demo-apps.md)." -msgstr "" +msgstr "Este guia assume que você usa o [template de aplicação API](https://github.com/yiisoft/app-api). Ele já inclui a leitura do corpo da requisição, a resolução da entrada da requisição, respostas de dados em JSON e exemplos de presenters. Para aplicações completas com outras estruturas, veja [Aplicações demo](../start/demo-apps.md)." #. type: Title ## #: ../src/guide/rest/quick-start.md #, no-wrap msgid "Creating request input" -msgstr "" +msgstr "Criando a entrada da requisição" #. type: Plain text #: ../src/guide/rest/quick-start.md msgid "Use [yiisoft/input-http](https://github.com/yiisoft/input-http) to describe request data as a typed input object. Attach `#[FromBody]` when all values should come from the parsed request body." -msgstr "" +msgstr "Use o [yiisoft/input-http](https://github.com/yiisoft/input-http) para descrever os dados da requisição como um objeto de entrada tipado. Adicione `#[FromBody]` quando todos os valores devem vir do corpo da requisição já interpretado." #. type: Plain text #: ../src/guide/rest/quick-start.md msgid "Create `src/Api/Post/CreatePostInput.php`:" -msgstr "" +msgstr "Crie `src/Api/Post/CreatePostInput.php`:" #. type: Fenced code block (php) #: ../src/guide/rest/quick-start.md @@ -93,11 +93,32 @@ msgid "" " public string $content = '';\n" "}\n" msgstr "" +"getValidationResult();\n" +"\n" +" if (!$result->isValid()) {\n" +" return $responseFactory->failValidation($result);\n" +" }\n" +"\n" +" return $responseFactory\n" +" ->success([\n" +" 'title' => $input->title,\n" +" 'content' => $input->content,\n" +" ])\n" +" ->withStatus(Status::CREATED);\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/rest/quick-start.md msgid "You can validate the input in the action as shown above. Alternatively, configure `RequestInputParametersResolver` to throw `Yiisoft\\Input\\Http\\InputValidationException` and convert that exception to a JSON response in one error handler. The API application template uses this centralized approach." -msgstr "" +msgstr "Você pode validar a entrada na action como mostrado acima. Outra opção é configurar o `RequestInputParametersResolver` para lançar `Yiisoft\\Input\\Http\\InputValidationException` e converter essa exceção em uma resposta JSON em um único tratador de erros. O template de aplicação API usa essa abordagem centralizada." #. type: Title ## #: ../src/guide/rest/quick-start.md #, no-wrap msgid "Returning JSON responses" -msgstr "" +msgstr "Retornando respostas JSON" #. type: Plain text #: ../src/guide/rest/quick-start.md msgid "For small endpoints, you can write JSON to a PSR-7 response manually as shown in [Responding with JSON](../runtime/response.md#responding-with-json). For APIs, prefer [yiisoft/data-response](https://github.com/yiisoft/data-response), which formats response data and sets the `Content-Type` header." -msgstr "" +msgstr "Para endpoints pequenos, você pode escrever o JSON em uma resposta PSR-7 manualmente, como mostrado em [Respondendo com JSON](../runtime/response.md#respondendo-com-json). Para APIs, prefira o [yiisoft/data-response](https://github.com/yiisoft/data-response), que formata os dados da resposta e define o header `Content-Type`." #. type: Plain text #: ../src/guide/rest/quick-start.md msgid "The API application template keeps response formatting in `src/Api/Shared/ResponseFactory.php`:" -msgstr "" +msgstr "O template de aplicação API mantém a formatação das respostas em `src/Api/Shared/ResponseFactory.php`:" #. type: Fenced code block (php) #: ../src/guide/rest/quick-start.md @@ -309,16 +408,57 @@ msgid "" " }\n" "}\n" msgstr "" +"dataResponseFactory->createResponse([\n" +" 'status' => 'success',\n" +" 'data' => $presenter->present($data),\n" +" ]);\n" +" }\n" +"\n" +" public function failValidation(Result $result): ResponseInterface\n" +" {\n" +" return $this->dataResponseFactory\n" +" ->createResponse([\n" +" 'status' => 'failed',\n" +" 'error_message' => 'Validation failed.',\n" +" 'error_data' => (new ValidationResultPresenter())->present($result),\n" +" ])\n" +" ->withStatus(Status::UNPROCESSABLE_ENTITY);\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/rest/quick-start.md msgid "Presenters are application-level abstractions that transform application objects to API output arrays. Keep them separate from domain entities so changing an API response doesn't force changes in business objects." -msgstr "" +msgstr "Presenters são abstrações da camada de aplicação que transformam objetos da aplicação em arrays de saída da API. Mantenha-os separados das entidades de domínio, para que mudar uma resposta da API não force mudanças nos objetos de negócio." #. type: Plain text #: ../src/guide/rest/quick-start.md msgid "Create `src/Api/Post/PostPresenter.php`:" -msgstr "" +msgstr "Crie `src/Api/Post/PostPresenter.php`:" #. type: Fenced code block (php) #: ../src/guide/rest/quick-start.md @@ -347,22 +487,44 @@ msgid "" " }\n" "}\n" msgstr "" +"\n" +" */\n" +"final readonly class PostPresenter implements PresenterInterface\n" +"{\n" +" public function present(mixed $value): array\n" +" {\n" +" return [\n" +" 'id' => $value->id,\n" +" 'title' => $value->title,\n" +" 'content' => $value->content,\n" +" ];\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/rest/quick-start.md msgid "The API template contains a fuller implementation of [response factory](https://github.com/yiisoft/app-api/blob/master/src/Api/Shared/ResponseFactory.php) and [presenters](https://github.com/yiisoft/app-api/tree/master/src/Api/Shared/Presenter)." -msgstr "" +msgstr "O template de API contém uma implementação mais completa da [response factory](https://github.com/yiisoft/app-api/blob/master/src/Api/Shared/ResponseFactory.php) e dos [presenters](https://github.com/yiisoft/app-api/tree/master/src/Api/Shared/Presenter)." #. type: Title ## #: ../src/guide/rest/quick-start.md #, no-wrap msgid "Routing an endpoint" -msgstr "" +msgstr "Roteando um endpoint" #. type: Plain text #: ../src/guide/rest/quick-start.md msgid "Register API routes in `config/common/routes.php`:" -msgstr "" +msgstr "Registre as rotas da API em `config/common/routes.php`:" #. type: Fenced code block (php) #: ../src/guide/rest/quick-start.md @@ -378,11 +540,20 @@ msgid "" " ->name('api/posts/create'),\n" "];\n" msgstr "" +"use App\\Api\\Post\\CreatePostAction;\n" +"use Yiisoft\\Http\\Method;\n" +"use Yiisoft\\Router\\Route;\n" +"\n" +"return [\n" +" Route::methods([Method::POST], '/posts')\n" +" ->action(CreatePostAction::class)\n" +" ->name('api/posts/create'),\n" +"];\n" #. type: Plain text #: ../src/guide/rest/quick-start.md msgid "Send JSON by setting `Content-Type: application/json`. Ask for JSON responses with `Accept: application/json`." -msgstr "" +msgstr "Envie JSON definindo `Content-Type: application/json`. Peça respostas JSON com `Accept: application/json`." #. type: Fenced code block (shell) #: ../src/guide/rest/quick-start.md @@ -393,44 +564,48 @@ msgid "" " -H 'Accept: application/json' \\\n" " -d '{\"title\":\"First post\",\"content\":\"Text\"}'\n" msgstr "" +"curl -X POST http://localhost:8080/posts \\\n" +" -H 'Content-Type: application/json' \\\n" +" -H 'Accept: application/json' \\\n" +" -d '{\"title\":\"First post\",\"content\":\"Text\"}'\n" #. type: Plain text #: ../src/guide/rest/quick-start.md msgid "Validation errors are returned as JSON with HTTP status `422 Unprocessable Entity`. Successful creation usually returns `201 Created`." -msgstr "" +msgstr "Erros de validação são retornados como JSON com status HTTP `422 Unprocessable Entity`. Uma criação bem-sucedida normalmente retorna `201 Created`." #. type: Title ## #: ../src/guide/rest/quick-start.md #, no-wrap msgid "Existing applications" -msgstr "" +msgstr "Aplicações existentes" #. type: Plain text #: ../src/guide/rest/quick-start.md msgid "If you add JSON API endpoints to an existing web application, install the API packages first:" -msgstr "" +msgstr "Se você for adicionar endpoints de API JSON a uma aplicação web existente, primeiro instale os pacotes de API:" #. type: Fenced code block (shell) #: ../src/guide/rest/quick-start.md #, no-wrap msgid "composer require yiisoft/input-http yiisoft/request-body-parser yiisoft/data-response\n" -msgstr "" +msgstr "composer require yiisoft/input-http yiisoft/request-body-parser yiisoft/data-response\n" #. type: Plain text #: ../src/guide/rest/quick-start.md msgid "If you use Docker:" -msgstr "" +msgstr "Se você usa Docker:" #. type: Fenced code block (shell) #: ../src/guide/rest/quick-start.md #, no-wrap msgid "make composer require yiisoft/input-http yiisoft/request-body-parser yiisoft/data-response\n" -msgstr "" +msgstr "make composer require yiisoft/input-http yiisoft/request-body-parser yiisoft/data-response\n" #. type: Plain text #: ../src/guide/rest/quick-start.md msgid "In `config/web/di/application.php`, add `RequestBodyParser` before `Router` so JSON requests are parsed before actions run:" -msgstr "" +msgstr "Em `config/web/di/application.php`, adicione o `RequestBodyParser` antes do `Router`, para que as requisições JSON sejam lidas antes de as actions rodarem:" #. type: Fenced code block (php) #: ../src/guide/rest/quick-start.md @@ -444,11 +619,18 @@ msgid "" " Router::class,\n" "];\n" msgstr "" +"use Yiisoft\\Request\\Body\\RequestBodyParser;\n" +"use Yiisoft\\Router\\Middleware\\Router;\n" +"\n" +"return [\n" +" RequestBodyParser::class,\n" +" Router::class,\n" +"];\n" #. type: Plain text #: ../src/guide/rest/quick-start.md msgid "In the same file, add JSON data response middleware before error handling and routing:" -msgstr "" +msgstr "No mesmo arquivo, adicione o middleware de resposta de dados JSON antes do tratamento de erros e do roteamento:" #. type: Fenced code block (php) #: ../src/guide/rest/quick-start.md @@ -467,11 +649,23 @@ msgid "" " // error handling, request body parser, router, and not-found middleware\n" "];\n" msgstr "" +"use Yiisoft\\DataResponse\\Formatter\\JsonFormatter;\n" +"use Yiisoft\\DataResponse\\Middleware\\ContentNegotiatorDataResponseMiddleware;\n" +"\n" +"return [\n" +" static fn() => new ContentNegotiatorDataResponseMiddleware(\n" +" formatters: [\n" +" 'application/json' => new JsonFormatter(),\n" +" ],\n" +" fallback: new JsonFormatter(),\n" +" ),\n" +" // tratamento de erros, leitor do corpo da requisição, router e middleware de não encontrado\n" +"];\n" #. type: Plain text #: ../src/guide/rest/quick-start.md msgid "Also in `config/web/di/application.php`, configure action parameter resolvers:" -msgstr "" +msgstr "Também em `config/web/di/application.php`, configure os resolvedores de parâmetros das actions:" #. type: Fenced code block (php) #: ../src/guide/rest/quick-start.md @@ -493,8 +687,23 @@ msgid "" " ],\n" "];\n" msgstr "" +"use Yiisoft\\Definitions\\Reference;\n" +"use Yiisoft\\Input\\Http\\HydratorAttributeParametersResolver;\n" +"use Yiisoft\\Input\\Http\\RequestInputParametersResolver;\n" +"use Yiisoft\\Middleware\\Dispatcher\\CompositeParametersResolver;\n" +"use Yiisoft\\Middleware\\Dispatcher\\ParametersResolverInterface;\n" +"\n" +"return [\n" +" ParametersResolverInterface::class => [\n" +" 'class' => CompositeParametersResolver::class,\n" +" '__construct()' => [\n" +" Reference::to(HydratorAttributeParametersResolver::class),\n" +" Reference::to(RequestInputParametersResolver::class),\n" +" ],\n" +" ],\n" +"];\n" #. type: Plain text #: ../src/guide/rest/quick-start.md msgid "Use the [API application template configuration](https://github.com/yiisoft/app-api/blob/master/config/web/di/application.php) as the complete reference for middleware order and resolver setup." -msgstr "" +msgstr "Use a [configuração do template de aplicação API](https://github.com/yiisoft/app-api/blob/master/config/web/di/application.php) como referência completa para a ordem dos middlewares e a configuração dos resolvedores." diff --git a/_translations/po/pt-BR/guide_runtime_logging.md.po b/_translations/po/pt-BR/guide_runtime_logging.md.po index 2c8dc76d..acf26e9a 100644 --- a/_translations/po/pt-BR/guide_runtime_logging.md.po +++ b/_translations/po/pt-BR/guide_runtime_logging.md.po @@ -80,7 +80,7 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "Without containers, the destination depends on how you start PHP and capture its output. For example, PHP-FPM discards worker output by default unless you enable `catch_workers_output`. See [web server logging configuration](../../cookbook/configuring-webservers/general.md#application-logs). To have Yii write application log files directly, configure a [file target](#logging-to-files)." -msgstr "Sem containers, o destino depende de como você inicia o PHP e captura a saída dele. Por exemplo, o PHP-FPM descarta a saída dos workers por padrão, a menos que você ative `catch_workers_output`. Veja a [configuração de logs do servidor web](../../cookbook/configuring-webservers/general.md#application-logs). Para o Yii escrever arquivos de log da aplicação diretamente, configure um [destino em arquivo](#logs-em-arquivos)." +msgstr "Sem containers, o destino depende de como você inicia o PHP e captura a saída dele. Por exemplo, o PHP-FPM descarta a saída dos workers por padrão, a menos que você ative `catch_workers_output`. Veja a [configuração de logs do servidor web](../../cookbook/configuring-webservers/general.md#logs-da-aplicacao). Para o Yii escrever arquivos de log da aplicação diretamente, configure um [destino em arquivo](#logs-em-arquivos)." #. type: Title ## #: ../src/guide/runtime/logging.md diff --git a/_translations/po/pt-BR/guide_security_authentication.md.po b/_translations/po/pt-BR/guide_security_authentication.md.po index 89533f7a..b4d7ddb6 100644 --- a/_translations/po/pt-BR/guide_security_authentication.md.po +++ b/_translations/po/pt-BR/guide_security_authentication.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-06-05 20:33+0000\n" "PO-Revision-Date: 2026-06-05 20:33+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,54 +19,54 @@ msgstr "" #: ../src/guide/security/authentication.md #, no-wrap msgid "Authentication" -msgstr "" +msgstr "Autenticação" #. type: Plain text #: ../src/guide/security/authentication.md msgid "Authentication is the process of verifying the identity of a user. It usually uses an identifier (for example, a username or an email address) and a secret token (such as a password or an access token) to judge if the user is the one whom he claims as. Authentication is the basis of the login feature." -msgstr "" +msgstr "Autenticação é o processo de verificar a identidade de um usuário. Normalmente ela usa um identificador (por exemplo, um nome de usuário ou um endereço de e-mail) e um token secreto (como uma senha ou um token de acesso) para decidir se o usuário é quem diz ser. A autenticação é a base do recurso de login." #. type: Plain text #: ../src/guide/security/authentication.md msgid "Yii provides an authentication framework which wires up various components to support login. To use this framework, you mainly need to do the following work:" -msgstr "" +msgstr "O Yii fornece um framework de autenticação que conecta vários componentes para dar suporte ao login. Para usar esse framework, você precisa basicamente fazer o seguinte:" #. type: Bullet: '* ' #: ../src/guide/security/authentication.md msgid "Configure the `Yiisoft\\User\\CurrentUser` service;" -msgstr "" +msgstr "Configurar o serviço `Yiisoft\\User\\CurrentUser`;" #. type: Bullet: '* ' #: ../src/guide/security/authentication.md msgid "Create a class implementing the `\\Yiisoft\\Auth\\IdentityInterface` interface;" -msgstr "" +msgstr "Criar uma classe que implementa a interface `\\Yiisoft\\Auth\\IdentityInterface`;" #. type: Bullet: '* ' #: ../src/guide/security/authentication.md msgid "Create a class implementing the `\\Yiisoft\\Auth\\IdentityRepositoryInterface` interface;" -msgstr "" +msgstr "Criar uma classe que implementa a interface `\\Yiisoft\\Auth\\IdentityRepositoryInterface`;" #. type: Plain text #: ../src/guide/security/authentication.md msgid "To use the `Yiisoft\\User\\CurrentUser` service, install [yiisoft/user](https://github.com/yiisoft/user) package:" -msgstr "" +msgstr "Para usar o serviço `Yiisoft\\User\\CurrentUser`, instale o pacote [yiisoft/user](https://github.com/yiisoft/user):" #. type: Fenced code block (shell) #: ../src/guide/security/authentication.md #, no-wrap msgid "composer require yiisoft/user\n" -msgstr "" +msgstr "composer require yiisoft/user\n" #. type: Title ## #: ../src/guide/security/authentication.md #, no-wrap msgid "Configuring `Yiisoft\\User\\CurrentUser`" -msgstr "" +msgstr "Configurando `Yiisoft\\User\\CurrentUser`" #. type: Plain text #: ../src/guide/security/authentication.md msgid "The `Yiisoft\\User\\CurrentUser` application service manages the user authentication status. It depends on `Yiisoft\\Auth\\IdentityRepositoryInterface` that should return an instance of `\\Yiisoft\\Auth\\IdentityInterface` which has the actual authentication logic." -msgstr "" +msgstr "O serviço de aplicação `Yiisoft\\User\\CurrentUser` gerencia o estado de autenticação do usuário. Ele depende de `Yiisoft\\Auth\\IdentityRepositoryInterface`, que deve retornar uma instância de `\\Yiisoft\\Auth\\IdentityInterface` contendo a lógica de autenticação de fato." #. type: Fenced code block (php) #: ../src/guide/security/authentication.md @@ -93,27 +93,47 @@ msgid "" " ],\n" "];\n" msgstr "" +"use Yiisoft\\Session\\Session;\n" +"use Yiisoft\\Session\\SessionInterface;\n" +"use Yiisoft\\Auth\\IdentityRepositoryInterface;\n" +"use Yiisoft\\Definitions\\Reference;\n" +"\n" +"return [\n" +" // ...\n" +"\n" +" SessionInterface::class => [\n" +" 'class' => Session::class,\n" +" '__construct()' => [\n" +" $params['session']['options'] ?? [],\n" +" $params['session']['handler'] ?? null,\n" +" ],\n" +" ],\n" +" IdentityRepositoryInterface::class => IdentityRepository::class,\n" +" CurrentUser::class => [\n" +" 'withSession()' => [Reference::to(SessionInterface::class)]\n" +" ],\n" +"];\n" #. type: Title ## #: ../src/guide/security/authentication.md #, no-wrap msgid "Implementing`\\Yiisoft\\Auth\\IdentityInterface`" -msgstr "" +msgstr "Implementando`\\Yiisoft\\Auth\\IdentityInterface`" #. type: Plain text #: ../src/guide/security/authentication.md msgid "The identity class must implement the `\\Yiisoft\\Auth\\IdentityInterface` which has a single method:" -msgstr "" +msgstr "A classe de identidade deve implementar a `\\Yiisoft\\Auth\\IdentityInterface`, que tem um único método:" #. type: Bullet: '* ' #: ../src/guide/security/authentication.md msgid "[[yii\\web\\IdentityInterface::getId()|getId()]]: it returns the ID of the user represented by this identity instance." -msgstr "" +msgstr "[[yii\\web\\IdentityInterface::getId()|getId()]]: retorna o ID do usuário representado por esta instância de identidade." #. type: Plain text #: ../src/guide/security/authentication.md msgid "In the following example, an identity class is implemented as a pure PHP object." -msgstr "" +msgstr "No exemplo a seguir, a classe de identidade é implementada como um objeto PHP puro." #. type: Fenced code block (php) #: ../src/guide/security/authentication.md @@ -138,32 +158,50 @@ msgid "" " }\n" "}\n" msgstr "" +"id;\n" +" }\n" +"}\n" #. type: Title ## #: ../src/guide/security/authentication.md #, no-wrap msgid "Implementing`\\Yiisoft\\Auth\\IdentityRepositoryInterface`" -msgstr "" +msgstr "Implementando`\\Yiisoft\\Auth\\IdentityRepositoryInterface`" #. type: Plain text #: ../src/guide/security/authentication.md msgid "The identity repository class must implement the `\\Yiisoft\\Auth\\IdentityRepositoryInterface` which has the following methods:" -msgstr "" +msgstr "A classe de repositório de identidades deve implementar a `\\Yiisoft\\Auth\\IdentityRepositoryInterface`, que tem os seguintes métodos:" #. type: Bullet: '* ' #: ../src/guide/security/authentication.md msgid "`findIdentity(string $id): ?IdentityInterface`: it looks for an instance of the identity class using the specified ID. This method is used when you need to keep the login status via session." -msgstr "" +msgstr "`findIdentity(string $id): ?IdentityInterface`: procura uma instância da classe de identidade usando o ID informado. Esse método é usado quando você precisa manter o estado de login via sessão." #. type: Bullet: '* ' #: ../src/guide/security/authentication.md msgid "`findIdentityByToken(string $token, string $type): ?IdentityInterface`: it looks for an instance of the identity class using the specified access token. This method is used when you need to authenticate a user by a single secret token (for example, in a stateless REST API)." -msgstr "" +msgstr "`findIdentityByToken(string $token, string $type): ?IdentityInterface`: procura uma instância da classe de identidade usando o token de acesso informado. Esse método é usado quando você precisa autenticar um usuário por um único token secreto (por exemplo, numa API REST sem estado)." #. type: Plain text #: ../src/guide/security/authentication.md msgid "A dummy implementation may look like the following:" -msgstr "" +msgstr "Uma implementação fictícia pode ficar assim:" #. type: Fenced code block (php) #: ../src/guide/security/authentication.md @@ -211,17 +249,58 @@ msgid "" " }\n" "}\n" msgstr "" +"namespace App\\User;\n" +"\n" +"use App\\User\\Identity;\n" +"use \\Yiisoft\\Auth\\IdentityInterface;\n" +"use \\Yiisoft\\Auth\\IdentityRepositoryInterface;\n" +"\n" +"final readonly class IdentityRepository implements IdentityRepositoryInterface\n" +"{\n" +" private const USERS = [\n" +" [\n" +" 'id' => 1,\n" +" 'token' => '12345' \n" +" ],\n" +" [\n" +" 'id' => 42,\n" +" 'token' => '54321'\n" +" ], \n" +" ];\n" +"\n" +" public function findIdentity(string $id) : ?IdentityInterface\n" +" {\n" +" foreach (self::USERS as $user) {\n" +" if ((string)$user['id'] === $id) {\n" +" return new Identity($id); \n" +" }\n" +" }\n" +" \n" +" return null;\n" +" }\n" +"\n" +" public function findIdentityByToken(string $token, string $type) : ?IdentityInterface\n" +" {\n" +" foreach (self::USERS as $user) {\n" +" if ($user['token'] === $token) {\n" +" return new Identity((string)$user['id']); \n" +" }\n" +" }\n" +" \n" +" return null;\n" +" }\n" +"}\n" #. type: Title ## #: ../src/guide/security/authentication.md #, no-wrap msgid "Using `Yiisoft\\User\\CurrentUser`" -msgstr "" +msgstr "Usando `Yiisoft\\User\\CurrentUser`" #. type: Plain text #: ../src/guide/security/authentication.md msgid "You can use `Yiisoft\\User\\CurrentUser` service to get current user identity. As any service, it could be auto-wired in either action handler constructor or method:" -msgstr "" +msgstr "Você pode usar o serviço `Yiisoft\\User\\CurrentUser` para obter a identidade do usuário atual. Como qualquer serviço, ele pode ser injetado automaticamente (autowiring) no construtor ou no método do handler da action:" #. type: Fenced code block (php) #: ../src/guide/security/authentication.md @@ -245,16 +324,33 @@ msgid "" " }\n" "}\n" msgstr "" +"use Psr\\Http\\Message\\ServerRequestInterface;\n" +"use Yiisoft\\User\\CurrentUser;\n" +"\n" +"final readonly class SiteController\n" +"{\n" +" public function __construct(private CurrentUser $user) {}\n" +"\n" +" public function index(ServerRequestInterface $request): ResponseInterface\n" +" {\n" +" if ($this->user->isGuest()) {\n" +" // o usuário é visitante\n" +" } else {\n" +" $identity = $this->user->getIdentity();\n" +" // faça algo com base na identidade\n" +" }\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/security/authentication.md msgid "`isGuest()` determines if user is logged in or not. `getIdentity()` returns an instance of identity." -msgstr "" +msgstr "`isGuest()` determina se o usuário está logado ou não. `getIdentity()` retorna uma instância da identidade." #. type: Plain text #: ../src/guide/security/authentication.md msgid "To log in a user, you may use the following code:" -msgstr "" +msgstr "Para fazer o login de um usuário, você pode usar o seguinte código:" #. type: Fenced code block (php) #: ../src/guide/security/authentication.md @@ -265,16 +361,20 @@ msgid "" "/* @var $user \\Yiisoft\\User\\CurrentUser */\n" "$user->login($identity);\n" msgstr "" +"$identity = $identityRepository->findByEmail($email);\n" +"\n" +"/* @var $user \\Yiisoft\\User\\CurrentUser */\n" +"$user->login($identity);\n" #. type: Plain text #: ../src/guide/security/authentication.md msgid "The `login()` method sets the identity to the User service. It stores identity into session so user authentication status is maintained." -msgstr "" +msgstr "O método `login()` define a identidade no serviço de usuário. Ele armazena a identidade na sessão, para que o estado de autenticação do usuário seja mantido." #. type: Plain text #: ../src/guide/security/authentication.md msgid "To log out a user, call" -msgstr "" +msgstr "Para fazer o logout de um usuário, chame" #. type: Fenced code block (php) #: ../src/guide/security/authentication.md @@ -283,22 +383,24 @@ msgid "" "/* @var $user \\Yiisoft\\User\\CurrentUser */\n" "$user->logout();\n" msgstr "" +"/* @var $user \\Yiisoft\\User\\CurrentUser */\n" +"$user->logout();\n" #. type: Title ## #: ../src/guide/security/authentication.md #, no-wrap msgid "Protecting Routes" -msgstr "" +msgstr "Protegendo rotas" #. type: Plain text #: ../src/guide/security/authentication.md msgid "The `Yiisoft\\Auth\\Middleware\\Authentication` middleware can be used to restrict access to a given route to authenticated users only." -msgstr "" +msgstr "O middleware `Yiisoft\\Auth\\Middleware\\Authentication` pode ser usado para restringir o acesso a uma rota apenas a usuários autenticados." #. type: Plain text #: ../src/guide/security/authentication.md msgid "First, configure the `Yiisoft\\Auth\\AuthenticationMethodInterface`:" -msgstr "" +msgstr "Primeiro, configure a `Yiisoft\\Auth\\AuthenticationMethodInterface`:" #. type: Fenced code block (php) #: ../src/guide/security/authentication.md @@ -312,11 +414,18 @@ msgid "" " AuthenticationMethodInterface::class => WebAuth::class,\n" "];\n" msgstr "" +"use Yiisoft\\Auth\\AuthenticationMethodInterface;\n" +"use Yiisoft\\User\\Method\\WebAuth;\n" +"\n" +"return [\n" +" // ...\n" +" AuthenticationMethodInterface::class => WebAuth::class,\n" +"];\n" #. type: Plain text #: ../src/guide/security/authentication.md msgid "Then, apply the `Yiisoft\\Auth\\Middleware\\Authentication` middleware to a route:" -msgstr "" +msgstr "Depois, aplique o middleware `Yiisoft\\Auth\\Middleware\\Authentication` a uma rota:" #. type: Fenced code block (php) #: ../src/guide/security/authentication.md @@ -329,12 +438,18 @@ msgid "" " ->action([SiteController::class, 'create'])\n" " ->name('site/create')\n" msgstr "" +"use Yiisoft\\Auth\\Middleware\\Authentication;\n" +" \n" +"Route::post('/create')\n" +" ->middleware(Authentication::class)\n" +" ->action([SiteController::class, 'create'])\n" +" ->name('site/create')\n" #. type: Plain text #: ../src/guide/security/authentication.md #, no-wrap msgid " Or to a group of routes:\n" -msgstr "" +msgstr " Ou a um grupo de rotas:\n" #. type: Fenced code block (php) #: ../src/guide/security/authentication.md @@ -353,39 +468,51 @@ msgid "" " ->name('site/update')\n" " )\n" msgstr "" +"use Yiisoft\\Auth\\Middleware\\Authentication;\n" +"\n" +"Group::create()\n" +" ->middleware(Authentication::class)\n" +" ->routes(\n" +" Route::post('/create')\n" +" ->action([SiteController::class, 'create'])\n" +" ->name('site/create'),\n" +" Route::put('/update/{id}')\n" +" ->action([SiteController::class, 'update'])\n" +" ->name('site/update')\n" +" )\n" #. type: Title ## #: ../src/guide/security/authentication.md #, no-wrap msgid "Authentication Events" -msgstr "" +msgstr "Eventos de autenticação" #. type: Plain text #: ../src/guide/security/authentication.md msgid "The user service raises a few events during the login and logout processes." -msgstr "" +msgstr "O serviço de usuário dispara alguns eventos durante os processos de login e logout." #. type: Bullet: '* ' #: ../src/guide/security/authentication.md msgid "`\\Yiisoft\\User\\Event\\BeforeLogin`: raised at the beginning of `login()`. If the event handler calls `invalidate()` on an event object, the login process will be cancelled." -msgstr "" +msgstr "`\\Yiisoft\\User\\Event\\BeforeLogin`: disparado no início de `login()`. Se o handler do evento chamar `invalidate()` no objeto do evento, o processo de login será cancelado." #. type: Bullet: '* ' #: ../src/guide/security/authentication.md msgid "`\\Yiisoft\\User\\Event\\AfterLogin`: raised after a successful login." -msgstr "" +msgstr "`\\Yiisoft\\User\\Event\\AfterLogin`: disparado após um login bem-sucedido." #. type: Bullet: '* ' #: ../src/guide/security/authentication.md msgid "`\\Yiisoft\\User\\Event\\BeforeLogout`: raised at the beginning of `logout()`. If the event handler calls `invalidate()` on an event object, the logout process will be cancelled." -msgstr "" +msgstr "`\\Yiisoft\\User\\Event\\BeforeLogout`: disparado no início de `logout()`. Se o handler do evento chamar `invalidate()` no objeto do evento, o processo de logout será cancelado." #. type: Bullet: '* ' #: ../src/guide/security/authentication.md msgid "`\\Yiisoft\\User\\Event\\AfterLogout`: raised after a successful logout." -msgstr "" +msgstr "`\\Yiisoft\\User\\Event\\AfterLogout`: disparado após um logout bem-sucedido." #. type: Plain text #: ../src/guide/security/authentication.md msgid "You may respond to these events to implement features such as login audit, online user statistics. For example, in the handler for `\\Yiisoft\\User\\Event\\AfterLogin`, you may record the login time and IP address in the `user` database table." -msgstr "" +msgstr "Você pode responder a esses eventos para implementar recursos como auditoria de login ou estatísticas de usuários online. Por exemplo, no handler de `\\Yiisoft\\User\\Event\\AfterLogin`, você pode registrar o horário e o endereço IP do login na tabela `user` do banco de dados." diff --git a/_translations/po/pt-BR/guide_security_authorization.md.po b/_translations/po/pt-BR/guide_security_authorization.md.po index f0288ee2..3badd80e 100644 --- a/_translations/po/pt-BR/guide_security_authorization.md.po +++ b/_translations/po/pt-BR/guide_security_authorization.md.po @@ -8,41 +8,40 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-06-05 20:33+0000\n" "PO-Revision-Date: 2026-06-05 20:33+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Fenced code block -#: ../src/guide/databases/db-migrations.md -#: ../src/guide/security/authorization.md +#: ../src/guide/databases/db-migrations.md ../src/guide/security/authorization.md #, no-wrap msgid "./yii migrate:up\n" -msgstr "" +msgstr "./yii migrate:up\n" #. type: Title # #: ../src/guide/security/authorization.md #, no-wrap msgid "Authorization" -msgstr "" +msgstr "Autorização" #. type: Plain text #: ../src/guide/security/authorization.md msgid "Authorization is the process of verifying that a user has enough permission to do something." -msgstr "" +msgstr "Autorização é o processo de verificar se um usuário tem permissão suficiente para fazer algo." #. type: Title ## #: ../src/guide/security/authorization.md #, no-wrap msgid "Checking for permission" -msgstr "" +msgstr "Verificando permissões" #. type: Plain text #: ../src/guide/security/authorization.md msgid "You can check if a user has certain permissions by using `\\Yiisoft\\User\\CurrentUser` service:" -msgstr "" +msgstr "Você pode verificar se um usuário tem determinadas permissões usando o serviço `\\Yiisoft\\User\\CurrentUser`:" #. type: Fenced code block (php) #: ../src/guide/security/authorization.md @@ -84,116 +83,151 @@ msgid "" " }\n" "}\n" msgstr "" +"namespace App\\Blog\\Post;\n" +"\n" +"use Yiisoft\\User\\CurrentUser;\n" +"use Yiisoft\\Router\\HydratorAttribute\\RouteArgument;\n" +"use Psr\\Http\\Message\\ResponseInterface;\n" +"\n" +"final readonly class PostController\n" +"{\n" +" public function __construct(\n" +" private PostRepositoryInterface $postRepository,\n" +" private CurrentUser $user\n" +" )\n" +" {\n" +" }\n" +"\n" +" public function update(#[RouteArgument('id')] int $id): ResponseInterface\n" +" {\n" +" $post = $this->postRepository->findByPK($id);\n" +" if ($post === null) {\n" +" // responda com 404\n" +" }\n" +"\n" +" if (!$this->canCurrentUserUpdatePost($post)) {\n" +" // responda com 403\n" +" }\n" +"\n" +" // continue com a atualização do post\n" +" }\n" +"\n" +" private function canCurrentUserUpdatePost(Post $post): bool\n" +" {\n" +" return $post->getAuthorId() === $this->user->getId() &&\n" +" $this->user->can('updatePost');\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/security/authorization.md msgid "Behind the scenes, `Yiisoft\\User\\CurrentUser::can()` method calls `Yiisoft\\Access\\AccessCheckerInterface::userHasPermission()` so you should provide an implementation in dependency container in order for it to work." -msgstr "" +msgstr "Por baixo dos panos, o método `Yiisoft\\User\\CurrentUser::can()` chama `Yiisoft\\Access\\AccessCheckerInterface::userHasPermission()`, então você precisa fornecer uma implementação no container de dependências para que ele funcione." #. type: Title ## #: ../src/guide/security/authorization.md #, no-wrap msgid "Role-based access control (RBAC)" -msgstr "" +msgstr "Controle de acesso baseado em papéis (RBAC)" #. type: Plain text #: ../src/guide/security/authorization.md msgid "Role-Based Access Control (RBAC) provides a simple yet powerful centralized access control. Please refer to the [Wikipedia](https://en.wikipedia.org/wiki/Role-based_access_control) for details about comparing RBAC with other more traditional access control schemes." -msgstr "" +msgstr "O controle de acesso baseado em papéis (RBAC, Role-Based Access Control) oferece um controle de acesso centralizado simples e flexível. Consulte a [Wikipedia](https://en.wikipedia.org/wiki/Role-based_access_control) para detalhes sobre a comparação do RBAC com outros esquemas de controle de acesso mais tradicionais." #. type: Plain text #: ../src/guide/security/authorization.md msgid "Yii implements a General Hierarchical RBAC, following the [NIST RBAC model](https://csrc.nist.gov/CSRC/media/Publications/conference-paper/2000/07/26/the-nist-model-for-role-based-access-control-towards-a-unified-/documents/sandhu-ferraiolo-kuhn-00.pdf)." -msgstr "" +msgstr "O Yii implementa um RBAC hierárquico geral, seguindo o [modelo RBAC do NIST](https://csrc.nist.gov/CSRC/media/Publications/conference-paper/2000/07/26/the-nist-model-for-role-based-access-control-towards-a-unified-/documents/sandhu-ferraiolo-kuhn-00.pdf)." #. type: Plain text #: ../src/guide/security/authorization.md msgid "Using RBAC involves two parts of work. The first part is to build up the RBAC authorization data, and the second part is to use the authorization data to perform access check in places where it's necessary. Since RBAC implements `\\Yiisoft\\Access\\AccessCheckerInterface`, using it's similar to using any other implementation of an access checker." -msgstr "" +msgstr "Usar RBAC envolve duas partes de trabalho. A primeira é montar os dados de autorização do RBAC, e a segunda é usar esses dados para fazer a verificação de acesso onde for necessário. Como o RBAC implementa `\\Yiisoft\\Access\\AccessCheckerInterface`, usá-lo é parecido com usar qualquer outra implementação de verificador de acesso." #. type: Plain text #: ../src/guide/security/authorization.md msgid "To ease description next, there are some basic RBAC concepts first." -msgstr "" +msgstr "Para facilitar a explicação a seguir, primeiro alguns conceitos básicos de RBAC." #. type: Title ### #: ../src/guide/security/authorization.md #, no-wrap msgid "Basic concepts" -msgstr "" +msgstr "Conceitos básicos" #. type: Plain text #: ../src/guide/security/authorization.md msgid "A role represents a collection of *permissions* (for example, creating posts, updating posts). You may assign a role to one or many users. To check if a user has a specified permission, you may check if the user has a role with that permission." -msgstr "" +msgstr "Um papel representa um conjunto de *permissões* (por exemplo, criar posts, atualizar posts). Você pode atribuir um papel a um ou mais usuários. Para verificar se um usuário tem uma determinada permissão, você pode verificar se ele tem um papel com essa permissão." #. type: Plain text #: ../src/guide/security/authorization.md msgid "Associated with each role or permission, there may be a *rule*. A rule represents a piece of code that an access checker will execute to decide if the corresponding role or permission applies to the current user. For example, the \"update post\" permission may have a rule that checks if the current user is the post creator. During access checking, if the user is NOT the post creator, there's no \"update post\" permission." -msgstr "" +msgstr "Cada papel ou permissão pode ter uma *regra* associada. Uma regra representa um trecho de código que o verificador de acesso executa para decidir se o papel ou a permissão correspondente se aplica ao usuário atual. Por exemplo, a permissão \"atualizar post\" pode ter uma regra que verifica se o usuário atual é o criador do post. Durante a verificação de acesso, se o usuário NÃO for o criador do post, ele não tem a permissão \"atualizar post\"." #. type: Plain text #: ../src/guide/security/authorization.md msgid "Both roles and permissions are in a hierarchy. In particular, a role may consist of other roles or permissions. And a permission may consist of other permissions. Yii implements a *partial order* hierarchy which includes the more special *tree* hierarchy. While a role can contain a permission, it isn't `true` vice versa." -msgstr "" +msgstr "Tanto papéis quanto permissões ficam em uma hierarquia. Em particular, um papel pode ser composto de outros papéis ou permissões. E uma permissão pode ser composta de outras permissões. O Yii implementa uma hierarquia de *ordem parcial*, que inclui a hierarquia mais específica em *árvore*. Embora um papel possa conter uma permissão, o inverso não é verdadeiro." #. type: Title ### #: ../src/guide/security/authorization.md #, no-wrap msgid "Configuring RBAC" -msgstr "" +msgstr "Configurando o RBAC" #. type: Plain text #: ../src/guide/security/authorization.md msgid "Yii RBAC requires storage to be provided." -msgstr "" +msgstr "O RBAC do Yii exige que um armazenamento seja fornecido." #. type: Plain text #: ../src/guide/security/authorization.md msgid "One of the following storages could be installed:" -msgstr "" +msgstr "Um dos seguintes armazenamentos pode ser instalado:" #. type: Bullet: '- ' #: ../src/guide/security/authorization.md msgid "[PHP storage](https://github.com/yiisoft/rbac-php) - PHP file storage;" -msgstr "" +msgstr "[Armazenamento PHP](https://github.com/yiisoft/rbac-php) - armazenamento em arquivos PHP;" #. type: Bullet: '- ' #: ../src/guide/security/authorization.md msgid "[DB storage](https://github.com/yiisoft/rbac-db) - database storage based on [Yii DB](https://github.com/yiisoft/db);" -msgstr "" +msgstr "[Armazenamento em DB](https://github.com/yiisoft/rbac-db) - armazenamento em banco de dados baseado no [Yii DB](https://github.com/yiisoft/db);" #. type: Bullet: '- ' #: ../src/guide/security/authorization.md msgid "[Cycle DB storage](https://github.com/yiisoft/rbac-cycle-db) - database storage based on [Cycle DBAL](https://github.com/cycle/database)." -msgstr "" +msgstr "[Armazenamento Cycle DB](https://github.com/yiisoft/rbac-cycle-db) - armazenamento em banco de dados baseado no [Cycle DBAL](https://github.com/cycle/database)." #. type: Plain text #: ../src/guide/security/authorization.md msgid "You can also provide your own storage using the [yiisoft/rbac](https://github.com/yiisoft/rbac) package." -msgstr "" +msgstr "Você também pode fornecer seu próprio armazenamento usando o pacote [yiisoft/rbac](https://github.com/yiisoft/rbac)." #. type: Title #### #: ../src/guide/security/authorization.md #, no-wrap msgid "Configuring RBAC with the [PHP storage](https://github.com/yiisoft/rbac-php)" -msgstr "" +msgstr "Configurando o RBAC com o [armazenamento PHP](https://github.com/yiisoft/rbac-php)" #. type: Plain text #: ../src/guide/security/authorization.md msgid "Install [yiisoft/rbac-php](https://github.com/yiisoft/rbac-php) package:" -msgstr "" +msgstr "Instale o pacote [yiisoft/rbac-php](https://github.com/yiisoft/rbac-php):" #. type: Fenced code block #: ../src/guide/security/authorization.md #, no-wrap msgid "composer require yiisoft/rbac-php\n" -msgstr "" +msgstr "composer require yiisoft/rbac-php\n" #. type: Plain text #: ../src/guide/security/authorization.md msgid "Before we set off to define authorization data and perform access checking, you need to configure the `Yiisoft\\Access\\AccessCheckerInterface` in dependency container:" -msgstr "" +msgstr "Antes de definir os dados de autorização e fazer verificações de acesso, você precisa configurar a `Yiisoft\\Access\\AccessCheckerInterface` no container de dependências:" #. type: Fenced code block (php) #: ../src/guide/security/authorization.md @@ -228,28 +262,56 @@ msgid "" " ],\n" "];\n" msgstr "" +"use Yiisoft\\Rbac\\ItemsStorageInterface;\n" +"use Yiisoft\\Rbac\\AssignmentsStorageInterface;\n" +"use Yiisoft\\Rbac\\ManagerInterface;\n" +"use Yiisoft\\Rbac\\Php\\ItemsStorage;\n" +"use Yiisoft\\Rbac\\Php\\AssignmentsStorage;\n" +"use Yiisoft\\Access\\AccessCheckerInterface;\n" +"use Yiisoft\\User\\CurrentUser;\n" +"\n" +"return [\n" +" // ...\n" +" ItemsStorageInterface::class => [\n" +" 'class' => ItemsStorage::class,\n" +" '__construct()' => [\n" +" 'filePath' => $params['rbacItemsStorageFilePath']\n" +" ]\n" +" ],\n" +" AssignmentsStorageInterface::class => [\n" +" 'class' => AssignmentsStorage::class,\n" +" '__construct()' => [\n" +" 'filePath' => $params['rbacAssignmentsStorageFilePath']\n" +" ]\n" +" ],\n" +" AccessCheckerInterface::class => ManagerInterface::class,\n" +"\n" +" CurrentUser::class => [\n" +" 'withAccessChecker()' => [Reference::to(AccessCheckerInterface::class)]\n" +" ],\n" +"];\n" #. type: Plain text #: ../src/guide/security/authorization.md msgid "`Yiisoft\\Rbac\\Manager` uses PHP script files to store authorization data. Make sure the directory and all the files in it are writable by the Web server process if you want to change permission hierarchy online." -msgstr "" +msgstr "O `Yiisoft\\Rbac\\Manager` usa arquivos de script PHP para armazenar os dados de autorização. Garanta que o diretório e todos os arquivos dentro dele tenham permissão de escrita para o processo do servidor web, se você quiser alterar a hierarquia de permissões em tempo de execução." #. type: Title #### #: ../src/guide/security/authorization.md #, no-wrap msgid "Configuring RBAC with the [DB storage](https://github.com/yiisoft/rbac-db)" -msgstr "" +msgstr "Configurando o RBAC com o [armazenamento em DB](https://github.com/yiisoft/rbac-db)" #. type: Plain text #: ../src/guide/security/authorization.md msgid "Install [yiisoft/rbac-db](https://github.com/yiisoft/rbac-db) package:" -msgstr "" +msgstr "Instale o pacote [yiisoft/rbac-db](https://github.com/yiisoft/rbac-db):" #. type: Fenced code block #: ../src/guide/security/authorization.md #, no-wrap msgid "composer require yiisoft/rbac-db\n" -msgstr "" +msgstr "composer require yiisoft/rbac-db\n" #. type: Plain text #: ../src/guide/security/authorization.md @@ -262,11 +324,17 @@ msgid "" " - [Microsoft SQL Server](https://github.com/yiisoft/db-mssql)\n" " - [Oracle](https://github.com/yiisoft/db-oracle)\n" msgstr "" +"Instale um dos seguintes drivers:\n" +" - [SQLite](https://github.com/yiisoft/db-sqlite) (a versão mínima exigida é a 3.8.3)\n" +" - [MySQL](https://github.com/yiisoft/db-mysql)\n" +" - [PostgreSQL](https://github.com/yiisoft/db-pgsql)\n" +" - [Microsoft SQL Server](https://github.com/yiisoft/db-mssql)\n" +" - [Oracle](https://github.com/yiisoft/db-oracle)\n" #. type: Plain text #: ../src/guide/security/authorization.md msgid "[Configure connection](https://yiisoft.github.io/docs/guide/start/databases.html#configuring-connection)." -msgstr "" +msgstr "[Configure a conexão](https://yiisoft.github.io/docs/guide/start/databases.html#configuring-connection)." #. type: Fenced code block (php) #: ../src/guide/security/authorization.md @@ -286,11 +354,24 @@ msgid "" " AccessCheckerInterface::class => ManagerInterface::class,\n" "];\n" msgstr "" +"use Yiisoft\\Rbac\\ItemsStorageInterface;\n" +"use Yiisoft\\Rbac\\AssignmentsStorageInterface;\n" +"use Yiisoft\\Rbac\\ManagerInterface;\n" +"use Yiisoft\\Rbac\\Db\\ItemsStorage;\n" +"use Yiisoft\\Rbac\\Db\\AssignmentsStorage;\n" +"use Yiisoft\\Access\\AccessCheckerInterface;\n" +"\n" +"return [\n" +" // ...\n" +" ItemsStorageInterface::class => ItemsStorage::class,\n" +" AssignmentsStorageInterface::class => AssignmentsStorage::class,\n" +" AccessCheckerInterface::class => ManagerInterface::class,\n" +"];\n" #. type: Plain text #: ../src/guide/security/authorization.md msgid "Add the RBAC [DB storage](https://github.com/yiisoft/rbac-db) migration paths to params.php:" -msgstr "" +msgstr "Adicione os caminhos das migrations do [armazenamento em DB](https://github.com/yiisoft/rbac-db) do RBAC ao params.php:" #. type: Fenced code block (php) #: ../src/guide/security/authorization.md @@ -306,78 +387,87 @@ msgid "" " ],\n" "];\n" msgstr "" +"return [\n" +" // ...\n" +" 'yiisoft/db-migration' => [\n" +" 'sourcePaths' => [\n" +" __DIR__ . '/../../vendor/yiisoft/rbac-db/migrations/items',\n" +" __DIR__ . '/../../vendor/yiisoft/rbac-db/migrations/assignments',\n" +" ],\n" +" ],\n" +"];\n" #. type: Plain text #: ../src/guide/security/authorization.md msgid "Apply migrations:" -msgstr "" +msgstr "Aplique as migrations:" #. type: Title ### #: ../src/guide/security/authorization.md #, no-wrap msgid "Building authorization data" -msgstr "" +msgstr "Montando os dados de autorização" #. type: Plain text #: ../src/guide/security/authorization.md msgid "Building authorization data is all about the following tasks:" -msgstr "" +msgstr "Montar os dados de autorização consiste nas seguintes tarefas:" #. type: Bullet: '- ' #: ../src/guide/security/authorization.md msgid "defining roles and permissions;" -msgstr "" +msgstr "definir papéis e permissões;" #. type: Bullet: '- ' #: ../src/guide/security/authorization.md msgid "establishing relations between roles and permissions;" -msgstr "" +msgstr "estabelecer relações entre papéis e permissões;" #. type: Bullet: '- ' #: ../src/guide/security/authorization.md msgid "defining rules;" -msgstr "" +msgstr "definir regras;" #. type: Bullet: '- ' #: ../src/guide/security/authorization.md msgid "associating rules with roles and permissions;" -msgstr "" +msgstr "associar regras a papéis e permissões;" #. type: Bullet: '- ' #: ../src/guide/security/authorization.md msgid "assigning roles to users." -msgstr "" +msgstr "atribuir papéis a usuários." #. type: Plain text #: ../src/guide/security/authorization.md msgid "Depending on authorization flexibility requirements, you can do the tasks in different ways. If only developers change your permission hierarchy, you can use either migrations or a console command. Migration advantage is that you could execute it along with other migrations. The Console command advantage is that you have a good overview of the hierarchy in the code without a need to read many migrations." -msgstr "" +msgstr "Dependendo da flexibilidade de autorização exigida, você pode fazer essas tarefas de maneiras diferentes. Se apenas desenvolvedores alteram sua hierarquia de permissões, você pode usar migrations ou um comando de console. A vantagem da migration é que você pode executá-la junto com as outras migrations. A vantagem do comando de console é que você tem uma boa visão da hierarquia no código, sem precisar ler muitas migrations." #. type: Plain text #: ../src/guide/security/authorization.md msgid "Either way, in the end, you'll get the following RBAC hierarchy:" -msgstr "" +msgstr "De qualquer forma, no fim você terá a seguinte hierarquia RBAC:" #. type: Plain text #: ../src/guide/security/authorization.md msgid "![Simple RBAC hierarchy](/images/guide/security/rbac-hierarchy-1.svg \"Simple RBAC hierarchy\")" -msgstr "" +msgstr "![Hierarquia RBAC simples](/images/guide/security/rbac-hierarchy-1.svg \"Hierarquia RBAC simples\")" #. type: Plain text #: ../src/guide/security/authorization.md msgid "In case you want to build permission hierarchy dynamically, you need a UI or a console command. The API used to build the hierarchy itself won't be different." -msgstr "" +msgstr "Caso você queira montar a hierarquia de permissões dinamicamente, precisa de uma interface de usuário ou de um comando de console. A API usada para montar a hierarquia em si não muda." #. type: Title ### #: ../src/guide/security/authorization.md #, no-wrap msgid "Using console command" -msgstr "" +msgstr "Usando um comando de console" #. type: Plain text #: ../src/guide/security/authorization.md msgid "If your permission hierarchy doesn't change at all, and you have a fixed number of users, you can create a [console command](../tutorial/console-applications.md) that will initialize authorization data once via APIs offered by `\\Yiisoft\\Rbac\\ManagerInterface`:" -msgstr "" +msgstr "Se a sua hierarquia de permissões não muda nunca e você tem um número fixo de usuários, pode criar um [comando de console](../tutorial/console-applications.md) que inicializa os dados de autorização uma única vez, usando as APIs oferecidas por `\\Yiisoft\\Rbac\\ManagerInterface`:" #. type: Fenced code block (php) #: ../src/guide/security/authorization.md @@ -449,11 +539,76 @@ msgid "" " }\n" "}\n" msgstr "" +"removeAll();\n" +"\n" +" $this->manager->addPermission((new Permission(RbacCommand::CREATE_POST_PERMISSION))->withDescription('Create a post'));\n" +" $this->manager->addPermission((new Permission(RbacCommand::UPDATE_POST_PERMISSION))->withDescription('Update post'));\n" +"\n" +" // adiciona o papel \"author\" e dá a ele a permissão \"createPost\"\n" +" $this->manager->addRole(new Role(RbacCommand::ROLE_AUTHOR));\n" +" $this->manager->addChild(RbacCommand::ROLE_AUTHOR, RbacCommand::CREATE_POST_PERMISSION);\n" +"\n" +" // adiciona o papel \"admin\" e dá a ele a permissão \"updatePost\"\n" +" // além das permissões do papel \"author\"\n" +" $this->manager->addRole(new Role(RbacCommand::ROLE_ADMIN));\n" +" $this->manager->addChild(RbacCommand::ROLE_ADMIN, RbacCommand::UPDATE_POST_PERMISSION);\n" +" $this->manager->addChild(RbacCommand::ROLE_ADMIN, RbacCommand::ROLE_AUTHOR);\n" +"\n" +" // Atribui papéis aos usuários. 1 e 2 são IDs retornados por IdentityInterface::getId(),\n" +" // normalmente implementado no seu model User.\n" +" $this->manager->assign(RbacCommand::ROLE_AUTHOR, 2);\n" +" $this->manager->assign(RbacCommand::ROLE_ADMIN, 1);\n" +"\n" +" return ExitCode::OK;\n" +" }\n" +"\n" +" private function removeAll(): void\n" +" {\n" +" $this->manager->revokeAll(2);\n" +" $this->manager->revokeAll(1);\n" +"\n" +" $this->manager->removeRole(RbacCommand::ROLE_ADMIN);\n" +" $this->manager->removeRole(RbacCommand::ROLE_AUTHOR);\n" +"\n" +" $this->manager->removePermission(RbacCommand::CREATE_POST_PERMISSION);\n" +" $this->manager->removePermission(RbacCommand::UPDATE_POST_PERMISSION);\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/security/authorization.md msgid "Add the command to `config/console/commands.php`:" -msgstr "" +msgstr "Adicione o comando em `config/console/commands.php`:" #. type: Fenced code block (php) #: ../src/guide/security/authorization.md @@ -464,17 +619,21 @@ msgid "" " 'rbac:init' => App\\Command\\RbacCommand::class\n" "];\n" msgstr "" +"return [ \n" +" // ...\n" +" 'rbac:init' => App\\Command\\RbacCommand::class\n" +"];\n" #. type: Plain text #: ../src/guide/security/authorization.md msgid "You can execute the command above from the console the following way:" -msgstr "" +msgstr "Você pode executar o comando acima no console da seguinte forma:" #. type: Fenced code block #: ../src/guide/security/authorization.md #, no-wrap msgid "./yii rbac:init\n" -msgstr "" +msgstr "./yii rbac:init\n" #. type: Plain text #: ../src/guide/security/authorization.md @@ -483,28 +642,30 @@ msgid "" "> If you don't want to hardcode what users have certain roles, don't put `->assign()` calls into the command. Instead,\n" " create either UI or console command to manage assignments.\n" msgstr "" +"> Se você não quer deixar fixo no código quais usuários têm determinados papéis, não coloque chamadas `->assign()` no comando. Em vez disso,\n" +" crie uma interface de usuário ou um comando de console para gerenciar as atribuições.\n" #. type: Title #### #: ../src/guide/security/authorization.md #, no-wrap msgid "Using migrations" -msgstr "" +msgstr "Usando migrations" #. type: Plain text #: ../src/guide/security/authorization.md #, no-wrap msgid "**TODO**: finish it when migrations are implemented.\n" -msgstr "" +msgstr "**TODO**: terminar quando as migrations forem implementadas.\n" #. type: Plain text #: ../src/guide/security/authorization.md msgid "You can use [migrations](../databases/db-migrations.md) to initialize and change hierarchy via APIs offered by `\\Yiisoft\\Rbac\\ManagerInterface`." -msgstr "" +msgstr "Você pode usar [migrations](../databases/db-migrations.md) para inicializar e alterar a hierarquia via APIs oferecidas por `\\Yiisoft\\Rbac\\ManagerInterface`." #. type: Plain text #: ../src/guide/security/authorization.md msgid "Create new migration using `./yii migrate:create init_rbac` then implement creating a hierarchy:" -msgstr "" +msgstr "Crie uma nova migration com `./yii migrate:create init_rbac` e implemente a criação da hierarquia:" #. type: Fenced code block (php) #: ../src/guide/security/authorization.md @@ -564,6 +725,59 @@ msgid "" " }\n" "}\n" msgstr "" +"manager->addPermission((new Permission(M260112125812InitRbac::CREATE_POST_PERMISSION))->withDescription('Create a post'));\n" +" $this->manager->addPermission((new Permission(M260112125812InitRbac::UPDATE_POST_PERMISSION))->withDescription('Update post'));\n" +"\n" +" // adiciona o papel \"author\" e dá a ele a permissão \"createPost\"\n" +" $this->manager->addRole(new Role(M260112125812InitRbac::ROLE_AUTHOR));\n" +" $this->manager->addChild(M260112125812InitRbac::ROLE_AUTHOR, M260112125812InitRbac::CREATE_POST_PERMISSION);\n" +"\n" +" // adiciona o papel \"admin\" e dá a ele a permissão \"updatePost\"\n" +" // além das permissões do papel \"author\"\n" +" $this->manager->addRole(new Role(M260112125812InitRbac::ROLE_ADMIN));\n" +" $this->manager->addChild(M260112125812InitRbac::ROLE_ADMIN, M260112125812InitRbac::UPDATE_POST_PERMISSION);\n" +" $this->manager->addChild(M260112125812InitRbac::ROLE_ADMIN, M260112125812InitRbac::ROLE_AUTHOR);\n" +"\n" +" // Atribui papéis aos usuários. 1 e 2 são IDs retornados por IdentityInterface::getId(),\n" +" // normalmente implementado no seu model User.\n" +" $this->manager->assign(M260112125812InitRbac::ROLE_AUTHOR, 2);\n" +" $this->manager->assign(M260112125812InitRbac::ROLE_ADMIN, 1);\n" +" }\n" +"\n" +" public function down(MigrationBuilder $b): void\n" +" {\n" +" $this->manager->revokeAll(2);\n" +" $this->manager->revokeAll(1);\n" +"\n" +" $this->manager->removeRole(M260112125812InitRbac::ROLE_ADMIN);\n" +" $this->manager->removeRole(M260112125812InitRbac::ROLE_AUTHOR);\n" +"\n" +" $this->manager->removePermission(M260112125812InitRbac::CREATE_POST_PERMISSION);\n" +" $this->manager->removePermission(M260112125812InitRbac::UPDATE_POST_PERMISSION);\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/security/authorization.md @@ -572,33 +786,35 @@ msgid "" "> If you don't want to hardcode which users have certain roles, don't put `->assign()` calls in migrations. Instead,\n" " create either UI or console command to manage assignments.\n" msgstr "" +"> Se você não quer deixar fixo no código quais usuários têm determinados papéis, não coloque chamadas `->assign()` nas migrations. Em vez disso,\n" +" crie uma interface de usuário ou um comando de console para gerenciar as atribuições.\n" #. type: Plain text #: ../src/guide/security/authorization.md msgid "You could apply migration by using `./yii migrate:up`." -msgstr "" +msgstr "Você pode aplicar a migration com `./yii migrate:up`." #. type: Title ## #: ../src/guide/security/authorization.md #, no-wrap msgid "Assigning roles to users" -msgstr "" +msgstr "Atribuindo papéis a usuários" #. type: Plain text #: ../src/guide/security/authorization.md #, no-wrap msgid "TODO: update when signup implemented in demo / template.\n" -msgstr "" +msgstr "TODO: atualizar quando o cadastro for implementado no demo / template.\n" #. type: Plain text #: ../src/guide/security/authorization.md msgid "The author can create a post, admin can update the post and do everything the author can." -msgstr "" +msgstr "O autor pode criar um post, o admin pode atualizar o post e fazer tudo o que o autor pode." #. type: Plain text #: ../src/guide/security/authorization.md msgid "If your application allows user signup, you need to assign roles to these new users at once. For example, in order for all signed-up users to become authors in your advanced project template, you need to change `frontend\\models\\SignupForm::signup()` as follows:" -msgstr "" +msgstr "Se sua aplicação permite o cadastro de usuários, você precisa atribuir papéis a esses novos usuários imediatamente. Por exemplo, para que todos os usuários cadastrados se tornem autores no seu template de projeto avançado, você precisa alterar `frontend\\models\\SignupForm::signup()` da seguinte forma:" #. type: Fenced code block (php) #: ../src/guide/security/authorization.md @@ -626,22 +842,43 @@ msgid "" " return null;\n" "}\n" msgstr "" +"public function signup()\n" +"{\n" +" if ($this->validate()) {\n" +" $user = new User();\n" +" $user->username = $this->username;\n" +" $user->email = $this->email;\n" +" $user->setPassword($this->password);\n" +" $user->generateAuthKey();\n" +" $user->save(false);\n" +"\n" +" // as três linhas a seguir foram adicionadas:\n" +" $authorRole = $this->manager->getRole('author');\n" +" if ($authorRole !== null) {\n" +" $this->manager->assign($authorRole->getName(), $user->getId());\n" +" }\n" +"\n" +" return $user;\n" +" }\n" +"\n" +" return null;\n" +"}\n" #. type: Plain text #: ../src/guide/security/authorization.md msgid "For applications that require complex access control with dynamically updated authorization data (such as an admin panel), you many need to develop special user interfaces using APIs offered by `Yiisoft\\Rbac\\Manager`." -msgstr "" +msgstr "Para aplicações que exigem controle de acesso complexo com dados de autorização atualizados dinamicamente (como um painel administrativo), talvez você precise desenvolver interfaces de usuário específicas usando as APIs oferecidas por `Yiisoft\\Rbac\\Manager`." #. type: Title ### #: ../src/guide/security/authorization.md #, no-wrap msgid "Using rules" -msgstr "" +msgstr "Usando regras" #. type: Plain text #: ../src/guide/security/authorization.md msgid "As aforementioned, rules add extra constraint to roles and permissions. A rule is a class extending from `\\Yiisoft\\Rbac\\Rule`. It must implement the `execute()` method. In the hierarchy you've created before, the author can't edit his own post. Let's fix it. First, you need a rule to verify that the user is the post author:" -msgstr "" +msgstr "Como mencionado, regras adicionam restrições extras a papéis e permissões. Uma regra é uma classe que estende `\\Yiisoft\\Rbac\\Rule`. Ela deve implementar o método `execute()`. Na hierarquia que você criou antes, o autor não pode editar o próprio post. Vamos corrigir isso. Primeiro, você precisa de uma regra para verificar se o usuário é o autor do post:" #. type: Fenced code block (php) #: ../src/guide/security/authorization.md @@ -665,11 +902,28 @@ msgid "" " }\n" "}\n" msgstr "" +"namespace App\\User\\Rbac;\n" +"\n" +"use Yiisoft\\Rbac\\Item;\n" +"use Yiisoft\\Rbac\\RuleContext;\n" +"use Yiisoft\\Rbac\\RuleInterface;\n" +"\n" +"/**\n" +" * Checks if the authorID matches user passed via params.\n" +" */\n" +"final readonly class AuthorRule implements RuleInterface\n" +"{\n" +" public function execute(?string $userId, Item $item, RuleContext $context): bool\n" +" {\n" +" $post = $context->getParameterValue('post');\n" +" return $post !== null && $post->getAuthorId() == $userId;\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/security/authorization.md msgid "The rule checks if user created the `post`. Create a special permission `updateOwnPost` in the command you've used before:" -msgstr "" +msgstr "A regra verifica se o usuário criou o `post`. Crie uma permissão especial `updateOwnPost` no comando que você usou antes:" #. type: Fenced code block (php) #: ../src/guide/security/authorization.md @@ -693,27 +947,44 @@ msgid "" "// Remove this line since we don't want the AuthorRule to be applied to the 'admin' role\n" "$this->manager->addChild('admin', 'author');\n" msgstr "" +"use Yiisoft\\Rbac\\Permission;\n" +"use Yiisoft\\Rbac\\ManagerInterface;\n" +"\n" +"// adiciona a permissão \"updateOwnPost\" e associa a regra a ela.\n" +"$updateOwnPost = (new Permission('updateOwnPost'))\n" +" ->withDescription('Update own post')\n" +" ->withRuleName(AuthorRule::class);\n" +"$this->manager->addPermission($updateOwnPost);\n" +"\n" +"// \"updateOwnPost\" será usada a partir de \"updatePost\"\n" +"$this->manager->addChild($updateOwnPost->getName(), $updatePost->getName());\n" +"\n" +"// permite que \"author\" atualize os próprios posts\n" +"$this->manager->addChild($authorRole->getName(), $updateOwnPost->getName());\n" +"\n" +"// Remova esta linha, já que não queremos que a AuthorRule seja aplicada ao papel 'admin'\n" +"$this->manager->addChild('admin', 'author');\n" #. type: Plain text #: ../src/guide/security/authorization.md msgid "Now you've got the following hierarchy:" -msgstr "" +msgstr "Agora você tem a seguinte hierarquia:" #. type: Plain text #: ../src/guide/security/authorization.md msgid "![RBAC hierarchy with a rule](/images/guide/security/rbac-hierarchy-2.svg \"RBAC hierarchy with a rule\")" -msgstr "" +msgstr "![Hierarquia RBAC com uma regra](/images/guide/security/rbac-hierarchy-2.svg \"Hierarquia RBAC com uma regra\")" #. type: Title ### #: ../src/guide/security/authorization.md #, no-wrap msgid "Access check" -msgstr "" +msgstr "Verificação de acesso" #. type: Plain text #: ../src/guide/security/authorization.md msgid "The check is done similarly to how it was done in the first section of this guide:" -msgstr "" +msgstr "A verificação é feita de forma semelhante à da primeira seção deste guia:" #. type: Fenced code block (php) #: ../src/guide/security/authorization.md @@ -754,26 +1025,60 @@ msgid "" " }\n" "}\n" msgstr "" +"namespace App\\Blog\\Post;\n" +"\n" +"use Yiisoft\\User\\CurrentUser;\n" +"use Yiisoft\\Router\\HydratorAttribute\\RouteArgument;\n" +"use Psr\\Http\\Message\\ResponseInterface;\n" +"\n" +"final readonly class PostController\n" +"{\n" +" public function __construct(\n" +" private PostRepositoryInterface $postRepository,\n" +" private CurrentUser $user\n" +" )\n" +" {\n" +" }\n" +"\n" +" public function update(#[RouteArgument('id')] int $id): ResponseInterface\n" +" {\n" +" $post = $this->postRepository->findByPK($id);\n" +" if ($post === null) {\n" +" // responda com 404\n" +" }\n" +"\n" +" if (!$this->canCurrentUserUpdatePost($post)) {\n" +" // responda com 403\n" +" }\n" +"\n" +" // continue com a atualização do post\n" +" }\n" +"\n" +" private function canCurrentUserUpdatePost(Post $post): bool\n" +" {\n" +" return $this->user->can('updatePost', ['post' => $post]);\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/security/authorization.md msgid "The difference is that now checking for a user's own post is part of the RBAC." -msgstr "" +msgstr "A diferença é que agora a verificação do próprio post do usuário faz parte do RBAC." #. type: Plain text #: ../src/guide/security/authorization.md msgid "If the current user is Jane with `ID=1` you are starting at `createPost` and trying to get to `Jane`:" -msgstr "" +msgstr "Se o usuário atual for Jane, com `ID=1`, você começa em `createPost` e tenta chegar a `Jane`:" #. type: Plain text #: ../src/guide/security/authorization.md msgid "![Access check](/images/guide/security/rbac-access-check-1.svg \"Access check\")" -msgstr "" +msgstr "![Verificação de acesso](/images/guide/security/rbac-access-check-1.svg \"Verificação de acesso\")" #. type: Plain text #: ../src/guide/security/authorization.md msgid "To check if a user can update a post, you need to pass an extra parameter that's required by `AuthorRule` described before:" -msgstr "" +msgstr "Para verificar se um usuário pode atualizar um post, você precisa passar um parâmetro extra exigido pela `AuthorRule` descrita antes:" #. type: Fenced code block (php) #: ../src/guide/security/authorization.md @@ -783,16 +1088,19 @@ msgid "" " // update post\n" "}\n" msgstr "" +"if ($user->can('updatePost', ['post' => $post])) {\n" +" // atualiza o post\n" +"}\n" #. type: Plain text #: ../src/guide/security/authorization.md msgid "Here is what happens if the current user is John:" -msgstr "" +msgstr "Veja o que acontece se o usuário atual for John:" #. type: Plain text #: ../src/guide/security/authorization.md msgid "![Access check](/images/guide/security/rbac-access-check-2.svg \"Access check\")" -msgstr "" +msgstr "![Verificação de acesso](/images/guide/security/rbac-access-check-2.svg \"Verificação de acesso\")" #. type: Plain text #: ../src/guide/security/authorization.md @@ -803,27 +1111,31 @@ msgid "" "`['post' => $post]`.\n" "If everything is fine, you will get to `author` assigned to John.\n" msgstr "" +"Você começa em `updatePost` e passa por `updateOwnPost`. Para passar na verificação de acesso, a `AuthorRule`\n" +"deve retornar `true` no método `execute()`. O método recebe seus `$params` da chamada do método `can()`, então o valor é\n" +"`['post' => $post]`.\n" +"Se tudo estiver certo, você chega a `author`, atribuído a John.\n" #. type: Plain text #: ../src/guide/security/authorization.md msgid "In the case of Jane, it's a bit simpler since she is an admin:" -msgstr "" +msgstr "No caso de Jane, é um pouco mais simples, já que ela é admin:" #. type: Plain text #: ../src/guide/security/authorization.md msgid "![Access check](/images/guide/security/rbac-access-check-3.svg \"Access check\")" -msgstr "" +msgstr "![Verificação de acesso](/images/guide/security/rbac-access-check-3.svg \"Verificação de acesso\")" #. type: Title ## #: ../src/guide/security/authorization.md #, no-wrap msgid "Implementing your own access checker" -msgstr "" +msgstr "Implementando seu próprio verificador de acesso" #. type: Plain text #: ../src/guide/security/authorization.md msgid "If RBAC doesn't suit your needs, you can implement your own access checker without changing the application code:" -msgstr "" +msgstr "Se o RBAC não atende às suas necessidades, você pode implementar seu próprio verificador de acesso sem alterar o código da aplicação:" #. type: Fenced code block (php) #: ../src/guide/security/authorization.md @@ -852,3 +1164,25 @@ msgid "" " }\n" "}\n" msgstr "" +"namespace App\\User;\n" +"\n" +"use \\Yiisoft\\Access\\AccessCheckerInterface;\n" +"\n" +"final readonly class AccessChecker implements AccessCheckerInterface\n" +"{\n" +" private const PERMISSIONS = [\n" +" [\n" +" 1 => ['editPost'],\n" +" 42 => ['editPost', 'deletePost'],\n" +" ],\n" +" ];\n" +"\n" +" public function userHasPermission($userId, string $permissionName, array $parameters = []) : bool\n" +" {\n" +" if (!array_key_exists($userId, self::PERMISSIONS)) {\n" +" return false;\n" +" }\n" +"\n" +" return in_array($permissionName, self::PERMISSIONS[$userId], true); \n" +" }\n" +"}\n" diff --git a/_translations/po/pt-BR/guide_security_best-practices.md.po b/_translations/po/pt-BR/guide_security_best-practices.md.po index de6fa0c6..2199372c 100644 --- a/_translations/po/pt-BR/guide_security_best-practices.md.po +++ b/_translations/po/pt-BR/guide_security_best-practices.md.po @@ -8,66 +8,61 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-06-29 17:10+0000\n" "PO-Revision-Date: 2026-06-29 17:10+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md -#: ../src/guide/concept/autoloading.md ../src/guide/concept/di-container.md -#: ../src/guide/security/best-practices.md ../src/guide/structure/domain.md -#: ../src/guide/tutorial/console-applications.md -#: ../src/internals/004-namespaces.md ../src/internals/007-exceptions.md -#: ../src/internals/008-interfaces.md +#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md ../src/guide/concept/autoloading.md ../src/guide/concept/di-container.md ../src/guide/security/best-practices.md ../src/guide/structure/domain.md ../src/guide/tutorial/console-applications.md ../src/internals/004-namespaces.md ../src/internals/007-exceptions.md ../src/internals/008-interfaces.md #, no-wrap msgid "References" -msgstr "" +msgstr "Referências" #. type: Title # #: ../src/guide/security/best-practices.md #, no-wrap msgid "Security best practices" -msgstr "" +msgstr "Boas práticas de segurança" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "Below, we'll review common security principles and describe how to avoid threats when developing applications using Yii. Most of these principles aren't unique to Yii alone but apply to website or software development in general, so you will also find links for further reading on the general ideas behind these." -msgstr "" +msgstr "A seguir, vamos revisar princípios comuns de segurança e descrever como evitar ameaças ao desenvolver aplicações com o Yii. A maioria desses princípios não é exclusiva do Yii e vale para o desenvolvimento de sites e software em geral, por isso você também vai encontrar links para leitura adicional sobre as ideias gerais por trás deles." #. type: Title ## #: ../src/guide/security/best-practices.md #, no-wrap msgid "Basic principles" -msgstr "" +msgstr "Princípios básicos" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "There are two main principles when it comes to security no matter which application is being developed:" -msgstr "" +msgstr "Há dois princípios principais quando o assunto é segurança, não importa qual aplicação esteja sendo desenvolvida:" #. type: Bullet: '1. ' #: ../src/guide/security/best-practices.md msgid "Filter input." -msgstr "" +msgstr "Filtre a entrada." #. type: Bullet: '2. ' #: ../src/guide/security/best-practices.md msgid "Escape output." -msgstr "" +msgstr "Escape a saída." #. type: Title ### #: ../src/guide/security/best-practices.md #, no-wrap msgid "Filter input" -msgstr "" +msgstr "Filtre a entrada" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "Filter input means that you should never consider input safe, and you should always check if the value you've got is actually among allowed ones. For example, if you know that you sort by three fields `title`, `created_at` and `status` and the field came from user input, it's better to check the value you've got right where you're receiving it. In terms of basic PHP, that would look like the following:" -msgstr "" +msgstr "Filtrar a entrada significa que você nunca deve considerar uma entrada segura e deve sempre verificar se o valor recebido está de fato entre os permitidos. Por exemplo, se você sabe que a ordenação é feita por três campos, `title`, `created_at` e `status`, e o campo vem da entrada do usuário, é melhor verificar o valor no mesmo lugar em que você o recebe. Em PHP puro, isso ficaria assim:" #. type: Fenced code block (php) #: ../src/guide/security/best-practices.md @@ -78,32 +73,36 @@ msgid "" "\tthrow new \\InvalidArgumentException('Invalid sort value.');\n" "}\n" msgstr "" +"$sortBy = $_GET['sort'];\n" +"if (!in_array($sortBy, ['title', 'created_at', 'status'])) {\n" +"\tthrow new \\InvalidArgumentException('Invalid sort value.');\n" +"}\n" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "In Yii, most probably you'll use form validation to do similar checks." -msgstr "" +msgstr "No Yii, você provavelmente vai usar a validação de formulários para fazer verificações parecidas." #. type: Plain text #: ../src/guide/security/best-practices.md msgid "Further reading on the topic:" -msgstr "" +msgstr "Leitura adicional sobre o assunto:" #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md msgid "" -msgstr "" +msgstr "" #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md msgid "" -msgstr "" +msgstr "" #. type: Title ### #: ../src/guide/security/best-practices.md #, no-wrap msgid "Escape output" -msgstr "" +msgstr "Escape a saída" #. type: Plain text #: ../src/guide/security/best-practices.md @@ -115,32 +114,37 @@ msgid "" "In the context of JavaScript or SQL, it will be a different set of characters.\n" "Since it's error-prone to escape manually, Yii provides various tools to perform escaping in different contexts.\n" msgstr "" +"Escapar a saída significa que, dependendo do contexto em que você usa os dados,\n" +"você deve prefixá-los com caracteres especiais para anular seu significado especial.\n" +"No contexto de HTML, você deve escapar `<`, `>` e caracteres especiais semelhantes.\n" +"No contexto de JavaScript ou SQL, o conjunto de caracteres será outro.\n" +"Como escapar manualmente é propenso a erros, o Yii fornece várias ferramentas para fazer o escape em diferentes contextos.\n" #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md msgid "" -msgstr "" +msgstr "" #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md msgid "" -msgstr "" +msgstr "" #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md msgid "" -msgstr "" +msgstr "" #. type: Title ## #: ../src/guide/security/best-practices.md #, no-wrap msgid "Avoiding SQL injections" -msgstr "" +msgstr "Evitando SQL injection" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "SQL injection happens when you form a query text by concatenating unescaped strings such as the following:" -msgstr "" +msgstr "SQL injection acontece quando você monta o texto de uma consulta concatenando strings não escapadas, como a seguir:" #. type: Fenced code block (php) #: ../src/guide/security/best-practices.md @@ -149,32 +153,34 @@ msgid "" "$username = $_GET['username'];\n" "$sql = \"SELECT * FROM user WHERE username = '$username'\";\n" msgstr "" +"$username = $_GET['username'];\n" +"$sql = \"SELECT * FROM user WHERE username = '$username'\";\n" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "Instead of supplying correct username attacker could give your applications something like `'; DROP TABLE user; --`. The Resulting SQL will be the following:" -msgstr "" +msgstr "Em vez de informar um nome de usuário correto, um atacante pode passar para sua aplicação algo como `'; DROP TABLE user; --`. O SQL resultante será o seguinte:" #. type: Fenced code block (sql) #: ../src/guide/security/best-practices.md #, no-wrap msgid "SELECT * FROM user WHERE username = ''; DROP TABLE user; --'\n" -msgstr "" +msgstr "SELECT * FROM user WHERE username = ''; DROP TABLE user; --'\n" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "This is a valid query that will search for users with empty username and then will drop `user` table most probably resulting in a broken website and data loss (you've set up regular backups, right?)." -msgstr "" +msgstr "Essa é uma consulta válida, que vai buscar usuários com nome de usuário vazio e depois apagar a tabela `user`, o que provavelmente resulta em um site quebrado e perda de dados (você configurou backups regulares, certo?)." #. type: Plain text #: ../src/guide/security/best-practices.md msgid "Make sure to either use PDO prepared statements directly or ensure that the library you prefer is doing it. In the case of prepared statements, it's impossible to manipulate the query as was demonstrated above." -msgstr "" +msgstr "Use prepared statements do PDO diretamente ou garanta que a biblioteca que você prefere faça isso. Com prepared statements, é impossível manipular a consulta como demonstrado acima." #. type: Plain text #: ../src/guide/security/best-practices.md msgid "If you use data to specify column names or table names, the best thing to do is to allow only a predefined set of values:" -msgstr "" +msgstr "Se você usa dados para especificar nomes de colunas ou de tabelas, o melhor é permitir apenas um conjunto predefinido de valores:" #. type: Fenced code block (php) #: ../src/guide/security/best-practices.md @@ -189,17 +195,25 @@ msgid "" " // ...\n" "}\n" msgstr "" +"function actionList($orderBy = null)\n" +"{\n" +" if (!in_array($orderBy, ['name', 'status'])) {\n" +" throw new \\InvalidArgumentException('Only name and status are allowed to order by.');\n" +" }\n" +" \n" +" // ...\n" +"}\n" #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md msgid "" -msgstr "" +msgstr "" #. type: Title ## #: ../src/guide/security/best-practices.md #, no-wrap msgid "Avoiding XSS" -msgstr "" +msgstr "Evitando XSS" #. type: Plain text #: ../src/guide/security/best-practices.md @@ -211,48 +225,53 @@ msgid "" "in a browser. Depending on the website instead of innocent alert, such a script could send messages using your name or even\n" "perform bank transactions.\n" msgstr "" +"XSS, ou cross-site scripting, acontece quando a saída não é escapada corretamente ao enviar HTML para o navegador. Por exemplo,\n" +"se o usuário pode informar o nome dele e, em vez de `Alexander`, ele digita ``, toda página que\n" +"exibe o nome do usuário sem escapá-lo vai executar o JavaScript `alert('Hello!');`, fazendo uma caixa de alerta aparecer\n" +"no navegador. Dependendo do site, em vez de um alerta inofensivo, um script assim poderia enviar mensagens em seu nome ou até\n" +"fazer transações bancárias.\n" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "Avoiding XSS is quite easy in Yii. There are two cases:" -msgstr "" +msgstr "Evitar XSS no Yii é bem fácil. Há dois casos:" #. type: Bullet: '1. ' #: ../src/guide/security/best-practices.md msgid "You want to output data as plain text." -msgstr "" +msgstr "Você quer exibir os dados como texto puro." #. type: Bullet: '2. ' #: ../src/guide/security/best-practices.md msgid "You want to output data as HTML." -msgstr "" +msgstr "Você quer exibir os dados como HTML." #. type: Plain text #: ../src/guide/security/best-practices.md msgid "If all you need is plain text, then escaping is as easy as the following:" -msgstr "" +msgstr "Se tudo o que você precisa é de texto puro, escapar é tão simples quanto o seguinte:" #. type: Fenced code block (php) #: ../src/guide/security/best-practices.md #, no-wrap msgid "\n" -msgstr "" +msgstr "\n" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "If it should be HTML, you could get some help from [HtmlPurifier](http://htmlpurifier.org/). Note that HtmlPurifier processing is quite heavy, so consider adding caching." -msgstr "" +msgstr "Se precisar ser HTML, você pode ter a ajuda do [HtmlPurifier](http://htmlpurifier.org/). Note que o processamento do HtmlPurifier é bem pesado, então considere usar cache." #. type: Title ## #: ../src/guide/security/best-practices.md #, no-wrap msgid "Avoiding CSRF" -msgstr "" +msgstr "Evitando CSRF" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "CSRF is an abbreviation for cross-site request forgery. The idea is that many applications assume that requests coming from a user browser are made by the user themselves. This assumption could be false." -msgstr "" +msgstr "CSRF é a sigla de cross-site request forgery (falsificação de requisição entre sites). A ideia é que muitas aplicações assumem que as requisições vindas do navegador de um usuário são feitas pelo próprio usuário. Essa suposição pode ser falsa." #. type: Plain text #: ../src/guide/security/best-practices.md @@ -264,6 +283,11 @@ msgid "" "requesting an image or requesting a page so when the user opens a page with such a manipulated `` tag,\n" "the browser will send the GET request to that URL and the user will be logged out from `an.example.com`.\n" msgstr "" +"Por exemplo, o site `an.example.com` tem uma URL `/logout` que, quando acessada com uma simples requisição GET, faz o logout do usuário. Enquanto\n" +"for o próprio usuário que faz a requisição, está tudo certo, mas um dia alguém mal-intencionado consegue publicar\n" +"`` em um fórum que o usuário visita com frequência. O navegador não faz diferença entre\n" +"requisitar uma imagem e requisitar uma página, então, quando o usuário abre uma página com essa tag `` manipulada,\n" +"o navegador envia a requisição GET para aquela URL e o usuário é deslogado de `an.example.com`.\n" #. type: Plain text #: ../src/guide/security/best-practices.md @@ -280,47 +304,57 @@ msgid "" "Unfortunately, this won't save you, because an attacker\n" "can put some JavaScript code instead of `` tag, which allows sending POST requests to that URL as well.\n" msgstr "" +"Essa é a ideia básica de como um ataque CSRF funciona. Alguém pode dizer que deslogar um usuário não é grave.\n" +"Porém, isso foi só um exemplo.\n" +"Há muito mais coisas que se pode fazer com essa abordagem.\n" +"Por exemplo, disparar pagamentos ou alterar dados. Imagine que um site tem uma URL\n" +"`http://an.example.com/purse/transfer?to=anotherUser&amount=2000`. Acessá-la com uma requisição GET causa a transferência de $2000\n" +"da conta de um usuário autorizado para o usuário `anotherUser`.\n" +"Você sabe que o navegador sempre envia uma requisição GET para carregar uma imagem,\n" +"então pode alterar o código para aceitar apenas requisições POST nessa URL.\n" +"Infelizmente, isso não vai salvar você, porque um atacante\n" +"pode colocar algum código JavaScript no lugar da tag ``, o que permite enviar requisições POST para essa URL também.\n" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "For this reason, Yii applies extra mechanisms to protect against CSRF attacks." -msgstr "" +msgstr "Por isso, o Yii aplica mecanismos extras para proteger contra ataques CSRF." #. type: Plain text #: ../src/guide/security/best-practices.md msgid "To avoid CSRF, you should always:" -msgstr "" +msgstr "Para evitar CSRF, você deve sempre:" #. type: Bullet: '1. ' #: ../src/guide/security/best-practices.md msgid "Follow HTTP specification. GET shouldn't change the application state. See [RFC2616](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html) for more details." -msgstr "" +msgstr "Seguir a especificação HTTP. GET não deve alterar o estado da aplicação. Veja a [RFC2616](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html) para mais detalhes." #. type: Bullet: '2. ' #: ../src/guide/security/best-practices.md msgid "Keep Yii CSRF protection enabled." -msgstr "" +msgstr "Manter a proteção CSRF do Yii ativada." #. type: Plain text #: ../src/guide/security/best-practices.md msgid "Yii has CSRF protection via `Yiisoft\\Csrf\\CsrfTokenMiddleware` from the [`yiisoft/csrf`](https://github.com/yiisoft/csrf) package. Make sure it's in your application middleware stack. For AJAX/SPA backends that use cookie-based authentication, the same package provides `Yiisoft\\Csrf\\CsrfHeaderMiddleware` — an alternative approach that relies on custom request headers and the CORS preflight mechanism instead of token-in-form." -msgstr "" +msgstr "O Yii tem proteção CSRF via `Yiisoft\\Csrf\\CsrfTokenMiddleware`, do pacote [`yiisoft/csrf`](https://github.com/yiisoft/csrf). Garanta que ele esteja na pilha de middlewares da sua aplicação. Para backends AJAX/SPA que usam autenticação baseada em cookie, o mesmo pacote fornece o `Yiisoft\\Csrf\\CsrfHeaderMiddleware`, uma abordagem alternativa que depende de headers de requisição personalizados e do mecanismo de preflight do CORS em vez de um token no formulário." #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md msgid "" -msgstr "" +msgstr "" #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md msgid "" -msgstr "" +msgstr "" #. type: Title ## #: ../src/guide/security/best-practices.md #, no-wrap msgid "Avoiding file exposure" -msgstr "" +msgstr "Evitando a exposição de arquivos" #. type: Plain text #: ../src/guide/security/best-practices.md @@ -329,138 +363,140 @@ msgid "" "By default, server webroot is meant to be pointed to `public` directory where `index.php` is. In the case of shared hosting\n" " environments, it could be impossible to achieve, so you'll end up with all the code, configs and logs in server webroot.\n" msgstr "" +"Por padrão, o webroot do servidor deve apontar para o diretório `public`, onde fica o `index.php`. Em ambientes de hospedagem\n" +" compartilhada, isso pode ser impossível, e você acaba com todo o código, as configurações e os logs no webroot do servidor.\n" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "If so, remember to deny access to everything except `web`. If it's impossible, consider hosting your application elsewhere." -msgstr "" +msgstr "Nesse caso, lembre-se de negar o acesso a tudo, exceto `web`. Se isso for impossível, considere hospedar sua aplicação em outro lugar." #. type: Title ## #: ../src/guide/security/best-practices.md #, no-wrap msgid "Avoiding debug info and tools in production" -msgstr "" +msgstr "Evitando informações e ferramentas de debug em produção" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "In debug mode, Yii shows quite verbose errors which are certainly helpful for development. The thing is that these verbose errors are handy for attacker as well since these could reveal database structure, configuration values and parts of your code." -msgstr "" +msgstr "No modo debug, o Yii mostra erros bem detalhados, que certamente ajudam no desenvolvimento. O problema é que esses erros detalhados também são úteis para um atacante, já que podem revelar a estrutura do banco de dados, valores de configuração e partes do seu código." #. type: Plain text #: ../src/guide/security/best-practices.md msgid "Never run production applications with debugger or Gii accessible to everyone. One could use it to get information about database structure, code and to simply rewrite code with what's generated by Gii." -msgstr "" +msgstr "Nunca rode aplicações em produção com o debugger ou o Gii acessíveis a todos. Alguém poderia usá-los para obter informações sobre a estrutura do banco de dados e o código, ou simplesmente reescrever o código com o que o Gii gera." #. type: Plain text #: ../src/guide/security/best-practices.md msgid "You should avoid the debug toolbar in production unless necessary. It exposes all the application and config details possible. If you absolutely need it, check twice you restrict access to your IP only." -msgstr "" +msgstr "Evite a barra de debug em produção, a menos que seja necessário. Ela expõe todos os detalhes possíveis da aplicação e da configuração. Se você realmente precisar dela, confira duas vezes se o acesso está restrito apenas ao seu IP." #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md msgid "" -msgstr "" +msgstr "" #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md msgid "" -msgstr "" +msgstr "" #. type: Title ## #: ../src/guide/security/best-practices.md #, no-wrap msgid "Using secure connection over TLS" -msgstr "" +msgstr "Usando conexão segura via TLS" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "Yii provides features that rely on cookies and/or PHP sessions. These can be vulnerable in case your connection is compromised. The risk is reduced if the app uses secure connection via TLS (often referred to as [SSL](https://en.wikipedia.org/wiki/Transport_Layer_Security))." -msgstr "" +msgstr "O Yii fornece recursos que dependem de cookies e/ou sessões do PHP. Eles podem ficar vulneráveis caso sua conexão seja comprometida. O risco diminui se a aplicação usar conexão segura via TLS (muitas vezes chamado de [SSL](https://en.wikipedia.org/wiki/Transport_Layer_Security))." #. type: Plain text #: ../src/guide/security/best-practices.md msgid "Nowadays, anyone can get a certificate for free and automatically update it thanks to [Let's Encrypt](https://letsencrypt.org/)." -msgstr "" +msgstr "Hoje em dia, qualquer pessoa pode obter um certificado de graça e renová-lo automaticamente graças ao [Let's Encrypt](https://letsencrypt.org/)." #. type: Title ## #: ../src/guide/security/best-practices.md #, no-wrap msgid "Secure server configuration" -msgstr "" +msgstr "Configuração segura do servidor" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "The purpose of this section is to highlight risks that need to be considered when creating a server configuration for serving a Yii-based website. Besides the points covered here, there may be other security-related configuration options to be considered, so don't consider this section to be complete." -msgstr "" +msgstr "O objetivo desta seção é destacar os riscos que precisam ser considerados ao criar a configuração de um servidor para servir um site baseado em Yii. Além dos pontos tratados aqui, pode haver outras opções de configuração relacionadas à segurança a considerar, então não considere esta seção completa." #. type: Title ### #: ../src/guide/security/best-practices.md #, no-wrap msgid "Avoiding `Host`-header attacks" -msgstr "" +msgstr "Evitando ataques via header `Host`" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "If the webserver is configured to serve the same site independent of the value of the `Host` header, this information mayn't be reliable and [may be faked by the user sending the HTTP request](https://www.acunetix.com/vulnerabilities/web/host-header-attack). In such situations, you should fix your webserver configuration to serve the site only for specified host names." -msgstr "" +msgstr "Se o servidor web estiver configurado para servir o mesmo site independentemente do valor do header `Host`, essa informação pode não ser confiável e [pode ser falsificada pelo usuário que envia a requisição HTTP](https://www.acunetix.com/vulnerabilities/web/host-header-attack). Nessas situações, você deve corrigir a configuração do servidor web para servir o site apenas para os nomes de host especificados." #. type: Plain text #: ../src/guide/security/best-practices.md msgid "For more information about the server configuration, please refer to the documentation of your webserver:" -msgstr "" +msgstr "Para mais informações sobre a configuração do servidor, consulte a documentação do seu servidor web:" #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md msgid "Apache 2: " -msgstr "" +msgstr "Apache 2: " #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md msgid "Nginx: " -msgstr "" +msgstr "Nginx: " #. type: Title ### #: ../src/guide/security/best-practices.md #, no-wrap msgid "Configuring SSL peer validation" -msgstr "" +msgstr "Configurando a validação SSL do peer" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "There is a typical misconception about how to solve SSL certificate validation issues such as:" -msgstr "" +msgstr "Há um equívoco comum sobre como resolver problemas de validação de certificado SSL, como:" #. type: Fenced code block #: ../src/guide/security/best-practices.md #, no-wrap msgid "cURL error 60: SSL certificate problem: unable to get local issuer certificate\n" -msgstr "" +msgstr "cURL error 60: SSL certificate problem: unable to get local issuer certificate\n" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "or" -msgstr "" +msgstr "ou" #. type: Fenced code block #: ../src/guide/security/best-practices.md #, no-wrap msgid "stream_socket_enable_crypto(): SSL operation failed with code 1. OpenSSL Error messages: error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed\n" -msgstr "" +msgstr "stream_socket_enable_crypto(): SSL operation failed with code 1. OpenSSL Error messages: error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed\n" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "Many sources wrongly suggest disabling SSL peer verification. That shouldn't be ever done since it enables man-in-the middle type of attacks. Instead, PHP should be configured properly:" -msgstr "" +msgstr "Muitas fontes sugerem, erroneamente, desativar a verificação SSL do peer. Isso nunca deve ser feito, porque abre caminho para ataques do tipo man-in-the-middle. Em vez disso, o PHP deve ser configurado corretamente:" #. type: Bullet: '1. ' #: ../src/guide/security/best-practices.md msgid "Download [https://curl.haxx.se/ca/cacert.pem](https://curl.haxx.se/ca/cacert.pem)." -msgstr "" +msgstr "Baixe [https://curl.haxx.se/ca/cacert.pem](https://curl.haxx.se/ca/cacert.pem)." #. type: Bullet: '2. ' #: ../src/guide/security/best-practices.md msgid "Add the following to your php.ini:" -msgstr "" +msgstr "Adicione o seguinte ao seu php.ini:" #. type: Fenced code block #: ../src/guide/security/best-practices.md @@ -469,28 +505,30 @@ msgid "" " openssl.cafile=\"/path/to/cacert.pem\"\n" " curl.cainfo=\"/path/to/cacert.pem\".\n" msgstr "" +" openssl.cafile=\"/path/to/cacert.pem\"\n" +" curl.cainfo=\"/path/to/cacert.pem\".\n" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "Note that you should keep the file up to date." -msgstr "" +msgstr "Note que você deve manter o arquivo atualizado." #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md msgid "[OWASP top 10](https://owasp.org/Top10/)" -msgstr "" +msgstr "[OWASP top 10](https://owasp.org/Top10/)" #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md msgid "[The Basics of Web Application Security](https://martinfowler.com/articles/web-security-basics.html) by Martin Fowler" -msgstr "" +msgstr "[The Basics of Web Application Security](https://martinfowler.com/articles/web-security-basics.html), de Martin Fowler" #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md msgid "[PHP manual: security](https://www.php.net/manual/en/security.php)" -msgstr "" +msgstr "[Manual do PHP: segurança](https://www.php.net/manual/en/security.php)" #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md msgid "[Information security at STackExchange](https://security.stackexchange.com/)" -msgstr "" +msgstr "[Segurança da informação no StackExchange](https://security.stackexchange.com/)" diff --git a/_translations/po/pt-BR/guide_security_cryptography.md.po b/_translations/po/pt-BR/guide_security_cryptography.md.po index 80a9abb0..2feca247 100644 --- a/_translations/po/pt-BR/guide_security_cryptography.md.po +++ b/_translations/po/pt-BR/guide_security_cryptography.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2025-09-04 08:34+0500\n" "PO-Revision-Date: 2025-09-04 08:34+0500\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,91 +19,91 @@ msgstr "" #: en/security/cryptography.md #, no-wrap msgid "Cryptography" -msgstr "" +msgstr "Criptografia" #. type: Plain text #: en/security/cryptography.md msgid "In this section, we'll review the following security aspects:" -msgstr "" +msgstr "Nesta seção, vamos ver os seguintes aspectos de segurança:" #. type: Bullet: '- ' #: en/security/cryptography.md msgid "Generating random data" -msgstr "" +msgstr "Geração de dados aleatórios" #. type: Bullet: '- ' #: en/security/cryptography.md msgid "Encryption and Decryption" -msgstr "" +msgstr "Cifrar e decifrar dados" #. type: Bullet: '- ' #: en/security/cryptography.md msgid "Confirming Data Integrity" -msgstr "" +msgstr "Confirmação da integridade dos dados" #. type: Plain text #: en/security/cryptography.md msgid "To use these features, you need to install `yiisoft/security` package:" -msgstr "" +msgstr "Para usar esses recursos, você precisa instalar o pacote `yiisoft/security`:" #. type: Fenced code block #: en/security/cryptography.md #, no-wrap msgid "composer install yiisoft/security\n" -msgstr "" +msgstr "composer install yiisoft/security\n" #. type: Title ## #: en/security/cryptography.md #, no-wrap msgid "Generating pseudorandom data" -msgstr "" +msgstr "Geração de dados pseudoaleatórios" #. type: Plain text #: en/security/cryptography.md msgid "Pseudorandom data are useful in many situations. For example, when resetting a password via email, you need to generate a token, save it to the database, and send it via email to the end user, which in turn will allow them to prove ownership of that account. It's important that this token be unique and hard to guess, else there is a possibility that an attacker can predict the token's value and reset the user's password." -msgstr "" +msgstr "Dados pseudoaleatórios são úteis em muitas situações. Por exemplo, ao redefinir uma senha por e-mail, você precisa gerar um token, salvá-lo no banco de dados e enviá-lo por e-mail ao usuário final, o que permite a ele provar que é o dono daquela conta. É importante que esse token seja único e difícil de adivinhar; caso contrário, existe a possibilidade de um atacante prever o valor do token e redefinir a senha do usuário." #. type: Plain text #: en/security/cryptography.md msgid "`\\Yiisoft\\Security\\Random` makes generating pseudorandom data simple:" -msgstr "" +msgstr "`\\Yiisoft\\Security\\Random` torna simples gerar dados pseudoaleatórios:" #. type: Fenced code block (php) #: en/security/cryptography.md #, no-wrap msgid "$key = \\Yiisoft\\Security\\Random::string(42);\n" -msgstr "" +msgstr "$key = \\Yiisoft\\Security\\Random::string(42);\n" #. type: Plain text #: en/security/cryptography.md msgid "The code above would give you a random string consisting of 42 characters." -msgstr "" +msgstr "O código acima gera uma string aleatória com 42 caracteres." #. type: Plain text #: en/security/cryptography.md msgid "If you need bytes or integers, use PHP functions directly:" -msgstr "" +msgstr "Se você precisar de bytes ou inteiros, use as funções do PHP diretamente:" #. type: Bullet: '- ' #: en/security/cryptography.md msgid "`random_bytes()` for bytes. Note that the output may not be ASCII." -msgstr "" +msgstr "`random_bytes()` para bytes. Note que a saída pode não ser ASCII." #. type: Bullet: '- ' #: en/security/cryptography.md msgid "`random_int()` for integers." -msgstr "" +msgstr "`random_int()` para inteiros." #. type: Title ## #: en/security/cryptography.md #, no-wrap msgid "Encryption and decryption" -msgstr "" +msgstr "Cifrar e decifrar dados" #. type: Plain text #: en/security/cryptography.md msgid "Yii provides convenient helper functions to encrypt/decrypt data using a secret key. The data is passed through the encryption function so that only the person who has the secret key will be able to decrypt it. For example, you need to store some information in your database, but you need to make sure only the user who has the secret key can view it (even if one compromises the application database):" -msgstr "" +msgstr "O Yii fornece funções auxiliares práticas para cifrar e decifrar dados usando uma chave secreta. Os dados passam pela função de cifragem de modo que apenas quem tem a chave secreta consiga decifrá-los. Por exemplo, você precisa armazenar alguma informação no banco de dados, mas precisa garantir que apenas o usuário que tem a chave secreta possa vê-la (mesmo que alguém comprometa o banco de dados da aplicação):" #. type: Fenced code block (php) #: en/security/cryptography.md @@ -114,11 +114,15 @@ msgid "" "// save data to a database or another storage\n" "saveData($encryptedData);\n" msgstr "" +"$encryptedData = (new \\Yiisoft\\Security\\Crypt())->encryptByPassword($data, $password);\n" +"\n" +"// salve os dados em um banco de dados ou outro armazenamento\n" +"saveData($encryptedData);\n" #. type: Plain text #: en/security/cryptography.md msgid "Decrypting it:" -msgstr "" +msgstr "Para decifrar:" #. type: Fenced code block (php) #: en/security/cryptography.md @@ -129,11 +133,15 @@ msgid "" "\n" "$data = (new \\Yiisoft\\Security\\Crypt())->decryptByPassword($encryptedData, $password);\n" msgstr "" +"// obtenha os dados cifrados de um banco de dados ou outro armazenamento\n" +"$encryptedData = getEncryptedData();\n" +"\n" +"$data = (new \\Yiisoft\\Security\\Crypt())->decryptByPassword($encryptedData, $password);\n" #. type: Plain text #: en/security/cryptography.md msgid "You could use a key instead of a password:" -msgstr "" +msgstr "Você pode usar uma chave em vez de uma senha:" #. type: Fenced code block (php) #: en/security/cryptography.md @@ -144,6 +152,10 @@ msgid "" "// save data to a database or another storage\n" "saveData($encryptedData);\n" msgstr "" +"$encryptedData = (new \\Yiisoft\\Security\\Crypt())->encryptByKey($data, $key);\n" +"\n" +"// salve os dados em um banco de dados ou outro armazenamento\n" +"saveData($encryptedData);\n" #. type: Fenced code block (php) #: en/security/cryptography.md @@ -154,22 +166,26 @@ msgid "" "\n" "$data = (new \\Yiisoft\\Security\\Crypt())->decryptByKey($encryptedData, $key);\n" msgstr "" +"// obtenha os dados cifrados de um banco de dados ou outro armazenamento\n" +"$encryptedData = getEncryptedData();\n" +"\n" +"$data = (new \\Yiisoft\\Security\\Crypt())->decryptByKey($encryptedData, $key);\n" #. type: Title ## #: en/security/cryptography.md #, no-wrap msgid "Confirming data integrity" -msgstr "" +msgstr "Confirmação da integridade dos dados" #. type: Plain text #: en/security/cryptography.md msgid "There are situations in which you need to verify that your data hasn't been tampered with by a third party or even corrupted in some way. Yii provides a way to confirm data integrity by MAC signing." -msgstr "" +msgstr "Há situações em que você precisa verificar se seus dados não foram adulterados por terceiros ou até corrompidos de alguma forma. O Yii oferece uma maneira de confirmar a integridade dos dados por meio de assinatura MAC." #. type: Plain text #: en/security/cryptography.md msgid "The `$key` should be present at both sending and receiving sides. On the sending side:" -msgstr "" +msgstr "A `$key` deve estar presente tanto no lado que envia quanto no que recebe. No lado que envia:" #. type: Fenced code block (php) #: en/security/cryptography.md @@ -179,11 +195,14 @@ msgid "" "\n" "sendMessage($signedMessage);\n" msgstr "" +"$signedMessage = (new \\Yiisoft\\Security\\Mac())->sign($message, $key);\n" +"\n" +"sendMessage($signedMessage);\n" #. type: Plain text #: en/security/cryptography.md msgid "On the receiving side:" -msgstr "" +msgstr "No lado que recebe:" #. type: Fenced code block (php) #: en/security/cryptography.md @@ -197,36 +216,43 @@ msgid "" " // data is tampered\n" "}\n" msgstr "" +"$signedMessage = receiveMessage($signedMessage);\n" +"\n" +"try {\n" +" $message = (new \\Yiisoft\\Security\\Mac())->getMessage($signedMessage, $key);\n" +"} catch (\\Yiisoft\\Security\\DataIsTamperedException $e) {\n" +" // os dados foram adulterados\n" +"}\n" #. type: Title ## #: en/security/cryptography.md #, no-wrap msgid "Masking token length" -msgstr "" +msgstr "Mascaramento do comprimento do token" #. type: Plain text #: en/security/cryptography.md msgid "Masking a token helps to mitigate a BREACH attack by randomizing how the token outputted on each request. A random mask is applied to the token, making the string always unique." -msgstr "" +msgstr "Mascarar um token ajuda a mitigar um ataque BREACH, tornando aleatória a forma como o token é exibido em cada requisição. Uma máscara aleatória é aplicada ao token, fazendo com que a string seja sempre única." #. type: Plain text #: en/security/cryptography.md msgid "To mask a token:" -msgstr "" +msgstr "Para mascarar um token:" #. type: Fenced code block (php) #: en/security/cryptography.md #, no-wrap msgid "$maskedToken = \\Yiisoft\\Security\\TokenMask::apply($token);\n" -msgstr "" +msgstr "$maskedToken = \\Yiisoft\\Security\\TokenMask::apply($token);\n" #. type: Plain text #: en/security/cryptography.md msgid "To get the original value from the masked one:" -msgstr "" +msgstr "Para obter o valor original a partir do mascarado:" #. type: Fenced code block (php) #: en/security/cryptography.md #, no-wrap msgid "$token = \\Yiisoft\\Security\\TokenMask::remove($maskedToken);\n" -msgstr "" +msgstr "$token = \\Yiisoft\\Security\\TokenMask::remove($maskedToken);\n" diff --git a/_translations/po/pt-BR/guide_security_overview.md.po b/_translations/po/pt-BR/guide_security_overview.md.po index c62e4ef3..a26c7f2e 100644 --- a/_translations/po/pt-BR/guide_security_overview.md.po +++ b/_translations/po/pt-BR/guide_security_overview.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2025-09-04 11:19+0500\n" "PO-Revision-Date: 2025-09-04 11:19+0500\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -24,44 +24,44 @@ msgstr "Segurança" #. type: Plain text #: en/security/overview.md msgid "Good security is vital to the health and success of any application. Unfortunately, many developers cut corners when it comes to security, either due to a lack of understanding or because implementation is too much of a hurdle. To make your Yii-powered application as secure as possible, Yii has included several excellent and easy-to-use security features." -msgstr "" +msgstr "Uma boa segurança é vital para a saúde e o sucesso de qualquer aplicação. Infelizmente, muitos desenvolvedores negligenciam a segurança, seja por falta de entendimento, seja porque a implementação parece um obstáculo grande demais. Para deixar sua aplicação Yii o mais segura possível, o Yii inclui vários recursos de segurança excelentes e fáceis de usar." #. type: Bullet: '* ' #: en/security/overview.md msgid "[Authentication](authentication.md)" -msgstr "" +msgstr "[Autenticação](authentication.md)" #. type: Bullet: '* ' #: en/security/overview.md msgid "[Authorization](authorization.md)" -msgstr "" +msgstr "[Autorização](authorization.md)" #. type: Bullet: '* ' #: en/security/overview.md msgid "[Working with Passwords](passwords.md)" -msgstr "" +msgstr "[Trabalhando com senhas](passwords.md)" #. type: Bullet: '* ' #: en/security/overview.md msgid "[Cryptography](cryptography.md)" -msgstr "" +msgstr "[Criptografia](cryptography.md)" #. type: Bullet: '* ' #: en/security/overview.md msgid "[Best Practices](best-practices.md)" -msgstr "" +msgstr "[Boas práticas](best-practices.md)" #. type: Bullet: '* ' #: en/security/overview.md msgid "[Trusted request](trusted-request.md)" -msgstr "" +msgstr "[Requisição confiável](trusted-request.md)" #. type: Plain text #: en/security/overview.md msgid "See also:" -msgstr "" +msgstr "Veja também:" #. type: Bullet: '* ' #: en/security/overview.md msgid "[Views security](../views/view.md#security)" -msgstr "" +msgstr "[Segurança de views](../views/view.md#security)" diff --git a/_translations/po/pt-BR/guide_security_passwords.md.po b/_translations/po/pt-BR/guide_security_passwords.md.po index a58513b1..28100c94 100644 --- a/_translations/po/pt-BR/guide_security_passwords.md.po +++ b/_translations/po/pt-BR/guide_security_passwords.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2025-09-04 11:19+0500\n" "PO-Revision-Date: 2025-09-04 11:19+0500\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,33 +19,33 @@ msgstr "" #: en/security/passwords.md #, no-wrap msgid "Working with passwords" -msgstr "" +msgstr "Trabalhando com senhas" #. type: Plain text #: en/security/passwords.md msgid "Most developers know that passwords can't be stored in plain text, but many developers believe it's still safe to hash passwords using `md5`, `sha1` or `sha256` etc. There was a time when using the aforementioned hashing algorithms was enough, but modern hardware makes it possible to reverse such hashes and even stronger ones using brute force attacks." -msgstr "" +msgstr "A maioria dos desenvolvedores sabe que senhas não podem ser armazenadas em texto puro, mas muitos ainda acreditam que é seguro gerar o hash de senhas com `md5`, `sha1`, `sha256` etc. Houve um tempo em que esses algoritmos de hash bastavam, mas o hardware moderno permite reverter esses hashes, e até outros mais fortes, com ataques de força bruta." #. type: Plain text #: en/security/passwords.md msgid "To offer increased security for user passwords, even in the worst case scenario (when one breaches your application), you need to use a hashing algorithm that's resilient against brute force attacks. The best current choice is `argon2`. Yii `yiisoft/security` package make securely generate and verify hashes easier and ensure the best possible hashing solution used." -msgstr "" +msgstr "Para oferecer mais segurança às senhas dos usuários, mesmo no pior cenário (quando alguém invade sua aplicação), você precisa usar um algoritmo de hash resistente a ataques de força bruta. A melhor escolha atual é o `argon2`. O pacote `yiisoft/security` do Yii facilita gerar e verificar hashes com segurança e garante que a melhor solução de hash possível seja usada." #. type: Plain text #: en/security/passwords.md msgid "To use it, you need to require the package first:" -msgstr "" +msgstr "Para usá-lo, primeiro instale o pacote:" #. type: Fenced code block #: en/security/passwords.md #, no-wrap msgid "composer require yiisoft/security\n" -msgstr "" +msgstr "composer require yiisoft/security\n" #. type: Plain text #: en/security/passwords.md msgid "When a user provides a password for the first time (e.g., upon registration), the password needs to be hashed and stored:" -msgstr "" +msgstr "Quando um usuário fornece uma senha pela primeira vez (por exemplo, no cadastro), é preciso gerar o hash da senha e armazená-lo:" #. type: Fenced code block (php) #: en/security/passwords.md @@ -56,11 +56,15 @@ msgid "" "// save hash to a database or another storage\n" "saveHash($hash); \n" msgstr "" +"$hash = (new PasswordHasher())->hash($password);\n" +"\n" +"// salve o hash em um banco de dados ou outro armazenamento\n" +"saveHash($hash); \n" #. type: Plain text #: en/security/passwords.md msgid "When a user attempts to log in, the submitted password must be verified against the previously hashed and stored password:" -msgstr "" +msgstr "Quando um usuário tenta fazer login, a senha enviada deve ser verificada contra o hash armazenado anteriormente:" #. type: Fenced code block (php) #: en/security/passwords.md @@ -75,3 +79,11 @@ msgid "" " // wrong password\n" "}\n" msgstr "" +"// obtenha o hash de um banco de dados ou outro armazenamento\n" +"$hash = getHash();\n" +"\n" +"if ((new PasswordHasher())->validate($password, $hash)) {\n" +" // tudo certo, fazendo login do usuário\n" +"} else {\n" +" // senha incorreta\n" +"}\n" diff --git a/_translations/po/pt-BR/guide_security_trusted-request.md.po b/_translations/po/pt-BR/guide_security_trusted-request.md.po index ab27eb83..0d8feb00 100644 --- a/_translations/po/pt-BR/guide_security_trusted-request.md.po +++ b/_translations/po/pt-BR/guide_security_trusted-request.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2025-09-04 11:19+0500\n" "PO-Revision-Date: 2025-09-04 11:19+0500\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,22 +19,22 @@ msgstr "" #: en/security/trusted-request.md #, no-wrap msgid "Trusted request" -msgstr "" +msgstr "Requisição confiável" #. type: Plain text #: en/security/trusted-request.md msgid "Getting user information, like a host and IP address, will work out of the box in a normal setup where a single webserver is used to serve the website. If your Yii application, however, runs behind a reverse proxy, you need to add configuration to retrieve this information as the direct client is now the proxy, and the user IP address is passed to the Yii application by a header set by the proxy." -msgstr "" +msgstr "Obter informações do usuário, como host e endereço IP, funciona de imediato em uma configuração normal, em que um único servidor web atende o site. Porém, se sua aplicação Yii roda atrás de um proxy reverso, você precisa adicionar configuração para obter essas informações, já que o cliente direto passa a ser o proxy e o endereço IP do usuário é repassado para a aplicação Yii por um header definido pelo proxy." #. type: Plain text #: en/security/trusted-request.md msgid "You shouldn't blindly trust headers provided by proxies unless you explicitly trust the proxy. Yii supports configuring trusted proxies via the `Yiisoft\\Yii\\Web\\Middleware\\TrustedHostsNetworkResolver`. You should add it to [middleware stack](../structure/middleware.md)." -msgstr "" +msgstr "Você não deve confiar cegamente nos headers fornecidos por proxies, a menos que confie explicitamente no proxy. O Yii permite configurar proxies confiáveis via `Yiisoft\\Yii\\Web\\Middleware\\TrustedHostsNetworkResolver`. Você deve adicioná-lo à [pilha de middlewares](../structure/middleware.md)." #. type: Plain text #: en/security/trusted-request.md msgid "The following is a request config for an application that runs behind an array of reverse proxies, which are located in the `10.0.2.0/24` IP network:" -msgstr "" +msgstr "A seguir está uma configuração de requisição para uma aplicação que roda atrás de um conjunto de proxies reversos localizados na rede IP `10.0.2.0/24`:" #. type: Fenced code block (php) #: en/security/trusted-request.md @@ -43,16 +43,18 @@ msgid "" "/** @var \\Yiisoft\\Yii\\Web\\Middleware\\TrustedHostsNetworkResolver $trustedHostsNetworkResolver */\n" "$trustedHostsNetworkResolver = $trustedHostsNetworkResolver->withAddedTrustedHosts(['1.0.2.0/24']);\n" msgstr "" +"/** @var \\Yiisoft\\Yii\\Web\\Middleware\\TrustedHostsNetworkResolver $trustedHostsNetworkResolver */\n" +"$trustedHostsNetworkResolver = $trustedHostsNetworkResolver->withAddedTrustedHosts(['1.0.2.0/24']);\n" #. type: Plain text #: en/security/trusted-request.md msgid "The proxy sends the IP in the `X-Forwarded-For` header by default, and the protocol (`http` or `https`) is in `X-Forwarded-Proto`." -msgstr "" +msgstr "Por padrão, o proxy envia o IP no header `X-Forwarded-For` e o protocolo (`http` ou `https`) em `X-Forwarded-Proto`." #. type: Plain text #: en/security/trusted-request.md msgid "In case your proxies are using different headers, you can use the request configuration to adjust these, e.g.:" -msgstr "" +msgstr "Caso seus proxies usem headers diferentes, você pode ajustá-los na configuração da requisição, por exemplo:" #. type: Fenced code block (php) #: en/security/trusted-request.md @@ -69,8 +71,18 @@ msgid "" " ['X-Proxy-User-Ip']\n" " );\n" msgstr "" +"/** @var \\Yiisoft\\Yii\\Web\\Middleware\\TrustedHostsNetworkResolver $trustedHostsNetworkResolver */\n" +"$trustedHostsNetworkResolver = $trustedHostsNetworkResolver\n" +" ->withAddedTrustedHosts(\n" +" ['1.0.2.0/24'],\n" +" ['X-ProxyUser-Ip'],\n" +" ['Front-End-Https'],\n" +" [],\n" +" [],\n" +" ['X-Proxy-User-Ip']\n" +" );\n" #. type: Plain text #: en/security/trusted-request.md msgid "With the above configuration, `X-ProxyUser-Ip` and `Front-End-Https` headers are used to get user IP and protocol." -msgstr "" +msgstr "Com a configuração acima, os headers `X-ProxyUser-Ip` e `Front-End-Https` são usados para obter o IP e o protocolo do usuário." diff --git a/src/pt-BR/guide/caching/data.md b/src/pt-BR/guide/caching/data.md index 0b7d1a62..1e69b953 100644 --- a/src/pt-BR/guide/caching/data.md +++ b/src/pt-BR/guide/caching/data.md @@ -1,27 +1,27 @@ -# Data caching +# Cache de dados -Data caching is about storing some PHP variables in a cache and retrieving -them later from the cache. It's also the foundation for more advanced -caching features, such as [page caching](page.md). +O cache de dados consiste em guardar algumas variáveis PHP no cache e +recuperá-las dele mais tarde. Ele também é a base para recursos de cache +mais avançados, como o [cache de páginas](page.md). -To use cache, install [yiisoft/cache](https://github.com/yiisoft/cache) -package: +Para usar o cache, instale o pacote +[yiisoft/cache](https://github.com/yiisoft/cache): ```shell composer require yiisoft/cache ``` -The following code is a typical usage pattern of data caching, where -`$cache` refers to a `Cache` instance from the package: +O código a seguir é um padrão típico de uso do cache de dados, em que +`$cache` se refere a uma instância de `Cache` do pacote: ```php public function getTopProducts(\Yiisoft\Cache\CacheInterface $cache): array { $key = ['top-products', $count = 10]; - // Try retrieving $data from cache. + // Tenta recuperar $data do cache. $data = $cache->getOrSet($key, function (\Psr\SimpleCache\CacheInterface $cache) use ($count) { - // Can't find $data in a cache, calculate it from scratch. + // $data não está no cache, então calcula do zero. return getTopProductsFromDatabase($count); }, 3600); @@ -29,92 +29,93 @@ public function getTopProducts(\Yiisoft\Cache\CacheInterface $cache): array } ``` -When cache has data associated with the `$key`, it returns the cached -value. Otherwise, it executes the passed anonymous function to calculate -the value to cache and return. - -If the anonymous function requires some data from the outer scope, you can -pass it with the `use` statement. - -## Cache handlers - -The cache service uses [PSR-16](https://www.php-fig.org/psr/psr-16/) -compatible cache handlers which represent various cache storages, such as -memory, files, and databases. - -Yii provides the following handlers: - -- `NullCache` — a cache placeholder which does no real caching. The purpose - of this handler is to simplify the code that needs to check the - availability of cache. For example, during development or if the server - doesn't have actual cache support, you may configure a cache service to - use this handler. When you enable actual cache support, you can switch to - using the corresponding cache handler. In both cases, you may use the - same code without extra checks. -- `ArrayCache` — provides caching for the current request only by storing - the values in an array. -- [APCu](https://github.com/yiisoft/cache-apcu) - uses a PHP - [APC](https://secure.php.net/manual/en/book.apc.php) extension. You can - consider this option as the fastest one when dealing with cache for a - centralized thick application (e.g., one server, no dedicated load - balancers, etc.). -- [Database](https://github.com/yiisoft/cache-db) — uses a database table to - store cached data. -- [File](https://github.com/yiisoft/cache-file) — uses standard files to - store cached data. This is particularly suitable to cache large chunks of - data, such as page content. -- [Memcached](https://github.com/yiisoft/cache-memcached) — uses a PHP - [memcached](https://secure.php.net/manual/en/book.memcached.php) - extension. You can consider this option as the fastest one when dealing - with cache in a distributed application - (e.g., with several servers, load balancers, etc.) -- [Wincache](https://github.com/yiisoft/cache-wincache) — uses PHP [WinCache](https://iis.net/downloads/microsoft/wincache-extension) - ([see also](https://secure.php.net/manual/en/book.wincache.php)) extension. - -[You could find more handlers at +Quando o cache tem dados associados à `$key`, ele retorna o valor em cache. +Caso contrário, executa a função anônima passada para calcular o valor a ser +guardado no cache e retornado. + +Se a função anônima precisar de dados do escopo externo, você pode passá-los +com a instrução `use`. + +## Drivers de cache + +O serviço de cache usa drivers de cache compatíveis com a +[PSR-16](https://www.php-fig.org/psr/psr-16/), que representam vários tipos +de armazenamento, como memória, arquivos e bancos de dados. + +O Yii fornece os seguintes drivers: + +- `NullCache` — um substituto de cache que não faz cache de verdade. O + objetivo desse driver é simplificar o código que precisa verificar se há + cache disponível. Por exemplo, durante o desenvolvimento ou se o servidor + não tiver suporte real a cache, você pode configurar o serviço de cache + para usar esse driver. Quando você habilitar o suporte real a cache, pode + trocar para o driver correspondente. Nos dois casos, você pode usar o + mesmo código, sem verificações extras. +- `ArrayCache` — faz cache apenas durante a requisição atual, guardando os + valores em um array. +- [APCu](https://github.com/yiisoft/cache-apcu) - usa a extensão + [APC](https://secure.php.net/manual/en/book.apc.php) do PHP. Você pode + considerar esta a opção mais rápida ao lidar com cache em uma aplicação + centralizada e robusta (por exemplo, um servidor, sem load balancers + dedicados etc.). +- [Banco de dados](https://github.com/yiisoft/cache-db) — usa uma tabela do + banco de dados para guardar os dados em cache. +- [Arquivo](https://github.com/yiisoft/cache-file) — usa arquivos comuns + para guardar os dados em cache. É especialmente adequado para guardar + grandes blocos de dados, como o conteúdo de páginas. +- [Memcached](https://github.com/yiisoft/cache-memcached) — usa a extensão + [memcached](https://secure.php.net/manual/en/book.memcached.php) do + PHP. Você pode considerar esta a opção mais rápida ao lidar com cache em + uma aplicação distribuída + (por exemplo, com vários servidores, load balancers etc.) +- [Wincache](https://github.com/yiisoft/cache-wincache) — usa a extensão [WinCache](https://iis.net/downloads/microsoft/wincache-extension) + ([veja também](https://secure.php.net/manual/en/book.wincache.php)) do PHP. + +[Você encontra mais drivers no packagist.org](https://packagist.org/providers/psr/simple-cache-implementation). > [!TIP] -> You may use different cache storage in the same application. A common strategy is: -> - To use memory-based cache storage to store small but constantly used data (e.g., statistics) -> - To use file-based or database-based cache storage to store big and less often used data (e.g., page content) +> Você pode usar armazenamentos de cache diferentes na mesma aplicação. Uma estratégia comum é: +> - Usar armazenamento de cache em memória para dados pequenos, mas usados constantemente (por exemplo, estatísticas) +> - Usar armazenamento de cache em arquivo ou em banco de dados para dados grandes e usados com menos frequência (por exemplo, conteúdo de páginas) -Cache handlers are usually set up in a [dependency injection -container](../concept/di-container.md) so that they can be globally -configurable and accessible. +Os drivers de cache normalmente são configurados em um [container de injeção +de dependência](../concept/di-container.md), para que possam ser +configurados e acessados globalmente. -Because all cache handlers support the same set of APIs, you can swap the -underlying cache handler with a different one. You can do it by -reconfiguring the application without modifying the code that uses the -cache. +Como todos os drivers de cache suportam o mesmo conjunto de APIs, você pode +trocar o driver de cache subjacente por outro. Basta reconfigurar a +aplicação, sem modificar o código que usa o cache. -### Cache keys +### Chaves de cache -A key uniquely identifies each data item stored in the cache. When you store -a data item, you have to specify a key for it. Later, when you retrieve the -data item, you should give the corresponding key. +Uma chave identifica de forma única cada item de dados guardado no cache. Ao +guardar um item, você precisa especificar uma chave para ele. Depois, ao +recuperar o item, você deve informar a chave correspondente. -You may use a string or an arbitrary value as a cache key. When a key isn't -a string, it will be automatically serialized into a string. +Você pode usar uma string ou um valor arbitrário como chave de cache. Quando +a chave não é uma string, ela é serializada automaticamente em uma string. -A common strategy of defining a cache key is to include all determining -factors in terms of an array. +Uma estratégia comum para definir uma chave de cache é incluir todos os +fatores determinantes em um array. -When different applications use the same cache storage, you should specify a -unique cache key prefix for each application to avoid conflicts of cache -keys. You can do this by using `\Yiisoft\Cache\PrefixedCache` decorator: +Quando aplicações diferentes usam o mesmo armazenamento de cache, você deve +especificar um prefixo de chave de cache único para cada aplicação, para +evitar conflitos de chaves. Você pode fazer isso usando o decorator +`\Yiisoft\Cache\PrefixedCache`: ```php $arrayCacheWithPrefix = new \Yiisoft\Cache\PrefixedCache(new \Yiisoft\Cache\ArrayCache(), 'myapp_'); $cache = new \Yiisoft\Cache\Cache($arrayCacheWithPrefix); ``` -### Cache expiration +### Expiração do cache -A data item stored in a cache will remain there forever unless it's removed -because of some caching policy enforcement. For example, caching space is -full and cache storage removes the oldest data. To change this behavior, -you can set a TTL parameter when calling a method to store a data item: +Um item de dados guardado no cache fica lá para sempre, a menos que seja +removido por alguma política de cache. Por exemplo, o espaço do cache fica +cheio e o armazenamento remove os dados mais antigos. Para mudar esse +comportamento, você pode definir um parâmetro TTL ao chamar um método que +guarda um item: ```php $ttl = 3600; @@ -123,35 +124,34 @@ return getTopProductsFromDatabase($count); }, $ttl); ``` -The `$ttl` parameter indicates for how many seconds the data item can remain -valid in the cache. When you retrieve the data item, if it has passed the -expiration time, the method will execute the function and set the resulting -value into cache. +O parâmetro `$ttl` indica por quantos segundos o item pode continuar válido +no cache. Ao recuperar o item, se o tempo de expiração já tiver passado, o +método executa a função e grava o valor resultante no cache. -You may set the default TTL for the cache: +Você pode definir o TTL padrão do cache: ```php -$cache = new \Yiisoft\Cache\Cache($arrayCache, 60 * 60); // 1 hour +$cache = new \Yiisoft\Cache\Cache($arrayCache, 60 * 60); // 1 hora ``` -Additionally, you can invalidate a cache key explicitly: +Além disso, você pode invalidar uma chave de cache explicitamente: ```php $cache->remove($key); ``` -### Invalidation dependencies +### Dependências de invalidação -Besides the expiration setting, changes of the so-called **invalidation -dependencies** may also invalidate cached data item. For example, -`\Yiisoft\Cache\Dependency\FileDependency` represents the dependency of a -file's modification time. When this dependency changes, it means something -modifying the corresponding file. As a result, any outdated file content -found in the cache should invalidate. +Além da configuração de expiração, mudanças nas chamadas **dependências de +invalidação** também podem invalidar um item em cache. Por exemplo, +`\Yiisoft\Cache\Dependency\FileDependency` representa a dependência da data +de modificação de um arquivo. Quando essa dependência muda, significa que +algo modificou o arquivo correspondente. Como resultado, qualquer conteúdo +desatualizado do arquivo encontrado no cache deve ser invalidado. -Cache dependencies are objects of `\Yiisoft\Cache\Dependency\Dependency` -descendant classes. When you store a data item in the cache, you can pass -along an associated cache dependency object. For example, +As dependências de cache são objetos de classes descendentes de +`\Yiisoft\Cache\Dependency\Dependency`. Ao guardar um item no cache, você +pode passar junto um objeto de dependência de cache associado. Por exemplo, ```php /** @@ -161,46 +161,48 @@ along an associated cache dependency object. For example, use Yiisoft\Cache\Dependency\TagDependency; -// Set many cache values marking both with a tag. +// Grava vários valores no cache, marcando ambos com uma tag. $cache->getOrSet('item_42_price', $callable, null, new TagDependency('item_42')); $cache->getOrSet('item_42_total', $callable, 3600, new TagDependency('item_42')); -// Trigger invalidation by tag. +// Dispara a invalidação pela tag. TagDependency::invalidate($cache, 'item_42'); ``` -Below is a summary of the available cache dependencies: +Veja um resumo das dependências de cache disponíveis: -- `\Yiisoft\Cache\Dependency\ValueDependency`: invalidates the cache when - specified value changes. -- `\Yiisoft\Cache\Dependency\CallbackDependency`: invalidates the cache when - the result of the specified PHP callback is different. -- `\Yiisoft\Cache\Dependency\FileDependency`: invalidates the cache when the - file's last modification time is different. -- `\Yiisoft\Cache\Dependency\TagDependency`: associates a cached data item - with one or many tags. You may invalidate the cached data items with the - specified tag(s) by calling `TagDependency::invalidate()`. +- `\Yiisoft\Cache\Dependency\ValueDependency`: invalida o cache quando o + valor especificado muda. +- `\Yiisoft\Cache\Dependency\CallbackDependency`: invalida o cache quando o + resultado do callback PHP especificado é diferente. +- `\Yiisoft\Cache\Dependency\FileDependency`: invalida o cache quando a data + da última modificação do arquivo é diferente. +- `\Yiisoft\Cache\Dependency\TagDependency`: associa um item em cache a uma + ou várias tags. Você pode invalidar os itens em cache com as tags + especificadas chamando `TagDependency::invalidate()`. -You may combine many dependencies using -`\Yiisoft\Cache\Dependency\AnyDependency` or +Você pode combinar várias dependências usando +`\Yiisoft\Cache\Dependency\AnyDependency` ou `\Yiisoft\Cache\Dependency\AllDependencies`. -To implement your own dependency, extend from +Para implementar a sua própria dependência, estenda `\Yiisoft\Cache\Dependency\Dependency`. -### Cache stampede prevention - -[A cache stampede](https://en.wikipedia.org/wiki/Cache_stampede) is a type -of cascading failure that can occur when massively parallel computing -systems with caching mechanisms come under a high load. This behavior is -sometimes also called dog-piling. - -The `\Yiisoft\Cache\Cache` uses a built-in "Probably early expiration" -algorithm that prevents cache stampede. This algorithm randomly fakes a -cache miss for one user while others are still served the cached value. You -can control its behavior with the fifth optional parameter of `getOrSet()`, -which is a float value called `$beta`. By default, beta is `1.0`, which is -usually enough. The higher the value, the earlier cache will be re-created. +### Prevenção do efeito manada + +O [efeito manada (cache +stampede)](https://en.wikipedia.org/wiki/Cache_stampede) é um tipo de falha +em cascata que pode ocorrer quando sistemas de computação massivamente +paralelos com mecanismos de cache ficam sob carga alta. Esse comportamento +às vezes também é chamado de dog-piling. + +O `\Yiisoft\Cache\Cache` usa um algoritmo embutido de "expiração antecipada +probabilística" ("Probably early expiration") que evita o efeito manada. +Esse algoritmo simula aleatoriamente um cache miss para um usuário enquanto +os outros continuam recebendo o valor em cache. Você pode controlar o +comportamento dele com o quinto parâmetro opcional de `getOrSet()`, um valor +float chamado `$beta`. Por padrão, beta é `1.0`, o que costuma ser +suficiente. Quanto maior o valor, mais cedo o cache será recriado. ```php /** diff --git a/src/pt-BR/guide/caching/overview.md b/src/pt-BR/guide/caching/overview.md index 1f9b8ccc..e2772151 100644 --- a/src/pt-BR/guide/caching/overview.md +++ b/src/pt-BR/guide/caching/overview.md @@ -1,21 +1,22 @@ # Cache -Caching is an inexpensive and effective way to improve the performance of an -application. By storing relatively static data in cache and serving it from -cache when requested, the application saves the time that it otherwise would -require to generate the data from scratch every time. +O cache é uma forma barata e eficaz de melhorar o desempenho de uma +aplicação. Ao armazenar dados relativamente estáticos no cache e servi-los +a partir dele quando solicitados, a aplicação economiza o tempo que, de +outra forma, precisaria para gerar os dados do zero a cada vez. -Caching can occur at different levels and places in an application. On the -server-side, at the lower level, cache may be used to store basic data, such -as a list of most recent article information fetched from the database; and -at the higher level, cache may be used to store fragments or whole of Web -pages, such as the rendering result of the most recent articles. On the -client-side, you may use HTTP caching to keep most recently visited page -content in the browser cache. +O cache pode ocorrer em diferentes níveis e lugares de uma aplicação. No +lado do servidor, no nível mais baixo, o cache pode ser usado para armazenar +dados básicos, como uma lista com as informações dos artigos mais recentes +obtida do banco de dados; e, no nível mais alto, o cache pode ser usado para +armazenar fragmentos ou páginas web inteiras, como o resultado da +renderização dos artigos mais recentes. No lado do cliente, você pode usar o +cache HTTP para manter o conteúdo das páginas visitadas mais recentemente no +cache do navegador. -Yii supports all these caching mechanisms: +O Yii suporta todos estes mecanismos de cache: -* [Data caching](data.md) -* [Fragment caching](fragment.md) -* [Page caching](page.md) -* [HTTP caching](http.md) +* [Cache de dados](data.md) +* [Cache de fragmentos](fragment.md) +* [Cache de páginas](page.md) +* [Cache HTTP](http.md) diff --git a/src/pt-BR/guide/databases/db-migrations.md b/src/pt-BR/guide/databases/db-migrations.md index c5751ce0..f19015fe 100644 --- a/src/pt-BR/guide/databases/db-migrations.md +++ b/src/pt-BR/guide/databases/db-migrations.md @@ -1,95 +1,96 @@ # Migrations -During the course of developing and maintaining a database-driven -application, the structure of the database being used evolves just like the -source code does. For example, during the development of an application, a -new table may be found necessary; after the application is deployed to -production, it may be discovered that an index should be created to improve -the query performance; and so on. Because a database structure change often -requires some source code changes, Yii supports the so-called *database -migration* feature that allows you to keep track of database changes in -terms of *database migrations* which are version-controlled together with -the source code. - -The following steps show how database migration can be used by a team during -development: - -1. Tim creates a new migration (e.g. creates a new table, changes a column - definition, etc.). -2. Tim commits the new migration into the source control system (e.g. Git, - Mercurial). -3. Doug updates his repository from the source control system and receives - the new migration. -4. Doug applies the migration to his local development database, thereby - synchronizing his database to reflect the changes that Tim has made. - -And the following steps show how to deploy a new release with database -migrations to production: - -1. Scott creates a release tag for the project repository that contains some - new database migrations. -2. Scott updates the source code on the production server to the release - tag. -3. Scott applies any accumulated database migrations to the production - database. +Ao longo do desenvolvimento e da manutenção de uma aplicação que usa banco +de dados, a estrutura do banco evolui assim como o código-fonte. Por +exemplo, durante o desenvolvimento de uma aplicação, pode surgir a +necessidade de uma nova tabela; depois que a aplicação vai para produção, +pode-se descobrir que é preciso criar um índice para melhorar o desempenho +de uma consulta; e assim por diante. Como uma mudança na estrutura do banco +de dados muitas vezes exige mudanças no código-fonte, o Yii oferece o +recurso chamado *migration de banco de dados*, que permite acompanhar as +mudanças no banco em forma de *migrations*, versionadas junto com o +código-fonte. + +Os passos a seguir mostram como uma equipe pode usar migrations durante o +desenvolvimento: + +1. Tim cria uma nova migration (por exemplo, cria uma nova tabela, altera a + definição de uma coluna etc.). +2. Tim faz o commit da nova migration no sistema de controle de versão (por + exemplo, Git, Mercurial). +3. Doug atualiza o repositório dele a partir do sistema de controle de + versão e recebe a nova migration. +4. Doug aplica a migration ao banco de dados local de desenvolvimento, + sincronizando o banco dele com as mudanças que Tim fez. + +E os passos a seguir mostram como fazer o deploy de uma nova release com +migrations para produção: + +1. Scott cria uma tag de release no repositório do projeto que contém + algumas migrations novas. +2. Scott atualiza o código-fonte no servidor de produção para a tag da + release. +3. Scott aplica todas as migrations acumuladas ao banco de dados de + produção. ```mermaid sequenceDiagram participant Tim - participant VCS as Source control + participant VCS as Controle de versão participant Doug - participant LocalDB as Local development database + participant LocalDB as Banco de dados local de desenvolvimento participant Scott - participant ProdServer as Production server - participant ProdDB as Production database + participant ProdServer as Servidor de produção + participant ProdDB as Banco de dados de produção - Tim->>Tim: Creates a new migration - Tim->>VCS: Commits the new migration - Doug->>VCS: Updates his repository and receives the new migration - Doug->>LocalDB: Applies the migration locally + Tim->>Tim: Cria uma nova migration + Tim->>VCS: Faz o commit da nova migration + Doug->>VCS: Atualiza o repositório e recebe a nova migration + Doug->>LocalDB: Aplica a migration localmente - Scott->>VCS: Creates a release tag with new migrations - Scott->>ProdServer: Updates source code to the release tag - Scott->>ProdDB: Applies accumulated migrations + Scott->>VCS: Cria uma tag de release com as novas migrations + Scott->>ProdServer: Atualiza o código-fonte para a tag da release + Scott->>ProdDB: Aplica as migrations acumuladas ``` -Yii provides a set of migration command line tools that allow you to: +O Yii fornece um conjunto de ferramentas de linha de comando para migrations +que permitem: -* create new migrations; -* apply migrations; -* revert migrations; -* re-apply migrations; -* show migration history and status. +* criar novas migrations; +* aplicar migrations; +* reverter migrations; +* reaplicar migrations; +* mostrar o histórico e o status das migrations. -All these tools are accessible through the command `yii migrate`. In this -section we will describe in detail how to accomplish various tasks using -these tools. +Todas essas ferramentas são acessíveis pelo comando `yii migrate`. Nesta +seção, vamos descrever em detalhes como realizar várias tarefas usando essas +ferramentas. > [!TIP] -> Migrations could affect not only database schema but adjust existing data to fit new schema, create RBAC -hierarchy or clean up cache. +> Migrations podem afetar não só o schema do banco de dados, mas também ajustar dados existentes ao novo schema, criar a hierarquia +de RBAC ou limpar o cache. > [!NOTE] -> When manipulating data using a migration you may find that using your Active Record or entity classes -> for this might be useful because some of the logic is already implemented there. Keep in mind however, that in contrast -> to code written in the migrations, whose nature is to stay constant forever, application logic is subject to change. -> So when using Active Record or entity classes in migration code, changes to the logic in the source code -> may accidentally break the existing migrations. For this reason migration code should be kept independent of other -> application logic such. +> Ao manipular dados em uma migration, pode parecer útil usar suas classes Active Record ou de entidade, +> já que parte da lógica já está implementada nelas. Lembre-se, porém, de que, ao contrário +> do código escrito nas migrations, que por natureza deve permanecer constante para sempre, a lógica da aplicação está sujeita a mudanças. +> Então, ao usar classes Active Record ou de entidade no código de migrations, mudanças na lógica do código-fonte +> podem quebrar acidentalmente as migrations existentes. Por isso, o código das migrations deve ser mantido independente do restante +> da lógica da aplicação. -## Initial configuration +## Configuração inicial -To use migrations, install -[yiisoft/db-migration](https://github.com/yiisoft/db-migration/) package: +Para usar migrations, instale o pacote +[yiisoft/db-migration](https://github.com/yiisoft/db-migration/): ```shell make composer require yiisoft/db-migration ``` -Create a directory to store migrations `src/Migration` right in the project -root. +Crie um diretório `src/Migration` para armazenar as migrations, diretamente +na raiz do projeto. -Add the following configuration to `config/common/params.php`: +Adicione a seguinte configuração em `config/common/params.php`: ```php 'yiisoft/db-migration' => [ @@ -98,28 +99,26 @@ Add the following configuration to `config/common/params.php`: ], ``` -If you want to place migrations elsewhere, you can define the path in -`newMigrationPath`. If your migrations to be applied are from multiple -sources, such as external modules, `sourcePaths` could be used to define -these. +Se você quiser colocar as migrations em outro lugar, pode definir o caminho +em `newMigrationPath`. Se as migrations a aplicar vêm de várias fontes, como +módulos externos, você pode usar `sourcePaths` para defini-las. -You need a database connection configured as well. See [Working with -databases](../start/databases.md) for an example of configuring it for -PostgreSQL. +Você também precisa de uma conexão com o banco de dados configurada. Veja +[Trabalhando com banco de dados](../start/databases.md) para um exemplo de +configuração com PostgreSQL. -## Creating a migration +## Criando uma migration -To create a new empty migration, run the following command: +Para criar uma nova migration vazia, execute o seguinte comando: ```sh make shell ./yii migrate:create ``` -The required `name` argument gives a brief description about the new -migration. For example, if the migration is about creating a new table named -*news*, you may use the name `create_news_table` and run the following -command: +O argumento obrigatório `name` dá uma breve descrição da nova migration. Por +exemplo, se a migration cria uma nova tabela chamada *news*, você pode usar +o nome `create_news_table` e executar o seguinte comando: ``` make shell @@ -128,13 +127,13 @@ make shell > [!NOTE] -> Because the `name` argument will be used as part of the generated migration class name, -> it should only contain letters, digits, and/or underscore characters. +> Como o argumento `name` é usado como parte do nome da classe de migration gerada, +> ele deve conter apenas letras, dígitos e/ou underscores. -The above command will create a new PHP class file named -`src/Migration/M251225221906CreateNewsTable.php`. The file contains the -following code which mainly declares a migration class with the skeleton -code: +O comando acima cria um novo arquivo de classe PHP chamado +`src/Migration/M251225221906CreateNewsTable.php`. O arquivo contém o código +a seguir, que basicamente declara uma classe de migration com o esqueleto do +código: ```php Note: Not all DBMS support transactions. And some DB queries cannot be put into a transaction. For some examples, -please refer to [implicit commit](https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html). +> Nota: nem todo SGBD dá suporte a transações. E algumas consultas não podem ser colocadas em uma transação. Para alguns exemplos, +consulte [implicit commit](https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html). -## Generating a migration +## Gerando uma migration -Instead of writing migrations by hand, the command provides a convenient way -generate some of the code. +Em vez de escrever migrations à mão, o comando oferece uma forma prática de +gerar parte do código. ```shell make shell ./yii migrate:create -- my_first_table --command=table --fields=name,example --table-comment=my_first_table ``` -That would generate the following: +Isso geraria o seguinte: ```php Note: Not all migrations are reversible. Trying to revert such migrations will cause an error and stop the -entire reverting process. +> Nota: nem todas as migrations são reversíveis. Tentar reverter uma migration assim causa um erro e interrompe +todo o processo de reversão. -## Redoing Migrations +## Refazendo migrations -Redoing migrations means first reverting the specified migrations and then -applying again. This can be done as follows: +Refazer migrations significa primeiro reverter as migrations especificadas e +depois aplicá-las novamente. Isso pode ser feito assim: ``` -./yii migrate:redo # redo the last applied migration -./yii migrate:redo --limit=3 # redo the last 3 applied migrations -./yii migrate:redo --all # redo all migrations +./yii migrate:redo # refaz a última migration aplicada +./yii migrate:redo --limit=3 # refaz as 3 últimas migrations aplicadas +./yii migrate:redo --all # refaz todas as migrations ``` -> Note: If a migration is not reversible, you will not be able to redo it. +> Nota: se uma migration não for reversível, você não conseguirá refazê-la. -## Listing Migrations +## Listando migrations -To list which migrations have been applied and which are not, you may use -the following commands: +Para listar quais migrations foram aplicadas e quais não foram, use os +seguintes comandos: ``` -./yii migrate/history # showing the last 10 applied migrations -./yii migrate:history --limit=5 # showing the last 5 applied migrations -./yii migrate:history --all # showing all applied migrations +./yii migrate/history # mostra as 10 últimas migrations aplicadas +./yii migrate:history --limit=5 # mostra as 5 últimas migrations aplicadas +./yii migrate:history --all # mostra todas as migrations aplicadas -./yii migrate:new # showing the first 10 new migrations -./yii migrate:new --limit=5 # showing the first 5 new migrations -./yii migrate:new --all # showing all new migrations +./yii migrate:new # mostra as 10 primeiras migrations novas +./yii migrate:new --limit=5 # mostra as 5 primeiras migrations novas +./yii migrate:new --all # mostra todas as migrations novas ``` -### Upgrading from Yii 2.0 +### Migrando do Yii 2.0 -Migrations in Yii 2.0 and the -[yiisoft/db-migration](https://github.com/yiisoft/db-migration/) package are -not compatible, and the `migration` table is also not compatible. +As migrations do Yii 2.0 e o pacote +[yiisoft/db-migration](https://github.com/yiisoft/db-migration/) não são +compatíveis, e a tabela `migration` também não é compatível. -A probable solution is to use structure dumps and rename the old `migration` -table. Upon the initial execution of migrations, a new `migration` table -with new fields will be created. All further changes in the database schema -are applied using the new `migration` component and recorded in the new -migration table. +Uma solução possível é usar dumps da estrutura e renomear a tabela +`migration` antiga. Na primeira execução das migrations, uma nova tabela +`migration` com os novos campos será criada. Todas as mudanças seguintes no +schema do banco de dados são aplicadas usando o novo componente `migration` +e registradas na nova tabela de migrations. diff --git a/src/pt-BR/guide/rest/quick-start.md b/src/pt-BR/guide/rest/quick-start.md index 4805a677..e6818b23 100644 --- a/src/pt-BR/guide/rest/quick-start.md +++ b/src/pt-BR/guide/rest/quick-start.md @@ -1,26 +1,27 @@ -# Quick start +# Início rápido -Yii works with JSON APIs through the same PSR-7 request and response objects -used by web pages. For API endpoints, the usual flow is: +O Yii trabalha com APIs JSON usando os mesmos objetos de requisição e +resposta PSR-7 das páginas web. Para endpoints de API, o fluxo comum é: -* Parse the request body when the client sends JSON. -* Map request data to a typed input object. -* Validate the input object. -* Return a response whose data is formatted as JSON. +* Ler o corpo da requisição quando o cliente envia JSON. +* Mapear os dados da requisição para um objeto de entrada tipado. +* Validar o objeto de entrada. +* Retornar uma resposta cujos dados são formatados como JSON. -This guide assumes that you use the [API application -template](https://github.com/yiisoft/app-api). It already includes request -body parsing, request input resolving, JSON data responses, and presenter -examples. For complete applications with different structures, see [Demo -applications](../start/demo-apps.md). +Este guia assume que você usa o [template de aplicação +API](https://github.com/yiisoft/app-api). Ele já inclui a leitura do corpo +da requisição, a resolução da entrada da requisição, respostas de dados em +JSON e exemplos de presenters. Para aplicações completas com outras +estruturas, veja [Aplicações demo](../start/demo-apps.md). -## Creating request input +## Criando a entrada da requisição -Use [yiisoft/input-http](https://github.com/yiisoft/input-http) to describe -request data as a typed input object. Attach `#[FromBody]` when all values -should come from the parsed request body. +Use o [yiisoft/input-http](https://github.com/yiisoft/input-http) para +descrever os dados da requisição como um objeto de entrada tipado. Adicione +`#[FromBody]` quando todos os valores devem vir do corpo da requisição já +interpretado. -Create `src/Api/Post/CreatePostInput.php`: +Crie `src/Api/Post/CreatePostInput.php`: ```php user->isGuest()) { - // user is guest + // o usuário é visitante } else { $identity = $this->user->getIdentity(); - // do something based on identity + // faça algo com base na identidade } } } ``` -`isGuest()` determines if user is logged in or not. `getIdentity()` returns -an instance of identity. +`isGuest()` determina se o usuário está logado ou não. `getIdentity()` +retorna uma instância da identidade. -To log in a user, you may use the following code: +Para fazer o login de um usuário, você pode usar o seguinte código: ```php $identity = $identityRepository->findByEmail($email); @@ -182,22 +184,23 @@ $identity = $identityRepository->findByEmail($email); $user->login($identity); ``` -The `login()` method sets the identity to the User service. It stores -identity into session so user authentication status is maintained. +O método `login()` define a identidade no serviço de usuário. Ele armazena +a identidade na sessão, para que o estado de autenticação do usuário seja +mantido. -To log out a user, call +Para fazer o logout de um usuário, chame ```php /* @var $user \Yiisoft\User\CurrentUser */ $user->logout(); ``` -## Protecting Routes +## Protegendo rotas -The `Yiisoft\Auth\Middleware\Authentication` middleware can be used to -restrict access to a given route to authenticated users only. +O middleware `Yiisoft\Auth\Middleware\Authentication` pode ser usado para +restringir o acesso a uma rota apenas a usuários autenticados. -First, configure the `Yiisoft\Auth\AuthenticationMethodInterface`: +Primeiro, configure a `Yiisoft\Auth\AuthenticationMethodInterface`: ```php use Yiisoft\Auth\AuthenticationMethodInterface; @@ -209,8 +212,8 @@ return [ ]; ``` -Then, apply the `Yiisoft\Auth\Middleware\Authentication` middleware to a -route: +Depois, aplique o middleware `Yiisoft\Auth\Middleware\Authentication` a uma +rota: ```php use Yiisoft\Auth\Middleware\Authentication; @@ -221,7 +224,7 @@ Route::post('/create') ->name('site/create') ``` - Or to a group of routes: + Ou a um grupo de rotas: ```php use Yiisoft\Auth\Middleware\Authentication; @@ -238,21 +241,22 @@ Group::create() ) ``` -## Authentication Events +## Eventos de autenticação -The user service raises a few events during the login and logout processes. +O serviço de usuário dispara alguns eventos durante os processos de login e +logout. -* `\Yiisoft\User\Event\BeforeLogin`: raised at the beginning of `login()`. - If the event handler calls `invalidate()` on an event object, the login - process will be cancelled. -* `\Yiisoft\User\Event\AfterLogin`: raised after a successful login. -* `\Yiisoft\User\Event\BeforeLogout`: raised at the beginning of - `logout()`. If the event handler calls `invalidate()` on an event object, - the logout process will be cancelled. -* `\Yiisoft\User\Event\AfterLogout`: raised after a successful logout. +* `\Yiisoft\User\Event\BeforeLogin`: disparado no início de `login()`. Se o + handler do evento chamar `invalidate()` no objeto do evento, o processo de + login será cancelado. +* `\Yiisoft\User\Event\AfterLogin`: disparado após um login bem-sucedido. +* `\Yiisoft\User\Event\BeforeLogout`: disparado no início de `logout()`. Se + o handler do evento chamar `invalidate()` no objeto do evento, o processo + de logout será cancelado. +* `\Yiisoft\User\Event\AfterLogout`: disparado após um logout bem-sucedido. -You may respond to these events to implement features such as login audit, -online user statistics. For example, in the handler for -`\Yiisoft\User\Event\AfterLogin`, you may record the login time and IP -address in the `user` database table. +Você pode responder a esses eventos para implementar recursos como auditoria +de login ou estatísticas de usuários online. Por exemplo, no handler de +`\Yiisoft\User\Event\AfterLogin`, você pode registrar o horário e o endereço +IP do login na tabela `user` do banco de dados. diff --git a/src/pt-BR/guide/security/authorization.md b/src/pt-BR/guide/security/authorization.md index f68d8560..8c50236b 100644 --- a/src/pt-BR/guide/security/authorization.md +++ b/src/pt-BR/guide/security/authorization.md @@ -1,12 +1,12 @@ -# Authorization +# Autorização -Authorization is the process of verifying that a user has enough permission -to do something. +Autorização é o processo de verificar se um usuário tem permissão suficiente +para fazer algo. -## Checking for permission +## Verificando permissões -You can check if a user has certain permissions by using -`\Yiisoft\User\CurrentUser` service: +Você pode verificar se um usuário tem determinadas permissões usando o +serviço `\Yiisoft\User\CurrentUser`: ```php namespace App\Blog\Post; @@ -28,14 +28,14 @@ final readonly class PostController { $post = $this->postRepository->findByPK($id); if ($post === null) { - // respond with 404 + // responda com 404 } if (!$this->canCurrentUserUpdatePost($post)) { - // respond with 403 + // responda com 403 } - // continue with updating the post + // continue com a atualização do post } private function canCurrentUserUpdatePost(Post $post): bool @@ -46,75 +46,80 @@ final readonly class PostController } ``` -Behind the scenes, `Yiisoft\User\CurrentUser::can()` method calls -`Yiisoft\Access\AccessCheckerInterface::userHasPermission()` so you should -provide an implementation in dependency container in order for it to work. +Por baixo dos panos, o método `Yiisoft\User\CurrentUser::can()` chama +`Yiisoft\Access\AccessCheckerInterface::userHasPermission()`, então você +precisa fornecer uma implementação no container de dependências para que ele +funcione. -## Role-based access control (RBAC) +## Controle de acesso baseado em papéis (RBAC) -Role-Based Access Control (RBAC) provides a simple yet powerful centralized -access control. Please refer to the -[Wikipedia](https://en.wikipedia.org/wiki/Role-based_access_control) for -details about comparing RBAC with other more traditional access control -schemes. +O controle de acesso baseado em papéis (RBAC, Role-Based Access Control) +oferece um controle de acesso centralizado simples e flexível. Consulte a +[Wikipedia](https://en.wikipedia.org/wiki/Role-based_access_control) para +detalhes sobre a comparação do RBAC com outros esquemas de controle de +acesso mais tradicionais. -Yii implements a General Hierarchical RBAC, following the [NIST RBAC -model](https://csrc.nist.gov/CSRC/media/Publications/conference-paper/2000/07/26/the-nist-model-for-role-based-access-control-towards-a-unified-/documents/sandhu-ferraiolo-kuhn-00.pdf). +O Yii implementa um RBAC hierárquico geral, seguindo o [modelo RBAC do +NIST](https://csrc.nist.gov/CSRC/media/Publications/conference-paper/2000/07/26/the-nist-model-for-role-based-access-control-towards-a-unified-/documents/sandhu-ferraiolo-kuhn-00.pdf). -Using RBAC involves two parts of work. The first part is to build up the -RBAC authorization data, and the second part is to use the authorization -data to perform access check in places where it's necessary. Since RBAC -implements `\Yiisoft\Access\AccessCheckerInterface`, using it's similar to -using any other implementation of an access checker. +Usar RBAC envolve duas partes de trabalho. A primeira é montar os dados de +autorização do RBAC, e a segunda é usar esses dados para fazer a verificação +de acesso onde for necessário. Como o RBAC implementa +`\Yiisoft\Access\AccessCheckerInterface`, usá-lo é parecido com usar +qualquer outra implementação de verificador de acesso. -To ease description next, there are some basic RBAC concepts first. +Para facilitar a explicação a seguir, primeiro alguns conceitos básicos de +RBAC. -### Basic concepts +### Conceitos básicos -A role represents a collection of *permissions* (for example, creating -posts, updating posts). You may assign a role to one or many users. To -check if a user has a specified permission, you may check if the user has a -role with that permission. +Um papel representa um conjunto de *permissões* (por exemplo, criar posts, +atualizar posts). Você pode atribuir um papel a um ou mais usuários. Para +verificar se um usuário tem uma determinada permissão, você pode verificar +se ele tem um papel com essa permissão. -Associated with each role or permission, there may be a *rule*. A rule -represents a piece of code that an access checker will execute to decide if -the corresponding role or permission applies to the current user. For -example, the "update post" permission may have a rule that checks if the -current user is the post creator. During access checking, if the user is -NOT the post creator, there's no "update post" permission. +Cada papel ou permissão pode ter uma *regra* associada. Uma regra +representa um trecho de código que o verificador de acesso executa para +decidir se o papel ou a permissão correspondente se aplica ao usuário +atual. Por exemplo, a permissão "atualizar post" pode ter uma regra que +verifica se o usuário atual é o criador do post. Durante a verificação de +acesso, se o usuário NÃO for o criador do post, ele não tem a permissão +"atualizar post". -Both roles and permissions are in a hierarchy. In particular, a role may -consist of other roles or permissions. And a permission may consist of -other permissions. Yii implements a *partial order* hierarchy which -includes the more special *tree* hierarchy. While a role can contain a -permission, it isn't `true` vice versa. +Tanto papéis quanto permissões ficam em uma hierarquia. Em particular, um +papel pode ser composto de outros papéis ou permissões. E uma permissão +pode ser composta de outras permissões. O Yii implementa uma hierarquia de +*ordem parcial*, que inclui a hierarquia mais específica em *árvore*. +Embora um papel possa conter uma permissão, o inverso não é verdadeiro. -### Configuring RBAC +### Configurando o RBAC -Yii RBAC requires storage to be provided. +O RBAC do Yii exige que um armazenamento seja fornecido. -One of the following storages could be installed: +Um dos seguintes armazenamentos pode ser instalado: -- [PHP storage](https://github.com/yiisoft/rbac-php) - PHP file storage; -- [DB storage](https://github.com/yiisoft/rbac-db) - database storage based - on [Yii DB](https://github.com/yiisoft/db); -- [Cycle DB storage](https://github.com/yiisoft/rbac-cycle-db) - database - storage based on [Cycle DBAL](https://github.com/cycle/database). +- [Armazenamento PHP](https://github.com/yiisoft/rbac-php) - armazenamento + em arquivos PHP; +- [Armazenamento em DB](https://github.com/yiisoft/rbac-db) - armazenamento + em banco de dados baseado no [Yii DB](https://github.com/yiisoft/db); +- [Armazenamento Cycle DB](https://github.com/yiisoft/rbac-cycle-db) - + armazenamento em banco de dados baseado no [Cycle + DBAL](https://github.com/cycle/database). -You can also provide your own storage using the -[yiisoft/rbac](https://github.com/yiisoft/rbac) package. +Você também pode fornecer seu próprio armazenamento usando o pacote +[yiisoft/rbac](https://github.com/yiisoft/rbac). -#### Configuring RBAC with the [PHP storage](https://github.com/yiisoft/rbac-php) +#### Configurando o RBAC com o [armazenamento PHP](https://github.com/yiisoft/rbac-php) -Install [yiisoft/rbac-php](https://github.com/yiisoft/rbac-php) package: +Instale o pacote [yiisoft/rbac-php](https://github.com/yiisoft/rbac-php): ``` composer require yiisoft/rbac-php ``` -Before we set off to define authorization data and perform access checking, -you need to configure the `Yiisoft\Access\AccessCheckerInterface` in -dependency container: +Antes de definir os dados de autorização e fazer verificações de acesso, +você precisa configurar a `Yiisoft\Access\AccessCheckerInterface` no +container de dependências: ```php use Yiisoft\Rbac\ItemsStorageInterface; @@ -147,31 +152,32 @@ return [ ]; ``` -`Yiisoft\Rbac\Manager` uses PHP script files to store authorization data. -Make sure the directory and all the files in it are writable by the Web -server process if you want to change permission hierarchy online. +O `Yiisoft\Rbac\Manager` usa arquivos de script PHP para armazenar os dados +de autorização. Garanta que o diretório e todos os arquivos dentro dele +tenham permissão de escrita para o processo do servidor web, se você quiser +alterar a hierarquia de permissões em tempo de execução. -#### Configuring RBAC with the [DB storage](https://github.com/yiisoft/rbac-db) +#### Configurando o RBAC com o [armazenamento em DB](https://github.com/yiisoft/rbac-db) -Install [yiisoft/rbac-db](https://github.com/yiisoft/rbac-db) package: +Instale o pacote [yiisoft/rbac-db](https://github.com/yiisoft/rbac-db): ``` composer require yiisoft/rbac-db ``` -Install one of the following drivers: - - [SQLite](https://github.com/yiisoft/db-sqlite) (minimal required version is 3.8.3) +Instale um dos seguintes drivers: + - [SQLite](https://github.com/yiisoft/db-sqlite) (a versão mínima exigida é a 3.8.3) - [MySQL](https://github.com/yiisoft/db-mysql) - [PostgreSQL](https://github.com/yiisoft/db-pgsql) - [Microsoft SQL Server](https://github.com/yiisoft/db-mssql) - [Oracle](https://github.com/yiisoft/db-oracle) -[Configure -connection](https://yiisoft.github.io/docs/guide/start/databases.html#configuring-connection). +[Configure a +conexão](https://yiisoft.github.io/docs/guide/start/databases.html#configuring-connection). -Before we set off to define authorization data and perform access checking, -you need to configure the `Yiisoft\Access\AccessCheckerInterface` in -dependency container: +Antes de definir os dados de autorização e fazer verificações de acesso, +você precisa configurar a `Yiisoft\Access\AccessCheckerInterface` no +container de dependências: ```php use Yiisoft\Rbac\ItemsStorageInterface; @@ -189,8 +195,8 @@ return [ ]; ``` -Add the RBAC [DB storage](https://github.com/yiisoft/rbac-db) migration -paths to params.php: +Adicione os caminhos das migrations do [armazenamento em +DB](https://github.com/yiisoft/rbac-db) do RBAC ao params.php: ```php return [ @@ -204,44 +210,44 @@ return [ ]; ``` -Apply migrations: +Aplique as migrations: ``` ./yii migrate:up ``` -### Building authorization data +### Montando os dados de autorização -Building authorization data is all about the following tasks: +Montar os dados de autorização consiste nas seguintes tarefas: -- defining roles and permissions; -- establishing relations between roles and permissions; -- defining rules; -- associating rules with roles and permissions; -- assigning roles to users. +- definir papéis e permissões; +- estabelecer relações entre papéis e permissões; +- definir regras; +- associar regras a papéis e permissões; +- atribuir papéis a usuários. -Depending on authorization flexibility requirements, you can do the tasks in -different ways. If only developers change your permission hierarchy, you -can use either migrations or a console command. Migration advantage is that -you could execute it along with other migrations. The Console command -advantage is that you have a good overview of the hierarchy in the code -without a need to read many migrations. +Dependendo da flexibilidade de autorização exigida, você pode fazer essas +tarefas de maneiras diferentes. Se apenas desenvolvedores alteram sua +hierarquia de permissões, você pode usar migrations ou um comando de +console. A vantagem da migration é que você pode executá-la junto com as +outras migrations. A vantagem do comando de console é que você tem uma boa +visão da hierarquia no código, sem precisar ler muitas migrations. -Either way, in the end, you'll get the following RBAC hierarchy: +De qualquer forma, no fim você terá a seguinte hierarquia RBAC: -![Simple RBAC hierarchy](/images/guide/security/rbac-hierarchy-1.svg "Simple -RBAC hierarchy") +![Hierarquia RBAC simples](/images/guide/security/rbac-hierarchy-1.svg +"Hierarquia RBAC simples") -In case you want to build permission hierarchy dynamically, you need a UI or -a console command. The API used to build the hierarchy itself won't be -different. +Caso você queira montar a hierarquia de permissões dinamicamente, precisa de +uma interface de usuário ou de um comando de console. A API usada para +montar a hierarquia em si não muda. -### Using console command +### Usando um comando de console -If your permission hierarchy doesn't change at all, and you have a fixed -number of users, you can create a [console -command](../tutorial/console-applications.md) that will initialize -authorization data once via APIs offered by +Se a sua hierarquia de permissões não muda nunca e você tem um número fixo +de usuários, pode criar um [comando de +console](../tutorial/console-applications.md) que inicializa os dados de +autorização uma única vez, usando as APIs oferecidas por `\Yiisoft\Rbac\ManagerInterface`: ```php @@ -280,18 +286,18 @@ final class RbacCommand extends Command $this->manager->addPermission((new Permission(RbacCommand::CREATE_POST_PERMISSION))->withDescription('Create a post')); $this->manager->addPermission((new Permission(RbacCommand::UPDATE_POST_PERMISSION))->withDescription('Update post')); - // add the "author" role and give this role the "createPost" permission + // adiciona o papel "author" e dá a ele a permissão "createPost" $this->manager->addRole(new Role(RbacCommand::ROLE_AUTHOR)); $this->manager->addChild(RbacCommand::ROLE_AUTHOR, RbacCommand::CREATE_POST_PERMISSION); - // add the "admin" role and give this role the "updatePost" permission - // as well as the permissions of the "author" role + // adiciona o papel "admin" e dá a ele a permissão "updatePost" + // além das permissões do papel "author" $this->manager->addRole(new Role(RbacCommand::ROLE_ADMIN)); $this->manager->addChild(RbacCommand::ROLE_ADMIN, RbacCommand::UPDATE_POST_PERMISSION); $this->manager->addChild(RbacCommand::ROLE_ADMIN, RbacCommand::ROLE_AUTHOR); - // Assign roles to users. 1 and 2 are IDs returned by IdentityInterface::getId() - // usually implemented in your User model. + // Atribui papéis aos usuários. 1 e 2 são IDs retornados por IdentityInterface::getId(), + // normalmente implementado no seu model User. $this->manager->assign(RbacCommand::ROLE_AUTHOR, 2); $this->manager->assign(RbacCommand::ROLE_ADMIN, 1); @@ -312,7 +318,7 @@ final class RbacCommand extends Command } ``` -Add the command to `config/console/commands.php`: +Adicione o comando em `config/console/commands.php`: ```php return [ @@ -321,24 +327,25 @@ return [ ]; ``` -You can execute the command above from the console the following way: +Você pode executar o comando acima no console da seguinte forma: ``` ./yii rbac:init ``` -> If you don't want to hardcode what users have certain roles, don't put `->assign()` calls into the command. Instead, - create either UI or console command to manage assignments. +> Se você não quer deixar fixo no código quais usuários têm determinados papéis, não coloque chamadas `->assign()` no comando. Em vez disso, + crie uma interface de usuário ou um comando de console para gerenciar as atribuições. -#### Using migrations +#### Usando migrations -**TODO**: finish it when migrations are implemented. +**TODO**: terminar quando as migrations forem implementadas. -You can use [migrations](../databases/db-migrations.md) to initialize and -change hierarchy via APIs offered by `\Yiisoft\Rbac\ManagerInterface`. +Você pode usar [migrations](../databases/db-migrations.md) para inicializar +e alterar a hierarquia via APIs oferecidas por +`\Yiisoft\Rbac\ManagerInterface`. -Create new migration using `./yii migrate:create init_rbac` then implement -creating a hierarchy: +Crie uma nova migration com `./yii migrate:create init_rbac` e implemente a +criação da hierarquia: ```php manager->addPermission((new Permission(M260112125812InitRbac::CREATE_POST_PERMISSION))->withDescription('Create a post')); $this->manager->addPermission((new Permission(M260112125812InitRbac::UPDATE_POST_PERMISSION))->withDescription('Update post')); - // add the "author" role and give this role the "createPost" permission + // adiciona o papel "author" e dá a ele a permissão "createPost" $this->manager->addRole(new Role(M260112125812InitRbac::ROLE_AUTHOR)); $this->manager->addChild(M260112125812InitRbac::ROLE_AUTHOR, M260112125812InitRbac::CREATE_POST_PERMISSION); - // add the "admin" role and give this role the "updatePost" permission - // as well as the permissions of the "author" role + // adiciona o papel "admin" e dá a ele a permissão "updatePost" + // além das permissões do papel "author" $this->manager->addRole(new Role(M260112125812InitRbac::ROLE_ADMIN)); $this->manager->addChild(M260112125812InitRbac::ROLE_ADMIN, M260112125812InitRbac::UPDATE_POST_PERMISSION); $this->manager->addChild(M260112125812InitRbac::ROLE_ADMIN, M260112125812InitRbac::ROLE_AUTHOR); - // Assign roles to users. 1 and 2 are IDs returned by IdentityInterface::getId() - // usually implemented in your User model. + // Atribui papéis aos usuários. 1 e 2 são IDs retornados por IdentityInterface::getId(), + // normalmente implementado no seu model User. $this->manager->assign(M260112125812InitRbac::ROLE_AUTHOR, 2); $this->manager->assign(M260112125812InitRbac::ROLE_ADMIN, 1); } @@ -396,22 +403,23 @@ final class M260112125812InitRbac implements RevertibleMigrationInterface } ``` -> If you don't want to hardcode which users have certain roles, don't put `->assign()` calls in migrations. Instead, - create either UI or console command to manage assignments. +> Se você não quer deixar fixo no código quais usuários têm determinados papéis, não coloque chamadas `->assign()` nas migrations. Em vez disso, + crie uma interface de usuário ou um comando de console para gerenciar as atribuições. -You could apply migration by using `./yii migrate:up`. +Você pode aplicar a migration com `./yii migrate:up`. -## Assigning roles to users +## Atribuindo papéis a usuários -TODO: update when signup implemented in demo / template. +TODO: atualizar quando o cadastro for implementado no demo / template. -The author can create a post, admin can update the post and do everything -the author can. +O autor pode criar um post, o admin pode atualizar o post e fazer tudo o que +o autor pode. -If your application allows user signup, you need to assign roles to these -new users at once. For example, in order for all signed-up users to become -authors in your advanced project template, you need to change -`frontend\models\SignupForm::signup()` as follows: +Se sua aplicação permite o cadastro de usuários, você precisa atribuir +papéis a esses novos usuários imediatamente. Por exemplo, para que todos os +usuários cadastrados se tornem autores no seu template de projeto avançado, +você precisa alterar `frontend\models\SignupForm::signup()` da seguinte +forma: ```php public function signup() @@ -424,7 +432,7 @@ public function signup() $user->generateAuthKey(); $user->save(false); - // the following three lines were added: + // as três linhas a seguir foram adicionadas: $authorRole = $this->manager->getRole('author'); if ($authorRole !== null) { $this->manager->assign($authorRole->getName(), $user->getId()); @@ -437,19 +445,19 @@ public function signup() } ``` -For applications that require complex access control with dynamically -updated authorization data (such as an admin panel), you many need to -develop special user interfaces using APIs offered by -`Yiisoft\Rbac\Manager`. +Para aplicações que exigem controle de acesso complexo com dados de +autorização atualizados dinamicamente (como um painel administrativo), +talvez você precise desenvolver interfaces de usuário específicas usando as +APIs oferecidas por `Yiisoft\Rbac\Manager`. -### Using rules +### Usando regras -As aforementioned, rules add extra constraint to roles and permissions. A -rule is a class extending from `\Yiisoft\Rbac\Rule`. It must implement the -`execute()` method. In the hierarchy you've created before, the author -can't edit his own post. Let's fix it. First, you need a rule to verify -that the user is the post author: +Como mencionado, regras adicionam restrições extras a papéis e permissões. +Uma regra é uma classe que estende `\Yiisoft\Rbac\Rule`. Ela deve +implementar o método `execute()`. Na hierarquia que você criou antes, o +autor não pode editar o próprio post. Vamos corrigir isso. Primeiro, você +precisa de uma regra para verificar se o usuário é o autor do post: ```php namespace App\User\Rbac; @@ -471,39 +479,38 @@ final readonly class AuthorRule implements RuleInterface } ``` -The rule checks if user created the `post`. Create a special permission -`updateOwnPost` in the command you've used before: +A regra verifica se o usuário criou o `post`. Crie uma permissão especial +`updateOwnPost` no comando que você usou antes: ```php use Yiisoft\Rbac\Permission; use Yiisoft\Rbac\ManagerInterface; -// add the "updateOwnPost" permission and associate the rule with it. +// adiciona a permissão "updateOwnPost" e associa a regra a ela. $updateOwnPost = (new Permission('updateOwnPost')) ->withDescription('Update own post') ->withRuleName(AuthorRule::class); $this->manager->addPermission($updateOwnPost); -// "updateOwnPost" will be used from "updatePost" +// "updateOwnPost" será usada a partir de "updatePost" $this->manager->addChild($updateOwnPost->getName(), $updatePost->getName()); -// allow "author" to update their own posts +// permite que "author" atualize os próprios posts $this->manager->addChild($authorRole->getName(), $updateOwnPost->getName()); -// Remove this line since we don't want the AuthorRule to be applied to the 'admin' role +// Remova esta linha, já que não queremos que a AuthorRule seja aplicada ao papel 'admin' $this->manager->addChild('admin', 'author'); ``` -Now you've got the following hierarchy: +Agora você tem a seguinte hierarquia: -![RBAC hierarchy with a rule](/images/guide/security/rbac-hierarchy-2.svg -"RBAC hierarchy with a rule") +![Hierarquia RBAC com uma regra](/images/guide/security/rbac-hierarchy-2.svg +"Hierarquia RBAC com uma regra") -### Access check +### Verificação de acesso -The check is done similarly to how it was done in the first section of this -guide: +A verificação é feita de forma semelhante à da primeira seção deste guia: ```php namespace App\Blog\Post; @@ -525,14 +532,14 @@ final readonly class PostController { $post = $this->postRepository->findByPK($id); if ($post === null) { - // respond with 404 + // responda com 404 } if (!$this->canCurrentUserUpdatePost($post)) { - // respond with 403 + // responda com 403 } - // continue with updating the post + // continue com a atualização do post } private function canCurrentUserUpdatePost(Post $post): bool @@ -542,44 +549,44 @@ final readonly class PostController } ``` -The difference is that now checking for a user's own post is part of the -RBAC. +A diferença é que agora a verificação do próprio post do usuário faz parte +do RBAC. -If the current user is Jane with `ID=1` you are starting at `createPost` and -trying to get to `Jane`: +Se o usuário atual for Jane, com `ID=1`, você começa em `createPost` e tenta +chegar a `Jane`: -![Access check](/images/guide/security/rbac-access-check-1.svg "Access -check") +![Verificação de acesso](/images/guide/security/rbac-access-check-1.svg +"Verificação de acesso") -To check if a user can update a post, you need to pass an extra parameter -that's required by `AuthorRule` described before: +Para verificar se um usuário pode atualizar um post, você precisa passar um +parâmetro extra exigido pela `AuthorRule` descrita antes: ```php if ($user->can('updatePost', ['post' => $post])) { - // update post + // atualiza o post } ``` -Here is what happens if the current user is John: +Veja o que acontece se o usuário atual for John: -![Access check](/images/guide/security/rbac-access-check-2.svg "Access -check") +![Verificação de acesso](/images/guide/security/rbac-access-check-2.svg +"Verificação de acesso") -You're starting with the `updatePost` and going through `updateOwnPost`. To pass the access check, `AuthorRule` -should return `true` from its `execute()` method. The method receives its `$params` from the `can()` method call, so the value is +Você começa em `updatePost` e passa por `updateOwnPost`. Para passar na verificação de acesso, a `AuthorRule` +deve retornar `true` no método `execute()`. O método recebe seus `$params` da chamada do método `can()`, então o valor é `['post' => $post]`. -If everything is fine, you will get to `author` assigned to John. +Se tudo estiver certo, você chega a `author`, atribuído a John. -In the case of Jane, it's a bit simpler since she is an admin: +No caso de Jane, é um pouco mais simples, já que ela é admin: -![Access check](/images/guide/security/rbac-access-check-3.svg "Access -check") +![Verificação de acesso](/images/guide/security/rbac-access-check-3.svg +"Verificação de acesso") -## Implementing your own access checker +## Implementando seu próprio verificador de acesso -If RBAC doesn't suit your needs, you can implement your own access checker -without changing the application code: +Se o RBAC não atende às suas necessidades, você pode implementar seu próprio +verificador de acesso sem alterar o código da aplicação: ```php diff --git a/src/pt-BR/guide/security/best-practices.md b/src/pt-BR/guide/security/best-practices.md index 32ae9410..78601e80 100644 --- a/src/pt-BR/guide/security/best-practices.md +++ b/src/pt-BR/guide/security/best-practices.md @@ -1,29 +1,29 @@ -# Security best practices +# Boas práticas de segurança -Below, we'll review common security principles and describe how to avoid -threats when developing applications using Yii. Most of these principles -aren't unique to Yii alone but apply to website or software development in -general, so you will also find links for further reading on the general -ideas behind these. +A seguir, vamos revisar princípios comuns de segurança e descrever como +evitar ameaças ao desenvolver aplicações com o Yii. A maioria desses +princípios não é exclusiva do Yii e vale para o desenvolvimento de sites e +software em geral, por isso você também vai encontrar links para leitura +adicional sobre as ideias gerais por trás deles. -## Basic principles +## Princípios básicos -There are two main principles when it comes to security no matter which -application is being developed: +Há dois princípios principais quando o assunto é segurança, não importa qual +aplicação esteja sendo desenvolvida: -1. Filter input. -2. Escape output. +1. Filtre a entrada. +2. Escape a saída. -### Filter input +### Filtre a entrada -Filter input means that you should never consider input safe, and you should -always check if the value you've got is actually among allowed ones. For -example, if you know that you sort by three fields `title`, `created_at` and -`status` and the field came from user input, it's better to check the value -you've got right where you're receiving it. In terms of basic PHP, that -would look like the following: +Filtrar a entrada significa que você nunca deve considerar uma entrada +segura e deve sempre verificar se o valor recebido está de fato entre os +permitidos. Por exemplo, se você sabe que a ordenação é feita por três +campos, `title`, `created_at` e `status`, e o campo vem da entrada do +usuário, é melhor verificar o valor no mesmo lugar em que você o recebe. Em +PHP puro, isso ficaria assim: ```php $sortBy = $_GET['sort']; @@ -32,57 +32,58 @@ if (!in_array($sortBy, ['title', 'created_at', 'status'])) { } ``` -In Yii, most probably you'll use form validation to do similar checks. +No Yii, você provavelmente vai usar a validação de formulários para fazer +verificações parecidas. -Further reading on the topic: +Leitura adicional sobre o assunto: - - -### Escape output +### Escape a saída -Escape output means that, depending on the context where you're using data, -you should prepend it with special characters to negate its special meaning. -In context of HTML you should escape `<`, `>` and alike special characters. -In the context of JavaScript or SQL, it will be a different set of characters. -Since it's error-prone to escape manually, Yii provides various tools to perform escaping in different contexts. +Escapar a saída significa que, dependendo do contexto em que você usa os dados, +você deve prefixá-los com caracteres especiais para anular seu significado especial. +No contexto de HTML, você deve escapar `<`, `>` e caracteres especiais semelhantes. +No contexto de JavaScript ou SQL, o conjunto de caracteres será outro. +Como escapar manualmente é propenso a erros, o Yii fornece várias ferramentas para fazer o escape em diferentes contextos. -Further reading on the topic: +Leitura adicional sobre o assunto: - - - -## Avoiding SQL injections +## Evitando SQL injection -SQL injection happens when you form a query text by concatenating unescaped -strings such as the following: +SQL injection acontece quando você monta o texto de uma consulta +concatenando strings não escapadas, como a seguir: ```php $username = $_GET['username']; $sql = "SELECT * FROM user WHERE username = '$username'"; ``` -Instead of supplying correct username attacker could give your applications -something like `'; DROP TABLE user; --`. The Resulting SQL will be the -following: +Em vez de informar um nome de usuário correto, um atacante pode passar para +sua aplicação algo como `'; DROP TABLE user; --`. O SQL resultante será o +seguinte: ```sql SELECT * FROM user WHERE username = ''; DROP TABLE user; --' ``` -This is a valid query that will search for users with empty username and -then will drop `user` table most probably resulting in a broken website and -data loss (you've set up regular backups, right?). +Essa é uma consulta válida, que vai buscar usuários com nome de usuário +vazio e depois apagar a tabela `user`, o que provavelmente resulta em um +site quebrado e perda de dados (você configurou backups regulares, certo?). -Make sure to either use PDO prepared statements directly or ensure that the -library you prefer is doing it. In the case of prepared statements, it's -impossible to manipulate the query as was demonstrated above. +Use prepared statements do PDO diretamente ou garanta que a biblioteca que +você prefere faça isso. Com prepared statements, é impossível manipular a +consulta como demonstrado acima. -If you use data to specify column names or table names, the best thing to do -is to allow only a predefined set of values: +Se você usa dados para especificar nomes de colunas ou de tabelas, o melhor +é permitir apenas um conjunto predefinido de valores: ```php function actionList($orderBy = null) @@ -95,188 +96,191 @@ function actionList($orderBy = null) } ``` -Further reading on the topic: +Leitura adicional sobre o assunto: - -## Avoiding XSS +## Evitando XSS -XSS or cross-site scripting happens when output isn't escaped properly when outputting HTML to the browser. For example, -if user can enter his name and instead of `Alexander` he enters ``, every page that -outputs username without escaping it will execute JavaScript `alert('Hello!');` resulting in alert box popping up -in a browser. Depending on the website instead of innocent alert, such a script could send messages using your name or even -perform bank transactions. +XSS, ou cross-site scripting, acontece quando a saída não é escapada corretamente ao enviar HTML para o navegador. Por exemplo, +se o usuário pode informar o nome dele e, em vez de `Alexander`, ele digita ``, toda página que +exibe o nome do usuário sem escapá-lo vai executar o JavaScript `alert('Hello!');`, fazendo uma caixa de alerta aparecer +no navegador. Dependendo do site, em vez de um alerta inofensivo, um script assim poderia enviar mensagens em seu nome ou até +fazer transações bancárias. -Avoiding XSS is quite easy in Yii. There are two cases: +Evitar XSS no Yii é bem fácil. Há dois casos: -1. You want to output data as plain text. -2. You want to output data as HTML. +1. Você quer exibir os dados como texto puro. +2. Você quer exibir os dados como HTML. -If all you need is plain text, then escaping is as easy as the following: +Se tudo o que você precisa é de texto puro, escapar é tão simples quanto o +seguinte: ```php ``` -If it should be HTML, you could get some help from -[HtmlPurifier](http://htmlpurifier.org/). Note that HtmlPurifier processing -is quite heavy, so consider adding caching. +Se precisar ser HTML, você pode ter a ajuda do +[HtmlPurifier](http://htmlpurifier.org/). Note que o processamento do +HtmlPurifier é bem pesado, então considere usar cache. -Further reading on the topic: +Leitura adicional sobre o assunto: - -## Avoiding CSRF +## Evitando CSRF -CSRF is an abbreviation for cross-site request forgery. The idea is that -many applications assume that requests coming from a user browser are made -by the user themselves. This assumption could be false. +CSRF é a sigla de cross-site request forgery (falsificação de requisição +entre sites). A ideia é que muitas aplicações assumem que as requisições +vindas do navegador de um usuário são feitas pelo próprio usuário. Essa +suposição pode ser falsa. -For example, the website `an.example.com` has a `/logout` URL that, when accessed using a simple GET request, logs the user out. As long -as it's requested by the user themselves everything is OK, but one day bad guys are somehow posting -`` on a forum the user often visits. The browser doesn't make any difference between -requesting an image or requesting a page so when the user opens a page with such a manipulated `` tag, -the browser will send the GET request to that URL and the user will be logged out from `an.example.com`. +Por exemplo, o site `an.example.com` tem uma URL `/logout` que, quando acessada com uma simples requisição GET, faz o logout do usuário. Enquanto +for o próprio usuário que faz a requisição, está tudo certo, mas um dia alguém mal-intencionado consegue publicar +`` em um fórum que o usuário visita com frequência. O navegador não faz diferença entre +requisitar uma imagem e requisitar uma página, então, quando o usuário abre uma página com essa tag `` manipulada, +o navegador envia a requisição GET para aquela URL e o usuário é deslogado de `an.example.com`. -That's the basic idea of how a CSRF attack works. One can say that logging out a user isn't a serious thing. -However, this was just an example. -There are many more things one could do using this approach. -For example, triggering payments or changing data. Imagine that some website has a URL -`http://an.example.com/purse/transfer?to=anotherUser&amount=2000`. Accessing it using GET request, causes transfer of $2000 -from an authorized user account to user `anotherUser`. -You know that the browser will always send a GET request to load an image, -so you can change the code to accept only POST requests on that URL. -Unfortunately, this won't save you, because an attacker -can put some JavaScript code instead of `` tag, which allows sending POST requests to that URL as well. +Essa é a ideia básica de como um ataque CSRF funciona. Alguém pode dizer que deslogar um usuário não é grave. +Porém, isso foi só um exemplo. +Há muito mais coisas que se pode fazer com essa abordagem. +Por exemplo, disparar pagamentos ou alterar dados. Imagine que um site tem uma URL +`http://an.example.com/purse/transfer?to=anotherUser&amount=2000`. Acessá-la com uma requisição GET causa a transferência de $2000 +da conta de um usuário autorizado para o usuário `anotherUser`. +Você sabe que o navegador sempre envia uma requisição GET para carregar uma imagem, +então pode alterar o código para aceitar apenas requisições POST nessa URL. +Infelizmente, isso não vai salvar você, porque um atacante +pode colocar algum código JavaScript no lugar da tag ``, o que permite enviar requisições POST para essa URL também. -For this reason, Yii applies extra mechanisms to protect against CSRF -attacks. +Por isso, o Yii aplica mecanismos extras para proteger contra ataques CSRF. -To avoid CSRF, you should always: +Para evitar CSRF, você deve sempre: -1. Follow HTTP specification. GET shouldn't change the application state. - See [RFC2616](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html) for - more details. -2. Keep Yii CSRF protection enabled. +1. Seguir a especificação HTTP. GET não deve alterar o estado da aplicação. + Veja a [RFC2616](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html) + para mais detalhes. +2. Manter a proteção CSRF do Yii ativada. -Yii has CSRF protection via `Yiisoft\Csrf\CsrfTokenMiddleware` from the -[`yiisoft/csrf`](https://github.com/yiisoft/csrf) package. Make sure it's -in your application middleware stack. For AJAX/SPA backends that use -cookie-based authentication, the same package provides -`Yiisoft\Csrf\CsrfHeaderMiddleware` — an alternative approach that relies on -custom request headers and the CORS preflight mechanism instead of -token-in-form. +O Yii tem proteção CSRF via `Yiisoft\Csrf\CsrfTokenMiddleware`, do pacote +[`yiisoft/csrf`](https://github.com/yiisoft/csrf). Garanta que ele esteja +na pilha de middlewares da sua aplicação. Para backends AJAX/SPA que usam +autenticação baseada em cookie, o mesmo pacote fornece o +`Yiisoft\Csrf\CsrfHeaderMiddleware`, uma abordagem alternativa que depende +de headers de requisição personalizados e do mecanismo de preflight do CORS +em vez de um token no formulário. -Further reading on the topic: +Leitura adicional sobre o assunto: - - -## Avoiding file exposure +## Evitando a exposição de arquivos -By default, server webroot is meant to be pointed to `public` directory where `index.php` is. In the case of shared hosting - environments, it could be impossible to achieve, so you'll end up with all the code, configs and logs in server webroot. +Por padrão, o webroot do servidor deve apontar para o diretório `public`, onde fica o `index.php`. Em ambientes de hospedagem + compartilhada, isso pode ser impossível, e você acaba com todo o código, as configurações e os logs no webroot do servidor. -If so, remember to deny access to everything except `web`. If it's -impossible, consider hosting your application elsewhere. +Nesse caso, lembre-se de negar o acesso a tudo, exceto `web`. Se isso for +impossível, considere hospedar sua aplicação em outro lugar. -## Avoiding debug info and tools in production +## Evitando informações e ferramentas de debug em produção -In debug mode, Yii shows quite verbose errors which are certainly helpful -for development. The thing is that these verbose errors are handy for -attacker as well since these could reveal database structure, configuration -values and parts of your code. +No modo debug, o Yii mostra erros bem detalhados, que certamente ajudam no +desenvolvimento. O problema é que esses erros detalhados também são úteis +para um atacante, já que podem revelar a estrutura do banco de dados, +valores de configuração e partes do seu código. -Never run production applications with debugger or Gii accessible to -everyone. One could use it to get information about database structure, -code and to simply rewrite code with what's generated by Gii. +Nunca rode aplicações em produção com o debugger ou o Gii acessíveis a +todos. Alguém poderia usá-los para obter informações sobre a estrutura do +banco de dados e o código, ou simplesmente reescrever o código com o que o +Gii gera. -You should avoid the debug toolbar in production unless necessary. It -exposes all the application and config details possible. If you absolutely -need it, check twice you restrict access to your IP only. +Evite a barra de debug em produção, a menos que seja necessário. Ela expõe +todos os detalhes possíveis da aplicação e da configuração. Se você +realmente precisar dela, confira duas vezes se o acesso está restrito apenas +ao seu IP. -Further reading on the topic: +Leitura adicional sobre o assunto: - - -## Using secure connection over TLS +## Usando conexão segura via TLS -Yii provides features that rely on cookies and/or PHP sessions. These can be -vulnerable in case your connection is compromised. The risk is reduced if -the app uses secure connection via TLS (often referred to as +O Yii fornece recursos que dependem de cookies e/ou sessões do PHP. Eles +podem ficar vulneráveis caso sua conexão seja comprometida. O risco diminui +se a aplicação usar conexão segura via TLS (muitas vezes chamado de [SSL](https://en.wikipedia.org/wiki/Transport_Layer_Security)). -Nowadays, anyone can get a certificate for free and automatically update it -thanks to [Let's Encrypt](https://letsencrypt.org/). +Hoje em dia, qualquer pessoa pode obter um certificado de graça e renová-lo +automaticamente graças ao [Let's Encrypt](https://letsencrypt.org/). -## Secure server configuration +## Configuração segura do servidor -The purpose of this section is to highlight risks that need to be considered -when creating a server configuration for serving a Yii-based -website. Besides the points covered here, there may be other -security-related configuration options to be considered, so don't consider -this section to be complete. +O objetivo desta seção é destacar os riscos que precisam ser considerados ao +criar a configuração de um servidor para servir um site baseado em Yii. Além +dos pontos tratados aqui, pode haver outras opções de configuração +relacionadas à segurança a considerar, então não considere esta seção +completa. -### Avoiding `Host`-header attacks +### Evitando ataques via header `Host` -If the webserver is configured to serve the same site independent of the -value of the `Host` header, this information mayn't be reliable and [may be -faked by the user sending the HTTP -request](https://www.acunetix.com/vulnerabilities/web/host-header-attack). -In such situations, you should fix your webserver configuration to serve the -site only for specified host names. +Se o servidor web estiver configurado para servir o mesmo site +independentemente do valor do header `Host`, essa informação pode não ser +confiável e [pode ser falsificada pelo usuário que envia a requisição +HTTP](https://www.acunetix.com/vulnerabilities/web/host-header-attack). +Nessas situações, você deve corrigir a configuração do servidor web para +servir o site apenas para os nomes de host especificados. -For more information about the server configuration, please refer to the -documentation of your webserver: +Para mais informações sobre a configuração do servidor, consulte a +documentação do seu servidor web: - Apache 2: - Nginx: -### Configuring SSL peer validation +### Configurando a validação SSL do peer -There is a typical misconception about how to solve SSL certificate -validation issues such as: +Há um equívoco comum sobre como resolver problemas de validação de +certificado SSL, como: ``` cURL error 60: SSL certificate problem: unable to get local issuer certificate ``` -or +ou ``` stream_socket_enable_crypto(): SSL operation failed with code 1. OpenSSL Error messages: error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed ``` -Many sources wrongly suggest disabling SSL peer verification. That -shouldn't be ever done since it enables man-in-the middle type of attacks. -Instead, PHP should be configured properly: +Muitas fontes sugerem, erroneamente, desativar a verificação SSL do peer. +Isso nunca deve ser feito, porque abre caminho para ataques do tipo +man-in-the-middle. Em vez disso, o PHP deve ser configurado corretamente: -1. Download +1. Baixe [https://curl.haxx.se/ca/cacert.pem](https://curl.haxx.se/ca/cacert.pem). -2. Add the following to your php.ini: +2. Adicione o seguinte ao seu php.ini: ``` openssl.cafile="/path/to/cacert.pem" curl.cainfo="/path/to/cacert.pem". ``` -Note that you should keep the file up to date. +Note que você deve manter o arquivo atualizado. -## References +## Referências - [OWASP top 10](https://owasp.org/Top10/) - [The Basics of Web Application - Security](https://martinfowler.com/articles/web-security-basics.html) by + Security](https://martinfowler.com/articles/web-security-basics.html), de Martin Fowler -- [PHP manual: security](https://www.php.net/manual/en/security.php) -- [Information security at - STackExchange](https://security.stackexchange.com/) +- [Manual do PHP: segurança](https://www.php.net/manual/en/security.php) +- [Segurança da informação no + StackExchange](https://security.stackexchange.com/) diff --git a/src/pt-BR/guide/security/cryptography.md b/src/pt-BR/guide/security/cryptography.md index 4b596bab..f2542d3d 100644 --- a/src/pt-BR/guide/security/cryptography.md +++ b/src/pt-BR/guide/security/cryptography.md @@ -1,90 +1,90 @@ -# Cryptography +# Criptografia -In this section, we'll review the following security aspects: +Nesta seção, vamos ver os seguintes aspectos de segurança: -- Generating random data -- Encryption and Decryption -- Confirming Data Integrity +- Geração de dados aleatórios +- Cifrar e decifrar dados +- Confirmação da integridade dos dados -To use these features, you need to install `yiisoft/security` package: +Para usar esses recursos, você precisa instalar o pacote `yiisoft/security`: ``` composer install yiisoft/security ``` -## Generating pseudorandom data +## Geração de dados pseudoaleatórios -Pseudorandom data are useful in many situations. For example, when resetting -a password via email, you need to generate a token, save it to the database, -and send it via email to the end user, which in turn will allow them to -prove ownership of that account. It's important that this token be unique -and hard to guess, else there is a possibility that an attacker can predict -the token's value and reset the user's password. +Dados pseudoaleatórios são úteis em muitas situações. Por exemplo, ao +redefinir uma senha por e-mail, você precisa gerar um token, salvá-lo no +banco de dados e enviá-lo por e-mail ao usuário final, o que permite a ele +provar que é o dono daquela conta. É importante que esse token seja único e +difícil de adivinhar; caso contrário, existe a possibilidade de um atacante +prever o valor do token e redefinir a senha do usuário. -`\Yiisoft\Security\Random` makes generating pseudorandom data simple: +`\Yiisoft\Security\Random` torna simples gerar dados pseudoaleatórios: ```php $key = \Yiisoft\Security\Random::string(42); ``` -The code above would give you a random string consisting of 42 characters. +O código acima gera uma string aleatória com 42 caracteres. -If you need bytes or integers, use PHP functions directly: +Se você precisar de bytes ou inteiros, use as funções do PHP diretamente: -- `random_bytes()` for bytes. Note that the output may not be ASCII. -- `random_int()` for integers. +- `random_bytes()` para bytes. Note que a saída pode não ser ASCII. +- `random_int()` para inteiros. -## Encryption and decryption +## Cifrar e decifrar dados -Yii provides convenient helper functions to encrypt/decrypt data using a -secret key. The data is passed through the encryption function so that only -the person who has the secret key will be able to decrypt it. For example, -you need to store some information in your database, but you need to make -sure only the user who has the secret key can view it (even if one -compromises the application database): +O Yii fornece funções auxiliares práticas para cifrar e decifrar dados +usando uma chave secreta. Os dados passam pela função de cifragem de modo +que apenas quem tem a chave secreta consiga decifrá-los. Por exemplo, você +precisa armazenar alguma informação no banco de dados, mas precisa garantir +que apenas o usuário que tem a chave secreta possa vê-la (mesmo que alguém +comprometa o banco de dados da aplicação): ```php $encryptedData = (new \Yiisoft\Security\Crypt())->encryptByPassword($data, $password); -// save data to a database or another storage +// salve os dados em um banco de dados ou outro armazenamento saveData($encryptedData); ``` -Decrypting it: +Para decifrar: ```php -// collect encrypted data from a database or another storage +// obtenha os dados cifrados de um banco de dados ou outro armazenamento $encryptedData = getEncryptedData(); $data = (new \Yiisoft\Security\Crypt())->decryptByPassword($encryptedData, $password); ``` -You could use a key instead of a password: +Você pode usar uma chave em vez de uma senha: ```php $encryptedData = (new \Yiisoft\Security\Crypt())->encryptByKey($data, $key); -// save data to a database or another storage +// salve os dados em um banco de dados ou outro armazenamento saveData($encryptedData); ``` -Decrypting it: +Para decifrar: ```php -// collect encrypted data from a database or another storage +// obtenha os dados cifrados de um banco de dados ou outro armazenamento $encryptedData = getEncryptedData(); $data = (new \Yiisoft\Security\Crypt())->decryptByKey($encryptedData, $key); ``` -## Confirming data integrity +## Confirmação da integridade dos dados -There are situations in which you need to verify that your data hasn't been -tampered with by a third party or even corrupted in some way. Yii provides a -way to confirm data integrity by MAC signing. +Há situações em que você precisa verificar se seus dados não foram +adulterados por terceiros ou até corrompidos de alguma forma. O Yii oferece +uma maneira de confirmar a integridade dos dados por meio de assinatura MAC. -The `$key` should be present at both sending and receiving sides. On the -sending side: +A `$key` deve estar presente tanto no lado que envia quanto no que +recebe. No lado que envia: ```php $signedMessage = (new \Yiisoft\Security\Mac())->sign($message, $key); @@ -92,7 +92,7 @@ $signedMessage = (new \Yiisoft\Security\Mac())->sign($message, $key); sendMessage($signedMessage); ``` -On the receiving side: +No lado que recebe: ```php $signedMessage = receiveMessage($signedMessage); @@ -100,23 +100,23 @@ $signedMessage = receiveMessage($signedMessage); try { $message = (new \Yiisoft\Security\Mac())->getMessage($signedMessage, $key); } catch (\Yiisoft\Security\DataIsTamperedException $e) { - // data is tampered + // os dados foram adulterados } ``` -## Masking token length +## Mascaramento do comprimento do token -Masking a token helps to mitigate a BREACH attack by randomizing how the -token outputted on each request. A random mask is applied to the token, -making the string always unique. +Mascarar um token ajuda a mitigar um ataque BREACH, tornando aleatória a +forma como o token é exibido em cada requisição. Uma máscara aleatória é +aplicada ao token, fazendo com que a string seja sempre única. -To mask a token: +Para mascarar um token: ```php $maskedToken = \Yiisoft\Security\TokenMask::apply($token); ``` -To get the original value from the masked one: +Para obter o valor original a partir do mascarado: ```php $token = \Yiisoft\Security\TokenMask::remove($maskedToken); diff --git a/src/pt-BR/guide/security/overview.md b/src/pt-BR/guide/security/overview.md index 807b6468..d37ea2ec 100644 --- a/src/pt-BR/guide/security/overview.md +++ b/src/pt-BR/guide/security/overview.md @@ -1,19 +1,19 @@ # Segurança -Good security is vital to the health and success of any -application. Unfortunately, many developers cut corners when it comes to -security, either due to a lack of understanding or because implementation is -too much of a hurdle. To make your Yii-powered application as secure as -possible, Yii has included several excellent and easy-to-use security -features. +Uma boa segurança é vital para a saúde e o sucesso de qualquer +aplicação. Infelizmente, muitos desenvolvedores negligenciam a segurança, +seja por falta de entendimento, seja porque a implementação parece um +obstáculo grande demais. Para deixar sua aplicação Yii o mais segura +possível, o Yii inclui vários recursos de segurança excelentes e fáceis de +usar. -* [Authentication](authentication.md) -* [Authorization](authorization.md) -* [Working with Passwords](passwords.md) -* [Cryptography](cryptography.md) -* [Best Practices](best-practices.md) -* [Trusted request](trusted-request.md) +* [Autenticação](authentication.md) +* [Autorização](authorization.md) +* [Trabalhando com senhas](passwords.md) +* [Criptografia](cryptography.md) +* [Boas práticas](best-practices.md) +* [Requisição confiável](trusted-request.md) -See also: +Veja também: -* [Views security](../views/view.md#security) +* [Segurança de views](../views/view.md#security) diff --git a/src/pt-BR/guide/security/passwords.md b/src/pt-BR/guide/security/passwords.md index 2e112d77..57ab89c8 100644 --- a/src/pt-BR/guide/security/passwords.md +++ b/src/pt-BR/guide/security/passwords.md @@ -1,45 +1,45 @@ -# Working with passwords +# Trabalhando com senhas -Most developers know that passwords can't be stored in plain text, but many -developers believe it's still safe to hash passwords using `md5`, `sha1` or -`sha256` etc. There was a time when using the aforementioned hashing -algorithms was enough, but modern hardware makes it possible to reverse such -hashes and even stronger ones using brute force attacks. +A maioria dos desenvolvedores sabe que senhas não podem ser armazenadas em +texto puro, mas muitos ainda acreditam que é seguro gerar o hash de senhas +com `md5`, `sha1`, `sha256` etc. Houve um tempo em que esses algoritmos de +hash bastavam, mas o hardware moderno permite reverter esses hashes, e até +outros mais fortes, com ataques de força bruta. -To offer increased security for user passwords, even in the worst case -scenario (when one breaches your application), you need to use a hashing -algorithm that's resilient against brute force attacks. The best current -choice is `argon2`. Yii `yiisoft/security` package make securely generate -and verify hashes easier and ensure the best possible hashing solution used. +Para oferecer mais segurança às senhas dos usuários, mesmo no pior cenário +(quando alguém invade sua aplicação), você precisa usar um algoritmo de hash +resistente a ataques de força bruta. A melhor escolha atual é o `argon2`. +O pacote `yiisoft/security` do Yii facilita gerar e verificar hashes com +segurança e garante que a melhor solução de hash possível seja usada. -To use it, you need to require the package first: +Para usá-lo, primeiro instale o pacote: ``` composer require yiisoft/security ``` -When a user provides a password for the first time (e.g., upon -registration), the password needs to be hashed and stored: +Quando um usuário fornece uma senha pela primeira vez (por exemplo, no +cadastro), é preciso gerar o hash da senha e armazená-lo: ```php $hash = (new PasswordHasher())->hash($password); -// save hash to a database or another storage +// salve o hash em um banco de dados ou outro armazenamento saveHash($hash); ``` -When a user attempts to log in, the submitted password must be verified -against the previously hashed and stored password: +Quando um usuário tenta fazer login, a senha enviada deve ser verificada +contra o hash armazenado anteriormente: ```php -// get hash from a database or another storage +// obtenha o hash de um banco de dados ou outro armazenamento $hash = getHash(); if ((new PasswordHasher())->validate($password, $hash)) { - // all good, logging in user + // tudo certo, fazendo login do usuário } else { - // wrong password + // senha incorreta } ``` diff --git a/src/pt-BR/guide/security/trusted-request.md b/src/pt-BR/guide/security/trusted-request.md index 29ff339a..fc6a0e46 100644 --- a/src/pt-BR/guide/security/trusted-request.md +++ b/src/pt-BR/guide/security/trusted-request.md @@ -1,30 +1,31 @@ -# Trusted request +# Requisição confiável -Getting user information, like a host and IP address, will work out of the -box in a normal setup where a single webserver is used to serve the -website. If your Yii application, however, runs behind a reverse proxy, you -need to add configuration to retrieve this information as the direct client -is now the proxy, and the user IP address is passed to the Yii application -by a header set by the proxy. +Obter informações do usuário, como host e endereço IP, funciona de imediato +em uma configuração normal, em que um único servidor web atende o +site. Porém, se sua aplicação Yii roda atrás de um proxy reverso, você +precisa adicionar configuração para obter essas informações, já que o +cliente direto passa a ser o proxy e o endereço IP do usuário é repassado +para a aplicação Yii por um header definido pelo proxy. -You shouldn't blindly trust headers provided by proxies unless you -explicitly trust the proxy. Yii supports configuring trusted proxies via -the `Yiisoft\Yii\Web\Middleware\TrustedHostsNetworkResolver`. You should -add it to [middleware stack](../structure/middleware.md). +Você não deve confiar cegamente nos headers fornecidos por proxies, a menos +que confie explicitamente no proxy. O Yii permite configurar proxies +confiáveis via `Yiisoft\Yii\Web\Middleware\TrustedHostsNetworkResolver`. +Você deve adicioná-lo à [pilha de middlewares](../structure/middleware.md). -The following is a request config for an application that runs behind an -array of reverse proxies, which are located in the `10.0.2.0/24` IP network: +A seguir está uma configuração de requisição para uma aplicação que roda +atrás de um conjunto de proxies reversos localizados na rede IP +`10.0.2.0/24`: ```php /** @var \Yiisoft\Yii\Web\Middleware\TrustedHostsNetworkResolver $trustedHostsNetworkResolver */ $trustedHostsNetworkResolver = $trustedHostsNetworkResolver->withAddedTrustedHosts(['1.0.2.0/24']); ``` -The proxy sends the IP in the `X-Forwarded-For` header by default, and the -protocol (`http` or `https`) is in `X-Forwarded-Proto`. +Por padrão, o proxy envia o IP no header `X-Forwarded-For` e o protocolo +(`http` ou `https`) em `X-Forwarded-Proto`. -In case your proxies are using different headers, you can use the request -configuration to adjust these, e.g.: +Caso seus proxies usem headers diferentes, você pode ajustá-los na +configuração da requisição, por exemplo: ```php /** @var \Yiisoft\Yii\Web\Middleware\TrustedHostsNetworkResolver $trustedHostsNetworkResolver */ @@ -39,5 +40,5 @@ $trustedHostsNetworkResolver = $trustedHostsNetworkResolver ); ``` -With the above configuration, `X-ProxyUser-Ip` and `Front-End-Https` headers -are used to get user IP and protocol. +Com a configuração acima, os headers `X-ProxyUser-Ip` e `Front-End-Https` +são usados para obter o IP e o protocolo do usuário. From 307aa1d322be45c5a35b56966bf17c988d62e670 Mon Sep 17 00:00:00 2001 From: Yuri Neves Date: Fri, 23 Oct 2026 14:18:14 -0300 Subject: [PATCH 06/11] Translate guide views, testing, tutorials and glossary to Brazilian Portuguese --- _translations/po/pt-BR/guide_glossary.md.po | 194 ++--- .../po/pt-BR/guide_testing_end-to-end.md.po | 115 ++- .../guide_testing_environment-setup.md.po | 168 ++-- .../po/pt-BR/guide_testing_functional.md.po | 112 ++- .../po/pt-BR/guide_testing_overview.md.po | 85 +- .../pt-BR/guide_testing_quality-tools.md.po | 82 +- .../po/pt-BR/guide_testing_unit.md.po | 183 ++++- .../guide_tutorial_console-applications.md.po | 80 +- .../po/pt-BR/guide_tutorial_docker.md.po | 367 +++++++-- .../po/pt-BR/guide_tutorial_i18n.md.po | 364 +++++++-- .../po/pt-BR/guide_tutorial_mailing.md.po | 286 +++++-- .../guide_tutorial_performance-tuning.md.po | 130 ++-- ...guide_tutorial_using-with-event-loop.md.po | 55 +- ...e_tutorial_using-yii-with-frankenphp.md.po | 204 +++-- ...guide_tutorial_using-yii-with-rapira.md.po | 142 ++-- ...e_tutorial_using-yii-with-roadrunner.md.po | 172 +++-- ...guide_tutorial_using-yii-with-swoole.md.po | 161 +++- .../po/pt-BR/guide_views_asset.md.po | 614 +++++++++++++-- .../pt-BR/guide_views_script-style-meta.md.po | 460 +++++++++-- .../pt-BR/guide_views_template-engines.md.po | 183 ++++- .../pt-BR/guide_views_view-injections.md.po | 95 ++- _translations/po/pt-BR/guide_views_view.md.po | 228 +++++- .../po/pt-BR/guide_views_widget.md.po | 727 ++++++++++++++++-- src/pt-BR/guide/glossary.md | 253 +++--- src/pt-BR/guide/testing/end-to-end.md | 57 +- src/pt-BR/guide/testing/environment-setup.md | 103 +-- src/pt-BR/guide/testing/functional.md | 38 +- src/pt-BR/guide/testing/overview.md | 66 +- src/pt-BR/guide/testing/quality-tools.md | 61 +- src/pt-BR/guide/testing/unit.md | 42 +- .../guide/tutorial/console-applications.md | 41 +- src/pt-BR/guide/tutorial/docker.md | 351 ++++----- src/pt-BR/guide/tutorial/i18n.md | 180 ++--- src/pt-BR/guide/tutorial/mailing.md | 259 ++++--- .../guide/tutorial/performance-tuning.md | 311 ++++---- .../guide/tutorial/using-with-event-loop.md | 65 +- .../tutorial/using-yii-with-frankenphp.md | 165 ++-- .../guide/tutorial/using-yii-with-rapira.md | 125 +-- .../tutorial/using-yii-with-roadrunner.md | 84 +- .../guide/tutorial/using-yii-with-swoole.md | 88 +-- src/pt-BR/guide/views/asset.md | 300 ++++---- src/pt-BR/guide/views/script-style-meta.md | 224 +++--- src/pt-BR/guide/views/template-engines.md | 119 +-- src/pt-BR/guide/views/view-injections.md | 50 +- src/pt-BR/guide/views/view.md | 141 ++-- src/pt-BR/guide/views/widget.md | 138 ++-- 46 files changed, 5769 insertions(+), 2699 deletions(-) diff --git a/_translations/po/pt-BR/guide_glossary.md.po b/_translations/po/pt-BR/guide_glossary.md.po index 46a1927c..9e1c6149 100644 --- a/_translations/po/pt-BR/guide_glossary.md.po +++ b/_translations/po/pt-BR/guide_glossary.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-05-30 06:43+0000\n" "PO-Revision-Date: 2026-05-30 06:43+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,529 +19,529 @@ msgstr "" #: ../src/guide/glossary.md #, no-wrap msgid "A" -msgstr "" +msgstr "A" #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "action" -msgstr "" +msgstr "action" #. type: Plain text #: ../src/guide/glossary.md msgid "Action is a callable, class, or class method that handles a matched route and returns a response. Read more in [\"Actions\"](structure/action.md)." -msgstr "" +msgstr "Action é um callable, uma classe ou um método de classe que trata uma rota correspondida e retorna uma resposta. Leia mais em [\"Actions\"](structure/action.md)." #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "alias" -msgstr "" +msgstr "alias" #. type: Plain text #: ../src/guide/glossary.md msgid "Alias is a string used by Yii to refer to the class or directory such as `@app/vendor`. Read more in [\"Aliases\"](concept/aliases.md)." -msgstr "" +msgstr "Alias é uma string usada pelo Yii para se referir a uma classe ou a um diretório, como `@app/vendor`. Leia mais em [\"Aliases\"](concept/aliases.md)." #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "application" -msgstr "" +msgstr "aplicação" #. type: Plain text #: ../src/guide/glossary.md msgid "Application is an object that starts up, handles a request through configured middleware, and shuts down. Read more in [\"Application\"](structure/application.md)." -msgstr "" +msgstr "A aplicação é um objeto que inicializa, trata uma requisição passando pelos middlewares configurados e encerra. Leia mais em [\"Aplicação\"](structure/application.md)." #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "asset" -msgstr "" +msgstr "asset" #. type: Plain text #: ../src/guide/glossary.md msgid "Asset refers to a resource file. Typically, it contains JavaScript or CSS code but can be any static content accessed via HTTP. Read more in [\"Assets\"](views/asset.md)." -msgstr "" +msgstr "Asset é um arquivo de recurso. Normalmente contém código JavaScript ou CSS, mas pode ser qualquer conteúdo estático acessado via HTTP. Leia mais em [\"Assets\"](views/asset.md)." #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "asset bundle" -msgstr "" +msgstr "asset bundle" #. type: Plain text #: ../src/guide/glossary.md msgid "Asset bundle is a PHP class that declares a group of CSS, JavaScript, image, or font files that should be published and registered together. Read more in [\"Asset Bundles\"](views/asset.md#asset-bundles)." -msgstr "" +msgstr "Asset bundle é uma classe PHP que declara um grupo de arquivos CSS, JavaScript, imagens ou fontes que devem ser publicados e registrados juntos. Leia mais em [\"Asset bundles\"](views/asset.md#asset-bundles)." #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "authentication" -msgstr "" +msgstr "autenticação" #. type: Plain text #: ../src/guide/glossary.md msgid "Authentication is the process of determining the identity of the current user. Read more in [\"Authentication\"](security/authentication.md)." -msgstr "" +msgstr "Autenticação é o processo de determinar a identidade do usuário atual. Leia mais em [\"Autenticação\"](security/authentication.md)." #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "authorization" -msgstr "" +msgstr "autorização" #. type: Plain text #: ../src/guide/glossary.md msgid "Authorization is the process of checking whether an authenticated or anonymous user is allowed to perform an action. Read more in [\"Authorization\"](security/authorization.md)." -msgstr "" +msgstr "Autorização é o processo de verificar se um usuário autenticado ou anônimo tem permissão para realizar uma ação. Leia mais em [\"Autorização\"](security/authorization.md)." #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "autoloading" -msgstr "" +msgstr "autoloading" #. type: Plain text #: ../src/guide/glossary.md msgid "Autoloading is the process of loading PHP classes automatically when they are first used. Read more in [\"Class autoloading\"](concept/autoloading.md)." -msgstr "" +msgstr "Autoloading é o processo de carregar classes PHP automaticamente quando elas são usadas pela primeira vez. Leia mais em [\"Autoloading de classes\"](concept/autoloading.md)." #. type: Title # #: ../src/guide/glossary.md #, no-wrap msgid "B" -msgstr "" +msgstr "B" #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "bootstrap" -msgstr "" +msgstr "bootstrap" #. type: Plain text #: ../src/guide/glossary.md msgid "Bootstrap is application startup code that prepares services, configuration, and runtime state before request handling. Read more in [\"Configuration\"](concept/configuration.md)." -msgstr "" +msgstr "Bootstrap é o código de inicialização da aplicação que prepara serviços, configuração e estado de execução antes do tratamento da requisição. Leia mais em [\"Configuração\"](concept/configuration.md)." #. type: Title # #: ../src/guide/glossary.md #, no-wrap msgid "C" -msgstr "" +msgstr "C" #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "configuration" -msgstr "" +msgstr "configuração" #. type: Plain text #: ../src/guide/glossary.md msgid "Configuration may refer either to the process of setting properties of an object or to a configuration file that stores settings for an object, or a class of objects. Read more in [\"Configuration\"](concept/configuration.md)." -msgstr "" +msgstr "Configuração pode se referir tanto ao processo de definir propriedades de um objeto quanto a um arquivo de configuração que guarda definições para um objeto ou uma classe de objetos. Leia mais em [\"Configuração\"](concept/configuration.md)." #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "container" -msgstr "" +msgstr "container" #. type: Plain text #: ../src/guide/glossary.md msgid "Container is an object that creates services, resolves their dependencies, and returns configured instances. Read more in [\"DI container\"](concept/di-container.md#di-container)." -msgstr "" +msgstr "Container é um objeto que cria serviços, resolve suas dependências e retorna instâncias configuradas. Leia mais em [\"Container de DI\"](concept/di-container.md#container-de-di)." #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "controller" -msgstr "" +msgstr "controller" #. type: Plain text #: ../src/guide/glossary.md msgid "Controller is a class that groups action methods for related routes. Read more in [\"Actions\"](structure/action.md)." -msgstr "" +msgstr "Controller é uma classe que agrupa métodos de action de rotas relacionadas. Leia mais em [\"Actions\"](structure/action.md)." #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "cookie" -msgstr "" +msgstr "cookie" #. type: Plain text #: ../src/guide/glossary.md msgid "Cookie is a small piece of data stored by a browser and sent with later requests to the same site. Read more in [\"Cookies\"](runtime/cookies.md)." -msgstr "" +msgstr "Cookie é um pequeno pedaço de dados guardado pelo navegador e enviado nas requisições seguintes ao mesmo site. Leia mais em [\"Cookies\"](runtime/cookies.md)." #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "CSRF" -msgstr "" +msgstr "CSRF" #. type: Plain text #: ../src/guide/glossary.md msgid "CSRF means cross-site request forgery, an attack where another site tries to make a user's browser submit an unwanted request to your application. Read more in [\"Avoiding CSRF\"](security/best-practices.md#avoiding-csrf)." -msgstr "" +msgstr "CSRF significa cross-site request forgery (falsificação de requisição entre sites), um ataque em que outro site tenta fazer o navegador de um usuário enviar uma requisição indesejada para sua aplicação. Leia mais em [\"Evitando CSRF\"](security/best-practices.md#evitando-csrf)." #. type: Title # #: ../src/guide/glossary.md #, no-wrap msgid "D" -msgstr "" +msgstr "D" #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "DI" -msgstr "" +msgstr "DI" #. type: Plain text #: ../src/guide/glossary.md msgid "Dependency injection is a programming technique where an object receives its dependencies from the outside. Read more in [\"Dependency injection and container\"](concept/di-container.md)." -msgstr "" +msgstr "Injeção de dependência é uma técnica de programação em que um objeto recebe suas dependências de fora. Leia mais em [\"Injeção de dependência e container\"](concept/di-container.md)." #. type: Title # #: ../src/guide/glossary.md #, no-wrap msgid "E" -msgstr "" +msgstr "E" #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "entry script" -msgstr "" +msgstr "entry script (script de entrada)" #. type: Plain text #: ../src/guide/glossary.md msgid "Entry script is the first PHP script executed for a web or console application. Read more in [\"Entry scripts\"](structure/entry-script.md)." -msgstr "" +msgstr "O script de entrada é o primeiro script PHP executado em uma aplicação web ou de console. Leia mais em [\"Scripts de entrada\"](structure/entry-script.md)." #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "event" -msgstr "" +msgstr "evento" #. type: Plain text #: ../src/guide/glossary.md msgid "Event is an object that represents something that happened and can be passed to listeners. Read more in [\"Events\"](concept/events.md)." -msgstr "" +msgstr "Evento é um objeto que representa algo que aconteceu e que pode ser passado para listeners. Leia mais em [\"Eventos\"](concept/events.md)." #. type: Title # #: ../src/guide/glossary.md #, no-wrap msgid "H" -msgstr "" +msgstr "H" #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "handler" -msgstr "" +msgstr "handler" #. type: Plain text #: ../src/guide/glossary.md msgid "Handler is callable code selected by routing or middleware to process a request and produce a response. Read more in [\"Routing and URL generation\"](runtime/routing.md)." -msgstr "" +msgstr "Handler é o código callable escolhido pelo roteamento ou por um middleware para processar uma requisição e produzir uma resposta. Leia mais em [\"Roteamento e geração de URLs\"](runtime/routing.md)." #. type: Title # #: ../src/guide/glossary.md #, no-wrap msgid "I" -msgstr "" +msgstr "I" #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "installation" -msgstr "" +msgstr "instalação" #. type: Plain text #: ../src/guide/glossary.md msgid "Installation is a process of preparing something to work either by following a readme file or by executing a specially prepared script. In the case of Yii, it's setting permissions and fulfilling software requirements." -msgstr "" +msgstr "Instalação é o processo de preparar algo para funcionar, seja seguindo um arquivo readme, seja executando um script preparado especialmente para isso. No caso do Yii, é definir permissões e atender aos requisitos de software." #. type: Title # #: ../src/guide/glossary.md #, no-wrap msgid "L" -msgstr "" +msgstr "L" #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "layout" -msgstr "" +msgstr "layout" #. type: Plain text #: ../src/guide/glossary.md msgid "Layout is a view template that wraps page-specific content with shared page structure. Read more in [\"Working with layouts\"](views/view.md#working-with-layouts)." -msgstr "" +msgstr "Layout é um template de view que envolve o conteúdo específico de uma página com a estrutura compartilhada da página. Leia mais em [\"Trabalhando com layouts\"](views/view.md#trabalhando-com-layouts)." #. type: Title # #: ../src/guide/glossary.md #, no-wrap msgid "M" -msgstr "" +msgstr "M" #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "migration" -msgstr "" +msgstr "migration" #. type: Plain text #: ../src/guide/glossary.md msgid "Migration is a versioned PHP class that applies or reverts a database schema or data change. Read more in [\"Migrations\"](databases/db-migrations.md)." -msgstr "" +msgstr "Migration é uma classe PHP versionada que aplica ou reverte uma mudança no schema ou nos dados do banco de dados. Leia mais em [\"Migrations\"](databases/db-migrations.md)." #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "middleware" -msgstr "" +msgstr "middleware" #. type: Plain text #: ../src/guide/glossary.md msgid "Middleware is a processor in the request processing stack. Given a request, it may either produce a response or do some action and pass processing to the next middleware. Read more in [\"Middleware\"](structure/middleware.md)." -msgstr "" +msgstr "Middleware é um processador na pilha de processamento da requisição. Dada uma requisição, ele pode produzir uma resposta ou fazer alguma ação e passar o processamento para o próximo middleware. Leia mais em [\"Middleware\"](structure/middleware.md)." #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "model" -msgstr "" +msgstr "model" #. type: Plain text #: ../src/guide/glossary.md msgid "Model is an object that represents application data and usually contains validation or business rules for that data. Read more in [\"Working with forms\"](start/forms.md)." -msgstr "" +msgstr "Model é um objeto que representa dados da aplicação e normalmente contém regras de validação ou de negócio para esses dados. Leia mais em [\"Trabalhando com formulários\"](start/forms.md)." #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "module" -msgstr "" +msgstr "módulo" #. type: Plain text #: ../src/guide/glossary.md msgid "The module is a namespace that groups some code based on a use-case. It's typically used within the main application and may contain any source code, define additional URL handlers or console commands." -msgstr "" +msgstr "O módulo é um namespace que agrupa código com base em um caso de uso. Normalmente é usado dentro da aplicação principal e pode conter qualquer código-fonte, definir handlers de URL adicionais ou comandos de console." #. type: Title # #: ../src/guide/glossary.md #, no-wrap msgid "N" -msgstr "" +msgstr "N" #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "namespace" -msgstr "" +msgstr "namespace" #. type: Plain text #: ../src/guide/glossary.md msgid "Namespace refers to a [PHP language feature](https://www.php.net/manual/en/language.namespaces.php) to group multiple classes under a certain name." -msgstr "" +msgstr "Namespace é um [recurso da linguagem PHP](https://www.php.net/manual/en/language.namespaces.php) para agrupar várias classes sob um determinado nome." #. type: Title # #: ../src/guide/glossary.md #, no-wrap msgid "P" -msgstr "" +msgstr "P" #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "package" -msgstr "" +msgstr "pacote" #. type: Plain text #: ../src/guide/glossary.md msgid "A package usually refers to [Composer package](https://getcomposer.org/doc/). It's code ready for reuse and redistribution installable automatically via a package manager." -msgstr "" +msgstr "Um pacote normalmente é um [pacote do Composer](https://getcomposer.org/doc/). É código pronto para reutilização e redistribuição, que pode ser instalado automaticamente por um gerenciador de pacotes." #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "parameter" -msgstr "" +msgstr "parâmetro" #. type: Plain text #: ../src/guide/glossary.md msgid "Parameter is a configuration value that can be used by application or package config files. Read more in [\"Parameters\"](concept/configuration.md#parameters)." -msgstr "" +msgstr "Parâmetro é um valor de configuração que pode ser usado pelos arquivos de configuração da aplicação ou de pacotes. Leia mais em [\"Parâmetros\"](concept/configuration.md#parametros)." #. type: Title # #: ../src/guide/glossary.md #, no-wrap msgid "Q" -msgstr "" +msgstr "Q" #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "queue" -msgstr "" +msgstr "queue (fila)" #. type: Plain text #: ../src/guide/glossary.md msgid "A queue is a data structure that processes items in first-in, first-out order. Yii has a [yiisoft/queue](https://github.com/yiisoft/queue) package." -msgstr "" +msgstr "Uma fila é uma estrutura de dados que processa itens na ordem em que chegaram (primeiro a entrar, primeiro a sair). O Yii tem o pacote [yiisoft/queue](https://github.com/yiisoft/queue)." #. type: Title # #: ../src/guide/glossary.md #, no-wrap msgid "R" -msgstr "" +msgstr "R" #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "request" -msgstr "" +msgstr "requisição" #. type: Plain text #: ../src/guide/glossary.md msgid "Request is a PSR-7 object that represents an incoming HTTP message, including method, URI, headers, body, uploaded files, and attributes. Read more in [\"Request\"](runtime/request.md)." -msgstr "" +msgstr "Requisição é um objeto PSR-7 que representa uma mensagem HTTP recebida, incluindo método, URI, headers, corpo, arquivos enviados e atributos. Leia mais em [\"Requisição\"](runtime/request.md)." #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "response" -msgstr "" +msgstr "resposta" #. type: Plain text #: ../src/guide/glossary.md msgid "Response is a PSR-7 object that represents an outgoing HTTP message, including status code, headers, and body. Read more in [\"Response\"](runtime/response.md)." -msgstr "" +msgstr "Resposta é um objeto PSR-7 que representa uma mensagem HTTP enviada, incluindo código de status, headers e corpo. Leia mais em [\"Resposta\"](runtime/response.md)." #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "route" -msgstr "" +msgstr "rota" #. type: Plain text #: ../src/guide/glossary.md msgid "Route describes which request method and URL pattern should be handled by which action or middleware. Read more in [\"Routing and URL generation\"](runtime/routing.md)." -msgstr "" +msgstr "A rota descreve qual método de requisição e qual padrão de URL devem ser tratados por qual action ou middleware. Leia mais em [\"Roteamento e geração de URLs\"](runtime/routing.md)." #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "rule" -msgstr "" +msgstr "regra" #. type: Plain text #: ../src/guide/glossary.md msgid "The rule usually refers to a validation rule of the [yiisoft/validator](https://github.com/yiisoft/validator) package. It holds a set of parameters for checking if a data set is valid. \"Rule handler\" does the actual processing." -msgstr "" +msgstr "A regra normalmente se refere a uma regra de validação do pacote [yiisoft/validator](https://github.com/yiisoft/validator). Ela guarda um conjunto de parâmetros para verificar se um conjunto de dados é válido. O \"rule handler\" faz o processamento de fato." #. type: Title # #: ../src/guide/glossary.md #, no-wrap msgid "S" -msgstr "" +msgstr "S" #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "service" -msgstr "" +msgstr "serviço" #. type: Plain text #: ../src/guide/glossary.md msgid "Service is a focused object that performs application work or provides infrastructure behavior and is usually stored in the DI container. Read more in [\"Service components\"](structure/service.md)." -msgstr "" +msgstr "Serviço é um objeto focado que realiza trabalho da aplicação ou fornece comportamento de infraestrutura e normalmente fica registrado no container de DI. Leia mais em [\"Componentes de serviço\"](structure/service.md)." #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "service provider" -msgstr "" +msgstr "service provider (provedor de serviços)" #. type: Plain text #: ../src/guide/glossary.md msgid "Service provider is a class that registers related service definitions for the DI container. Read more in [\"Service providers\"](concept/configuration.md#service-providers)." -msgstr "" +msgstr "Service provider é uma classe que registra definições de serviços relacionados para o container de DI. Leia mais em [\"Service providers\"](concept/configuration.md#service-providers)." #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "session" -msgstr "" +msgstr "sessão" #. type: Plain text #: ../src/guide/glossary.md msgid "Session is server-side storage associated with a browser across multiple requests. Read more in [\"Sessions\"](runtime/sessions.md)." -msgstr "" +msgstr "Sessão é um armazenamento no servidor associado a um navegador ao longo de várias requisições. Leia mais em [\"Sessões\"](runtime/sessions.md)." #. type: Title # #: ../src/guide/glossary.md #, no-wrap msgid "T" -msgstr "" +msgstr "T" #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "template" -msgstr "" +msgstr "template" #. type: Plain text #: ../src/guide/glossary.md msgid "Template is a file used by a view or template engine to produce presentation output such as HTML. Read more in [\"Views\"](views/view.md)." -msgstr "" +msgstr "Template é um arquivo usado por uma view ou por um template engine para produzir a saída de apresentação, como HTML. Leia mais em [\"Views\"](views/view.md)." #. type: Title # #: ../src/guide/glossary.md #, no-wrap msgid "V" -msgstr "" +msgstr "V" #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "vendor" -msgstr "" +msgstr "vendor" #. type: Plain text #: ../src/guide/glossary.md msgid "A vendor is an organization or individual developer providing code in the form of packages. It also may refer to [Composer's `vendor` directory](https://getcomposer.org/doc/)." -msgstr "" +msgstr "Vendor é uma organização ou um desenvolvedor individual que fornece código na forma de pacotes. Também pode se referir ao [diretório `vendor` do Composer](https://getcomposer.org/doc/)." #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "view" -msgstr "" +msgstr "view" #. type: Plain text #: ../src/guide/glossary.md msgid "View is responsible for presenting data to end users, usually by executing a template with provided data. Read more in [\"Views\"](views/view.md)." -msgstr "" +msgstr "A view é responsável por apresentar dados aos usuários finais, normalmente executando um template com os dados fornecidos. Leia mais em [\"Views\"](views/view.md)." #. type: Title # #: ../src/guide/glossary.md #, no-wrap msgid "W" -msgstr "" +msgstr "W" #. type: Title ## #: ../src/guide/glossary.md #, no-wrap msgid "widget" -msgstr "" +msgstr "widget" #. type: Plain text #: ../src/guide/glossary.md msgid "Widget is a reusable view component that renders a piece of user interface. Read more in [\"Widgets\"](views/widget.md)." -msgstr "" +msgstr "Widget é um componente de view reutilizável que renderiza uma parte da interface do usuário. Leia mais em [\"Widgets\"](views/widget.md)." diff --git a/_translations/po/pt-BR/guide_testing_end-to-end.md.po b/_translations/po/pt-BR/guide_testing_end-to-end.md.po index 3877a245..513fa885 100644 --- a/_translations/po/pt-BR/guide_testing_end-to-end.md.po +++ b/_translations/po/pt-BR/guide_testing_end-to-end.md.po @@ -8,46 +8,44 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-05-08 08:49+0000\n" "PO-Revision-Date: 2026-05-08 08:49+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Plain text -#: ../src/cookbook/configuring-xdebug.md ../src/guide/testing/end-to-end.md -#: ../src/guide/testing/environment-setup.md -#: ../src/guide/testing/quality-tools.md +#: ../src/cookbook/configuring-xdebug.md ../src/guide/testing/end-to-end.md ../src/guide/testing/environment-setup.md ../src/guide/testing/quality-tools.md msgid "With Docker:" -msgstr "" +msgstr "Com Docker:" #. type: Title # #: ../src/guide/testing/end-to-end.md #, no-wrap msgid "End-to-end tests" -msgstr "" +msgstr "Testes end-to-end" #. type: Plain text #: ../src/guide/testing/end-to-end.md msgid "The Yii application template uses the `Web` Codeception suite for tests that go through an HTTP server. These tests live in `tests/Web` and use `App\\Tests\\Support\\WebTester`." -msgstr "" +msgstr "O template de aplicação Yii usa a suíte `Web` do Codeception para testes que passam por um servidor HTTP. Esses testes ficam em `tests/Web` e usam `App\\Tests\\Support\\WebTester`." #. type: Plain text #: ../src/guide/testing/end-to-end.md msgid "Use web tests for user-visible HTTP behavior: pages, links, forms, redirects, cookies, and error pages." -msgstr "" +msgstr "Use testes web para o comportamento HTTP visível ao usuário: páginas, links, formulários, redirecionamentos, cookies e páginas de erro." #. type: Title ## #: ../src/guide/testing/end-to-end.md #, no-wrap msgid "Web suite" -msgstr "" +msgstr "Suíte Web" #. type: Plain text #: ../src/guide/testing/end-to-end.md msgid "The template configures `tests/Web.suite.yml` like this:" -msgstr "" +msgstr "O template configura `tests/Web.suite.yml` assim:" #. type: Fenced code block (yaml) #: ../src/guide/testing/end-to-end.md ../src/guide/testing/environment-setup.md @@ -64,22 +62,32 @@ msgid "" " - PhpBrowser:\n" " url: http://127.0.0.1:8080\n" msgstr "" +"actor: WebTester\n" +"extensions:\n" +" enabled:\n" +" - Codeception\\Extension\\RunProcess:\n" +" 0: composer serve\n" +" sleep: 3\n" +"modules:\n" +" enabled:\n" +" - PhpBrowser:\n" +" url: http://127.0.0.1:8080\n" #. type: Plain text #: ../src/guide/testing/end-to-end.md msgid "`RunProcess` starts the application with the Composer `serve` script. `PhpBrowser` sends HTTP requests to the server." -msgstr "" +msgstr "`RunProcess` inicia a aplicação com o script `serve` do Composer. `PhpBrowser` envia requisições HTTP ao servidor." #. type: Title ## #: ../src/guide/testing/end-to-end.md ../src/guide/testing/functional.md #, no-wrap msgid "Test a page" -msgstr "" +msgstr "Testar uma página" #. type: Plain text #: ../src/guide/testing/end-to-end.md msgid "The template includes `tests/Web/HomePageCest.php`:" -msgstr "" +msgstr "O template inclui `tests/Web/HomePageCest.php`:" #. type: Fenced code block (php) #: ../src/guide/testing/end-to-end.md @@ -104,45 +112,63 @@ msgid "" " }\n" "}\n" msgstr "" +"wantTo('home page works.');\n" +" $I->amOnPage('/');\n" +" $I->expectTo('see page home.');\n" +" $I->see('Hello!');\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/testing/end-to-end.md msgid "Run the web suite locally:" -msgstr "" +msgstr "Execute a suíte web localmente:" #. type: Fenced code block (shell) #: ../src/guide/testing/end-to-end.md #, no-wrap msgid "APP_ENV=test vendor/bin/codecept run Web\n" -msgstr "" +msgstr "APP_ENV=test vendor/bin/codecept run Web\n" #. type: Plain text #: ../src/guide/testing/end-to-end.md ../src/guide/testing/unit.md msgid "Run only this test:" -msgstr "" +msgstr "Execute apenas este teste:" #. type: Fenced code block (shell) #: ../src/guide/testing/end-to-end.md #, no-wrap msgid "APP_ENV=test vendor/bin/codecept run Web HomePageCest\n" -msgstr "" +msgstr "APP_ENV=test vendor/bin/codecept run Web HomePageCest\n" #. type: Fenced code block (shell) #: ../src/guide/testing/end-to-end.md #, no-wrap msgid "make test Web\n" -msgstr "" +msgstr "make test Web\n" #. type: Title ## #: ../src/guide/testing/end-to-end.md #, no-wrap msgid "Test links and error pages" -msgstr "" +msgstr "Testar links e páginas de erro" #. type: Plain text #: ../src/guide/testing/end-to-end.md msgid "Use the same actor methods for navigation and response assertions:" -msgstr "" +msgstr "Use os mesmos métodos do actor para navegação e asserções sobre a resposta:" #. type: Fenced code block (php) #: ../src/guide/testing/end-to-end.md @@ -168,28 +194,47 @@ msgid "" " }\n" "}\n" msgstr "" +"wantTo('see 404 page.');\n" +" $I->amOnPage('/non-existent-page');\n" +" $I->canSeeResponseCodeIs(404);\n" +" $I->see('404');\n" +" $I->see('The page /non-existent-page not found.');\n" +" }\n" +"}\n" #. type: Title ## #: ../src/guide/testing/end-to-end.md #, no-wrap msgid "Smoke test with curl" -msgstr "" +msgstr "Smoke test com curl" #. type: Plain text #: ../src/guide/testing/end-to-end.md msgid "For a deployment smoke test, start the application and check one URL:" -msgstr "" +msgstr "Para um smoke test de deploy, inicie a aplicação e verifique uma URL:" #. type: Fenced code block (shell) #: ../src/guide/testing/end-to-end.md #, no-wrap msgid "APP_ENV=test ./yii serve --port=8080\n" -msgstr "" +msgstr "APP_ENV=test ./yii serve --port=8080\n" #. type: Plain text #: ../src/guide/testing/end-to-end.md msgid "In another terminal:" -msgstr "" +msgstr "Em outro terminal:" #. type: Fenced code block (shell) #: ../src/guide/testing/end-to-end.md @@ -198,42 +243,44 @@ msgid "" "curl -fsS http://127.0.0.1:8080/ > /tmp/home.html\n" "grep -q \"Hello!\" /tmp/home.html\n" msgstr "" +"curl -fsS http://127.0.0.1:8080/ > /tmp/home.html\n" +"grep -q \"Hello!\" /tmp/home.html\n" #. type: Title ## #: ../src/guide/testing/end-to-end.md ../src/guide/testing/functional.md #, no-wrap msgid "Reset state" -msgstr "" +msgstr "Redefinir o estado" #. type: Plain text #: ../src/guide/testing/end-to-end.md msgid "Web tests use real infrastructure, so reset state before each scenario:" -msgstr "" +msgstr "Testes web usam infraestrutura real, então redefina o estado antes de cada cenário:" #. type: Bullet: '- ' #: ../src/guide/testing/end-to-end.md msgid "Load only the records required by the scenario." -msgstr "" +msgstr "Carregue apenas os registros exigidos pelo cenário." #. type: Bullet: '- ' #: ../src/guide/testing/end-to-end.md msgid "Clear session and cookie storage." -msgstr "" +msgstr "Limpe o armazenamento de sessão e de cookies." #. type: Bullet: '- ' #: ../src/guide/testing/end-to-end.md msgid "Clear generated files and outgoing messages." -msgstr "" +msgstr "Limpe arquivos gerados e mensagens de saída." #. type: Bullet: '- ' #: ../src/guide/testing/end-to-end.md msgid "Stop background workers, or make their effects deterministic." -msgstr "" +msgstr "Pare os workers em segundo plano ou torne seus efeitos determinísticos." #. type: Plain text #: ../src/guide/testing/end-to-end.md msgid "If the scenario changes a database, reset it in the Cest `_before()` hook or in a project-specific helper:" -msgstr "" +msgstr "Se o cenário altera um banco de dados, redefina-o no hook `_before()` do Cest ou em um helper específico do projeto:" #. type: Fenced code block (php) #: ../src/guide/testing/end-to-end.md @@ -244,3 +291,7 @@ msgid "" " // Reset database tables, files, queues, and outgoing messages.\n" "}\n" msgstr "" +"public function _before(WebTester $I): void\n" +"{\n" +" // Redefina tabelas do banco de dados, arquivos, filas e mensagens de saída.\n" +"}\n" diff --git a/_translations/po/pt-BR/guide_testing_environment-setup.md.po b/_translations/po/pt-BR/guide_testing_environment-setup.md.po index d1cb7c48..3a2739fa 100644 --- a/_translations/po/pt-BR/guide_testing_environment-setup.md.po +++ b/_translations/po/pt-BR/guide_testing_environment-setup.md.po @@ -8,19 +8,17 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-05-08 08:49+0000\n" "PO-Revision-Date: 2026-05-08 08:49+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Plain text -#: ../src/cookbook/configuring-xdebug.md ../src/guide/testing/end-to-end.md -#: ../src/guide/testing/environment-setup.md -#: ../src/guide/testing/quality-tools.md +#: ../src/cookbook/configuring-xdebug.md ../src/guide/testing/end-to-end.md ../src/guide/testing/environment-setup.md ../src/guide/testing/quality-tools.md msgid "With Docker:" -msgstr "" +msgstr "Com Docker:" #. type: Fenced code block (yaml) #: ../src/guide/testing/end-to-end.md ../src/guide/testing/environment-setup.md @@ -37,28 +35,38 @@ msgid "" " - PhpBrowser:\n" " url: http://127.0.0.1:8080\n" msgstr "" +"actor: WebTester\n" +"extensions:\n" +" enabled:\n" +" - Codeception\\Extension\\RunProcess:\n" +" 0: composer serve\n" +" sleep: 3\n" +"modules:\n" +" enabled:\n" +" - PhpBrowser:\n" +" url: http://127.0.0.1:8080\n" #. type: Title # #: ../src/guide/testing/environment-setup.md #, no-wrap msgid "Testing environment setup" -msgstr "" +msgstr "Configuração do ambiente de testes" #. type: Plain text #: ../src/guide/testing/environment-setup.md msgid "The Yii application template has the test environment configured. Use this page when creating a new project from the template, restoring removed test files, or adding a new suite." -msgstr "" +msgstr "O template de aplicação Yii já vem com o ambiente de testes configurado. Use esta página ao criar um novo projeto a partir do template, restaurar arquivos de teste removidos ou adicionar uma nova suíte." #. type: Title ## #: ../src/guide/testing/environment-setup.md #, no-wrap msgid "Composer configuration" -msgstr "" +msgstr "Configuração do Composer" #. type: Plain text #: ../src/guide/testing/environment-setup.md msgid "The template requires Codeception, PHPUnit, and the modules used by the suites:" -msgstr "" +msgstr "O template exige o Codeception, o PHPUnit e os módulos usados pelas suítes:" #. type: Fenced code block (json) #: ../src/guide/testing/environment-setup.md @@ -82,22 +90,39 @@ msgid "" " }\n" "}\n" msgstr "" +"{\n" +" \"require-dev\": {\n" +" \"codeception/codeception\": \"^5.3\",\n" +" \"codeception/module-asserts\": \"^3.2\",\n" +" \"codeception/module-cli\": \"^2.0\",\n" +" \"codeception/module-phpbrowser\": \"^3.0\",\n" +" \"phpunit/phpunit\": \"^11.5\"\n" +" },\n" +" \"autoload-dev\": {\n" +" \"psr-4\": {\n" +" \"App\\\\Tests\\\\\": \"tests\"\n" +" }\n" +" },\n" +" \"scripts\": {\n" +" \"test\": \"codecept run\"\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/testing/environment-setup.md msgid "If these entries are already in your project, keep the installed versions from `composer.lock`." -msgstr "" +msgstr "Se essas entradas já estiverem no seu projeto, mantenha as versões instaladas do `composer.lock`." #. type: Title ## #: ../src/guide/testing/environment-setup.md #, no-wrap msgid "Main Codeception file" -msgstr "" +msgstr "Arquivo principal do Codeception" #. type: Plain text #: ../src/guide/testing/environment-setup.md msgid "The root `codeception.yml` defines the test namespace, paths, bootstrap file, and coverage source:" -msgstr "" +msgstr "O `codeception.yml` na raiz define o namespace dos testes, os caminhos, o arquivo de bootstrap e a origem da cobertura:" #. type: Fenced code block (yaml) #: ../src/guide/testing/environment-setup.md @@ -130,11 +155,37 @@ msgid "" " enabled:\n" " - Codeception\\Extension\\RunFailed\n" msgstr "" +"namespace: App\\Tests\n" +"support_namespace: Support\n" +"bootstrap: bootstrap.php\n" +"\n" +"settings:\n" +" shuffle: true\n" +" colors: true\n" +"\n" +"paths:\n" +" tests: tests\n" +" output: tests/_output\n" +" data: tests/Support/Data\n" +" support: tests/Support\n" +"\n" +"coverage:\n" +" enabled: true\n" +" show_uncovered: true\n" +" show_only_summary: true\n" +" include:\n" +" - src/*\n" +" - public/index.php\n" +" - yii\n" +"\n" +"extensions:\n" +" enabled:\n" +" - Codeception\\Extension\\RunFailed\n" #. type: Plain text #: ../src/guide/testing/environment-setup.md msgid "`tests/bootstrap.php` prepares the application environment for every suite:" -msgstr "" +msgstr "`tests/bootstrap.php` prepara o ambiente da aplicação para todas as suítes:" #. type: Fenced code block (php) #: ../src/guide/testing/environment-setup.md @@ -146,22 +197,27 @@ msgid "" "\n" "App\\Environment::prepare();\n" msgstr "" +"\n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,40 +19,40 @@ msgstr "" #: ../src/guide/testing/end-to-end.md ../src/guide/testing/functional.md #, no-wrap msgid "Test a page" -msgstr "" +msgstr "Testar uma página" #. type: Title ## #: ../src/guide/testing/end-to-end.md ../src/guide/testing/functional.md #, no-wrap msgid "Reset state" -msgstr "" +msgstr "Redefinir o estado" #. type: Title # #: ../src/guide/testing/functional.md #, no-wrap msgid "Functional tests" -msgstr "" +msgstr "Testes funcionais" #. type: Plain text #: ../src/guide/testing/functional.md msgid "Functional tests run application code in the same PHP process. In the Yii application template they live in `tests/Functional` and use `App\\Tests\\Support\\FunctionalTester`." -msgstr "" +msgstr "Testes funcionais executam o código da aplicação no mesmo processo PHP. No template de aplicação Yii eles ficam em `tests/Functional` e usam `App\\Tests\\Support\\FunctionalTester`." #. type: Plain text #: ../src/guide/testing/functional.md msgid "Use them for routing, middleware, action handlers, views, container configuration, headers, cookies, and sessions." -msgstr "" +msgstr "Use-os para roteamento, middlewares, action handlers, views, configuração do container, headers, cookies e sessões." #. type: Title ## #: ../src/guide/testing/functional.md #, no-wrap msgid "Functional tester" -msgstr "" +msgstr "Functional tester" #. type: Plain text #: ../src/guide/testing/functional.md msgid "The template already has a helper method for sending PSR-7 requests:" -msgstr "" +msgstr "O template já tem um método helper para enviar requisições PSR-7:" #. type: Fenced code block (php) #: ../src/guide/testing/functional.md @@ -92,11 +92,44 @@ msgid "" " }\n" "}\n" msgstr "" +"runAndGetResponse($request);\n" +" $body = $response->getBody();\n" +" if ($body->isSeekable()) {\n" +" $body->rewind();\n" +" }\n" +"\n" +" return $response;\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/testing/functional.md msgid "The template includes `tests/Functional/HomePageCest.php`:" -msgstr "" +msgstr "O template inclui `tests/Functional/HomePageCest.php`:" #. type: Fenced code block (php) #: ../src/guide/testing/functional.md @@ -130,11 +163,38 @@ msgid "" " }\n" "}\n" msgstr "" +"sendRequest(\n" +" new ServerRequest(uri: '/'),\n" +" );\n" +"\n" +" assertSame(200, $response->getStatusCode());\n" +" assertStringContainsString(\n" +" 'Don\\'t forget to check the guide',\n" +" $response->getBody()->getContents(),\n" +" );\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/testing/functional.md ../src/guide/testing/unit.md msgid "Run it:" -msgstr "" +msgstr "Execute-o:" #. type: Fenced code block (shell) #: ../src/guide/testing/functional.md @@ -143,17 +203,19 @@ msgid "" "APP_ENV=test vendor/bin/codecept run Functional\n" "APP_ENV=test vendor/bin/codecept run Functional HomePageCest\n" msgstr "" +"APP_ENV=test vendor/bin/codecept run Functional\n" +"APP_ENV=test vendor/bin/codecept run Functional HomePageCest\n" #. type: Title ## #: ../src/guide/testing/functional.md #, no-wrap msgid "Send request data" -msgstr "" +msgstr "Enviar dados na requisição" #. type: Plain text #: ../src/guide/testing/functional.md msgid "Use PSR-7 methods to model the request:" -msgstr "" +msgstr "Use os métodos PSR-7 para modelar a requisição:" #. type: Fenced code block (php) #: ../src/guide/testing/functional.md @@ -174,16 +236,30 @@ msgid "" "assertSame(302, $response->getStatusCode());\n" "assertSame('/contact/sent', $response->getHeaderLine('Location'));\n" msgstr "" +"$request = (new ServerRequest(uri: '/contact', method: 'POST'))\n" +" ->withHeader('Content-Type', 'application/x-www-form-urlencoded')\n" +" ->withParsedBody([\n" +" 'ContactForm' => [\n" +" 'name' => 'Sam',\n" +" 'email' => 'sam@example.test',\n" +" 'body' => 'Hello.',\n" +" ],\n" +" ]);\n" +"\n" +"$response = $tester->sendRequest($request);\n" +"\n" +"assertSame(302, $response->getStatusCode());\n" +"assertSame('/contact/sent', $response->getHeaderLine('Location'));\n" #. type: Plain text #: ../src/guide/testing/functional.md msgid "For JSON APIs, write the JSON body into a PSR-7 stream and set `Content-Type: application/json`." -msgstr "" +msgstr "Para APIs JSON, escreva o corpo JSON em um stream PSR-7 e defina `Content-Type: application/json`." #. type: Plain text #: ../src/guide/testing/functional.md msgid "Functional tests often touch runtime files, sessions, cache, and a database. Reset changed state in the Cest `_before()` hook or in a project helper:" -msgstr "" +msgstr "Testes funcionais costumam mexer em arquivos de runtime, sessões, cache e banco de dados. Redefina o estado alterado no hook `_before()` do Cest ou em um helper do projeto:" #. type: Fenced code block (php) #: ../src/guide/testing/functional.md @@ -194,8 +270,12 @@ msgid "" " // Reset database tables, cache pools, queues, and outgoing messages.\n" "}\n" msgstr "" +"public function _before(FunctionalTester $tester): void\n" +"{\n" +" // Redefina tabelas do banco de dados, pools de cache, filas e mensagens de saída.\n" +"}\n" #. type: Plain text #: ../src/guide/testing/functional.md msgid "Keep pure domain rules in unit tests. Put request and response behavior in functional tests." -msgstr "" +msgstr "Mantenha as regras de domínio puras nos testes unitários. Coloque o comportamento de requisição e resposta nos testes funcionais." diff --git a/_translations/po/pt-BR/guide_testing_overview.md.po b/_translations/po/pt-BR/guide_testing_overview.md.po index e04594f1..747eb305 100644 --- a/_translations/po/pt-BR/guide_testing_overview.md.po +++ b/_translations/po/pt-BR/guide_testing_overview.md.po @@ -8,16 +8,15 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-05-08 08:49+0000\n" "PO-Revision-Date: 2026-05-08 08:49+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ### -#: ../src/cookbook/making-http-requests.md ../src/guide/index.md -#: ../src/guide/testing/overview.md ../src/guide/tutorial/docker.md +#: ../src/cookbook/making-http-requests.md ../src/guide/index.md ../src/guide/testing/overview.md ../src/guide/tutorial/docker.md #, no-wrap msgid "Testing" msgstr "Testes" @@ -26,116 +25,116 @@ msgstr "Testes" #: ../src/guide/testing/environment-setup.md ../src/guide/testing/overview.md #, no-wrap msgid "APP_ENV=test vendor/bin/codecept run\n" -msgstr "" +msgstr "APP_ENV=test vendor/bin/codecept run\n" #. type: Fenced code block (shell) #: ../src/guide/testing/environment-setup.md ../src/guide/testing/overview.md #, no-wrap msgid "vendor/bin/codecept build\n" -msgstr "" +msgstr "vendor/bin/codecept build\n" #. type: Fenced code block (shell) #: ../src/guide/testing/environment-setup.md ../src/guide/testing/overview.md #, no-wrap msgid "make codecept build\n" -msgstr "" +msgstr "make codecept build\n" #. type: Plain text #: ../src/guide/testing/overview.md msgid "The Yii application template includes a ready test setup. It uses Codeception with PHPUnit assertions and has four suites:" -msgstr "" +msgstr "O template de aplicação Yii inclui uma configuração de testes pronta. Ele usa o Codeception com asserções do PHPUnit e tem quatro suítes:" #. type: Bullet: '- ' #: ../src/guide/testing/overview.md msgid "`Unit` for isolated PHP classes." -msgstr "" +msgstr "`Unit` para classes PHP isoladas." #. type: Bullet: '- ' #: ../src/guide/testing/overview.md msgid "`Functional` for application code called in the same PHP process." -msgstr "" +msgstr "`Functional` para código da aplicação chamado no mesmo processo PHP." #. type: Bullet: '- ' #: ../src/guide/testing/overview.md msgid "`Web` for requests sent through an HTTP server." -msgstr "" +msgstr "`Web` para requisições enviadas por um servidor HTTP." #. type: Bullet: '- ' #: ../src/guide/testing/overview.md msgid "`Console` for console commands." -msgstr "" +msgstr "`Console` para comandos de console." #. type: Plain text #: ../src/guide/testing/overview.md msgid "The main files are:" -msgstr "" +msgstr "Os arquivos principais são:" #. type: Bullet: '- ' #: ../src/guide/testing/overview.md msgid "`codeception.yml`." -msgstr "" +msgstr "`codeception.yml`." #. type: Bullet: '- ' #: ../src/guide/testing/overview.md msgid "`tests/bootstrap.php`." -msgstr "" +msgstr "`tests/bootstrap.php`." #. type: Bullet: '- ' #: ../src/guide/testing/overview.md msgid "`tests/Unit.suite.yml`." -msgstr "" +msgstr "`tests/Unit.suite.yml`." #. type: Bullet: '- ' #: ../src/guide/testing/overview.md msgid "`tests/Functional.suite.yml`." -msgstr "" +msgstr "`tests/Functional.suite.yml`." #. type: Bullet: '- ' #: ../src/guide/testing/overview.md msgid "`tests/Web.suite.yml`." -msgstr "" +msgstr "`tests/Web.suite.yml`." #. type: Bullet: '- ' #: ../src/guide/testing/overview.md msgid "`tests/Console.suite.yml`." -msgstr "" +msgstr "`tests/Console.suite.yml`." #. type: Bullet: '- ' #: ../src/guide/testing/overview.md msgid "`tests/Support/*Tester.php`." -msgstr "" +msgstr "`tests/Support/*Tester.php`." #. type: Title ## #: ../src/guide/testing/overview.md #, no-wrap msgid "Run tests locally" -msgstr "" +msgstr "Executar testes localmente" #. type: Plain text #: ../src/guide/testing/overview.md msgid "Build actor classes after installing dependencies or changing a suite:" -msgstr "" +msgstr "Gere as classes de actor depois de instalar as dependências ou alterar uma suíte:" #. type: Plain text #: ../src/guide/testing/overview.md msgid "Run all tests:" -msgstr "" +msgstr "Execute todos os testes:" #. type: Plain text #: ../src/guide/testing/overview.md msgid "The template also defines a Composer script:" -msgstr "" +msgstr "O template também define um script do Composer:" #. type: Fenced code block (shell) #: ../src/guide/testing/overview.md #, no-wrap msgid "APP_ENV=test composer test\n" -msgstr "" +msgstr "APP_ENV=test composer test\n" #. type: Plain text #: ../src/guide/testing/overview.md msgid "Run one suite:" -msgstr "" +msgstr "Execute uma suíte:" #. type: Fenced code block (shell) #: ../src/guide/testing/overview.md @@ -146,11 +145,15 @@ msgid "" "APP_ENV=test vendor/bin/codecept run Web\n" "APP_ENV=test vendor/bin/codecept run Console\n" msgstr "" +"APP_ENV=test vendor/bin/codecept run Unit\n" +"APP_ENV=test vendor/bin/codecept run Functional\n" +"APP_ENV=test vendor/bin/codecept run Web\n" +"APP_ENV=test vendor/bin/codecept run Console\n" #. type: Plain text #: ../src/guide/testing/overview.md msgid "Run one test class or method:" -msgstr "" +msgstr "Execute uma classe ou um método de teste:" #. type: Fenced code block (shell) #: ../src/guide/testing/overview.md @@ -159,28 +162,30 @@ msgid "" "APP_ENV=test vendor/bin/codecept run Functional HomePageCest\n" "APP_ENV=test vendor/bin/codecept run Functional HomePageCest:base\n" msgstr "" +"APP_ENV=test vendor/bin/codecept run Functional HomePageCest\n" +"APP_ENV=test vendor/bin/codecept run Functional HomePageCest:base\n" #. type: Plain text #: ../src/guide/testing/overview.md msgid "`APP_ENV=test` is required for local commands because `tests/bootstrap.php` prepares the application environment before tests run." -msgstr "" +msgstr "`APP_ENV=test` é obrigatório nos comandos locais porque `tests/bootstrap.php` prepara o ambiente da aplicação antes da execução dos testes." #. type: Title ## #: ../src/guide/testing/overview.md #, no-wrap msgid "Run tests in Docker" -msgstr "" +msgstr "Executar testes no Docker" #. type: Plain text #: ../src/guide/testing/overview.md msgid "Build actor classes:" -msgstr "" +msgstr "Gere as classes de actor:" #. type: Fenced code block (shell) #: ../src/guide/testing/overview.md #, no-wrap msgid "make test\n" -msgstr "" +msgstr "make test\n" #. type: Fenced code block (shell) #: ../src/guide/testing/overview.md @@ -191,39 +196,43 @@ msgid "" "make test Web\n" "make test Console\n" msgstr "" +"make test Unit\n" +"make test Functional\n" +"make test Web\n" +"make test Console\n" #. type: Plain text #: ../src/guide/testing/overview.md msgid "The Docker test environment reads `docker/test/.env`, where `APP_ENV=test` is already set." -msgstr "" +msgstr "O ambiente de testes do Docker lê `docker/test/.env`, onde `APP_ENV=test` já está definido." #. type: Title ## #: ../src/guide/testing/overview.md #, no-wrap msgid "Choose a suite" -msgstr "" +msgstr "Escolher uma suíte" #. type: Plain text #: ../src/guide/testing/overview.md msgid "Start with unit tests for code that has no framework boundary: value objects, validators, domain services, and transformers." -msgstr "" +msgstr "Comece com testes unitários para código que não tem fronteira com o framework: value objects, validadores, serviços de domínio e transformadores." #. type: Plain text #: ../src/guide/testing/overview.md msgid "Use functional tests when code needs Yii configuration, dependency injection, routing, middleware, request handling, or template rendering." -msgstr "" +msgstr "Use testes funcionais quando o código precisa da configuração do Yii, injeção de dependência, roteamento, middlewares, tratamento de requisições ou renderização de templates." #. type: Plain text #: ../src/guide/testing/overview.md msgid "Use web tests for behavior that must go through an HTTP server: status codes, links, redirects, cookies, and rendered pages as seen by a client." -msgstr "" +msgstr "Use testes web para comportamentos que precisam passar por um servidor HTTP: códigos de status, links, redirecionamentos, cookies e páginas renderizadas como o cliente as vê." #. type: Plain text #: ../src/guide/testing/overview.md msgid "Use console tests for commands in `src/Console`." -msgstr "" +msgstr "Use testes de console para os comandos em `src/Console`." #. type: Plain text #: ../src/guide/testing/overview.md msgid "Run static analysis in CI and before changing shared contracts." -msgstr "" +msgstr "Execute a análise estática no CI e antes de alterar contratos compartilhados." diff --git a/_translations/po/pt-BR/guide_testing_quality-tools.md.po b/_translations/po/pt-BR/guide_testing_quality-tools.md.po index 16af8566..5d858394 100644 --- a/_translations/po/pt-BR/guide_testing_quality-tools.md.po +++ b/_translations/po/pt-BR/guide_testing_quality-tools.md.po @@ -8,189 +8,187 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-05-08 08:49+0000\n" "PO-Revision-Date: 2026-05-08 08:49+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Plain text -#: ../src/cookbook/configuring-xdebug.md ../src/guide/testing/end-to-end.md -#: ../src/guide/testing/environment-setup.md -#: ../src/guide/testing/quality-tools.md +#: ../src/cookbook/configuring-xdebug.md ../src/guide/testing/end-to-end.md ../src/guide/testing/environment-setup.md ../src/guide/testing/quality-tools.md msgid "With Docker:" -msgstr "" +msgstr "Com Docker:" #. type: Title # #: ../src/guide/testing/quality-tools.md #, no-wrap msgid "Static analysis and code quality" -msgstr "" +msgstr "Análise estática e qualidade de código" #. type: Plain text #: ../src/guide/testing/quality-tools.md msgid "The Yii application template includes static analysis and code quality tools alongside the test suite." -msgstr "" +msgstr "O template de aplicação Yii inclui ferramentas de análise estática e de qualidade de código junto com a suíte de testes." #. type: Title ## #: ../src/guide/testing/quality-tools.md #, no-wrap msgid "Psalm" -msgstr "" +msgstr "Psalm" #. type: Plain text #: ../src/guide/testing/quality-tools.md msgid "Run Psalm locally:" -msgstr "" +msgstr "Execute o Psalm localmente:" #. type: Fenced code block (shell) #: ../src/guide/testing/quality-tools.md #, no-wrap msgid "vendor/bin/psalm\n" -msgstr "" +msgstr "vendor/bin/psalm\n" #. type: Plain text #: ../src/guide/testing/quality-tools.md msgid "Run Psalm in Docker:" -msgstr "" +msgstr "Execute o Psalm no Docker:" #. type: Fenced code block (shell) #: ../src/guide/testing/quality-tools.md #, no-wrap msgid "make psalm\n" -msgstr "" +msgstr "make psalm\n" #. type: Plain text #: ../src/guide/testing/quality-tools.md msgid "The template stores Psalm configuration in `psalm.xml`. The GitHub Actions workflow runs Psalm for supported PHP versions." -msgstr "" +msgstr "O template guarda a configuração do Psalm em `psalm.xml`. O workflow do GitHub Actions executa o Psalm nas versões de PHP suportadas." #. type: Plain text #: ../src/guide/testing/quality-tools.md msgid "When Psalm reports an issue, fix the code or add a precise type annotation. Keep suppressions narrow and local to the line or method that needs them." -msgstr "" +msgstr "Quando o Psalm reportar um problema, corrija o código ou adicione uma anotação de tipo precisa. Mantenha as supressões restritas e locais à linha ou ao método que precisa delas." #. type: Title ## #: ../src/guide/testing/quality-tools.md #, no-wrap msgid "Composer Dependency Analyser" -msgstr "" +msgstr "Composer Dependency Analyser" #. type: Plain text #: ../src/guide/testing/quality-tools.md msgid "Composer Dependency Analyser checks that `composer.json` matches the classes used by the application." -msgstr "" +msgstr "O Composer Dependency Analyser verifica se o `composer.json` corresponde às classes usadas pela aplicação." #. type: Plain text #: ../src/guide/testing/quality-tools.md msgid "Run it locally:" -msgstr "" +msgstr "Execute-o localmente:" #. type: Fenced code block (shell) #: ../src/guide/testing/quality-tools.md #, no-wrap msgid "vendor/bin/composer-dependency-analyser --config=composer-dependency-analyser.php\n" -msgstr "" +msgstr "vendor/bin/composer-dependency-analyser --config=composer-dependency-analyser.php\n" #. type: Plain text #: ../src/guide/testing/quality-tools.md msgid "Run it in Docker:" -msgstr "" +msgstr "Execute-o no Docker:" #. type: Fenced code block (shell) #: ../src/guide/testing/quality-tools.md #, no-wrap msgid "make composer-dependency-analyser\n" -msgstr "" +msgstr "make composer-dependency-analyser\n" #. type: Plain text #: ../src/guide/testing/quality-tools.md msgid "Use this check after adding or removing package usage in `src`, `config`, or `tests`." -msgstr "" +msgstr "Use essa verificação depois de adicionar ou remover o uso de pacotes em `src`, `config` ou `tests`." #. type: Title ## #: ../src/guide/testing/quality-tools.md #, no-wrap msgid "PHP CS Fixer" -msgstr "" +msgstr "PHP CS Fixer" #. type: Plain text #: ../src/guide/testing/quality-tools.md msgid "PHP CS Fixer applies the project coding style from `.php-cs-fixer.php`." -msgstr "" +msgstr "O PHP CS Fixer aplica o estilo de código do projeto definido em `.php-cs-fixer.php`." #. type: Fenced code block (shell) #: ../src/guide/testing/quality-tools.md #, no-wrap msgid "vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.php --diff\n" -msgstr "" +msgstr "vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.php --diff\n" #. type: Fenced code block (shell) #: ../src/guide/testing/quality-tools.md #, no-wrap msgid "make cs-fix\n" -msgstr "" +msgstr "make cs-fix\n" #. type: Plain text #: ../src/guide/testing/quality-tools.md msgid "Commit formatting changes together with the code that needs them." -msgstr "" +msgstr "Faça o commit das mudanças de formatação junto com o código que as exige." #. type: Title ## #: ../src/guide/testing/quality-tools.md #, no-wrap msgid "Rector" -msgstr "" +msgstr "Rector" #. type: Plain text #: ../src/guide/testing/quality-tools.md msgid "Rector applies configured code upgrades and refactorings from `rector.php`." -msgstr "" +msgstr "O Rector aplica as atualizações e refatorações de código configuradas em `rector.php`." #. type: Plain text #: ../src/guide/testing/quality-tools.md msgid "Preview changes locally:" -msgstr "" +msgstr "Visualize as mudanças localmente:" #. type: Fenced code block (shell) #: ../src/guide/testing/quality-tools.md #, no-wrap msgid "vendor/bin/rector --dry-run\n" -msgstr "" +msgstr "vendor/bin/rector --dry-run\n" #. type: Plain text #: ../src/guide/testing/quality-tools.md msgid "Apply changes locally:" -msgstr "" +msgstr "Aplique as mudanças localmente:" #. type: Fenced code block (shell) #: ../src/guide/testing/quality-tools.md #, no-wrap msgid "vendor/bin/rector\n" -msgstr "" +msgstr "vendor/bin/rector\n" #. type: Fenced code block (shell) #: ../src/guide/testing/quality-tools.md #, no-wrap msgid "make rector\n" -msgstr "" +msgstr "make rector\n" #. type: Plain text #: ../src/guide/testing/quality-tools.md msgid "Review Rector changes before committing them. Automated refactoring can change behavior when custom rules or broad paths are configured." -msgstr "" +msgstr "Revise as mudanças do Rector antes de fazer o commit. A refatoração automatizada pode alterar o comportamento quando regras personalizadas ou caminhos amplos estão configurados." #. type: Title ## #: ../src/guide/testing/quality-tools.md #, no-wrap msgid "Pull request checks" -msgstr "" +msgstr "Verificações de pull request" #. type: Plain text #: ../src/guide/testing/quality-tools.md msgid "A practical local check before opening a pull request is:" -msgstr "" +msgstr "Uma verificação local prática antes de abrir um pull request é:" #. type: Fenced code block (shell) #: ../src/guide/testing/quality-tools.md @@ -202,6 +200,11 @@ msgid "" "vendor/bin/composer-dependency-analyser --config=composer-dependency-analyser.php\n" "vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.php --diff\n" msgstr "" +"APP_ENV=test vendor/bin/codecept build\n" +"APP_ENV=test vendor/bin/codecept run\n" +"vendor/bin/psalm\n" +"vendor/bin/composer-dependency-analyser --config=composer-dependency-analyser.php\n" +"vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.php --diff\n" #. type: Fenced code block (shell) #: ../src/guide/testing/quality-tools.md @@ -213,3 +216,8 @@ msgid "" "make composer-dependency-analyser\n" "make cs-fix\n" msgstr "" +"make codecept build\n" +"make test\n" +"make psalm\n" +"make composer-dependency-analyser\n" +"make cs-fix\n" diff --git a/_translations/po/pt-BR/guide_testing_unit.md.po b/_translations/po/pt-BR/guide_testing_unit.md.po index 076caf5c..923ef5a8 100644 --- a/_translations/po/pt-BR/guide_testing_unit.md.po +++ b/_translations/po/pt-BR/guide_testing_unit.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-05-08 08:49+0000\n" "PO-Revision-Date: 2026-05-08 08:49+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -18,28 +18,28 @@ msgstr "" #. type: Plain text #: ../src/guide/testing/end-to-end.md ../src/guide/testing/unit.md msgid "Run only this test:" -msgstr "" +msgstr "Execute apenas este teste:" #. type: Plain text #: ../src/guide/testing/functional.md ../src/guide/testing/unit.md msgid "Run it:" -msgstr "" +msgstr "Execute-o:" #. type: Title # #: ../src/guide/testing/unit.md #, no-wrap msgid "Unit tests" -msgstr "" +msgstr "Testes unitários" #. type: Plain text #: ../src/guide/testing/unit.md msgid "Unit tests check a small piece of PHP code directly. In the Yii application template they live in `tests/Unit` and run through the `Unit` Codeception suite." -msgstr "" +msgstr "Testes unitários verificam diretamente um pequeno trecho de código PHP. No template de aplicação Yii eles ficam em `tests/Unit` e são executados pela suíte `Unit` do Codeception." #. type: Plain text #: ../src/guide/testing/unit.md msgid "The template includes `tests/Unit/EnvironmentTest.php`:" -msgstr "" +msgstr "O template inclui `tests/Unit/EnvironmentTest.php`:" #. type: Fenced code block (php) #: ../src/guide/testing/unit.md @@ -69,34 +69,57 @@ msgid "" " }\n" "}\n" msgstr "" +"generate('Hello, Yii3!');\n" +"\n" +" assertSame('hello-yii3', $slug);\n" +" }\n" +"}\n" #. type: Fenced code block (shell) #: ../src/guide/testing/unit.md #, no-wrap msgid "APP_ENV=test vendor/bin/codecept run Unit SlugGeneratorTest\n" -msgstr "" +msgstr "APP_ENV=test vendor/bin/codecept run Unit SlugGeneratorTest\n" #. type: Title ## #: ../src/guide/testing/unit.md #, no-wrap msgid "Test services with dependencies" -msgstr "" +msgstr "Testar serviços com dependências" #. type: Plain text #: ../src/guide/testing/unit.md msgid "Pass dependencies through the constructor and use test doubles for I/O." -msgstr "" +msgstr "Passe as dependências pelo construtor e use test doubles para I/O." #. type: Plain text #: ../src/guide/testing/unit.md msgid "Create `src/Clock/ClockInterface.php`:" -msgstr "" +msgstr "Crie `src/Clock/ClockInterface.php`:" #. type: Fenced code block (php) #: ../src/guide/testing/unit.md @@ -191,11 +251,23 @@ msgid "" " public function now(): DateTimeImmutable;\n" "}\n" msgstr "" +"clock->now());\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/testing/unit.md msgid "Create `tests/Unit/PublishPostTest.php`:" -msgstr "" +msgstr "Crie `tests/Unit/PublishPostTest.php`:" #. type: Fenced code block (php) #: ../src/guide/testing/unit.md @@ -291,14 +399,45 @@ msgid "" " }\n" "}\n" msgstr "" +"publish('Testing Yii');\n" +"\n" +" assertSame('Testing Yii', $post->title);\n" +" assertSame('2026-05-07 10:00:00', $post->publishedAt->format('Y-m-d H:i:s'));\n" +" }\n" +"}\n" #. type: Fenced code block (shell) #: ../src/guide/testing/unit.md #, no-wrap msgid "APP_ENV=test vendor/bin/codecept run Unit PublishPostTest\n" -msgstr "" +msgstr "APP_ENV=test vendor/bin/codecept run Unit PublishPostTest\n" #. type: Plain text #: ../src/guide/testing/unit.md msgid "Keep unit tests focused on one class or one small collaboration. Use functional tests when the behavior depends on Yii configuration, dependency injection, routing, or middleware." -msgstr "" +msgstr "Mantenha os testes unitários focados em uma classe ou em uma pequena colaboração. Use testes funcionais quando o comportamento depende da configuração do Yii, injeção de dependência, roteamento ou middlewares." diff --git a/_translations/po/pt-BR/guide_tutorial_console-applications.md.po b/_translations/po/pt-BR/guide_tutorial_console-applications.md.po index 19795c68..9352da81 100644 --- a/_translations/po/pt-BR/guide_tutorial_console-applications.md.po +++ b/_translations/po/pt-BR/guide_tutorial_console-applications.md.po @@ -8,23 +8,18 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-03-30 08:11+0000\n" "PO-Revision-Date: 2026-03-30 08:11+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md -#: ../src/guide/concept/autoloading.md ../src/guide/security/best-practices.md -#: ../src/guide/structure/domain.md -#: ../src/guide/tutorial/console-applications.md -#: ../src/internals/004-namespaces.md ../src/internals/007-exceptions.md -#: ../src/internals/008-interfaces.md +#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md ../src/guide/concept/autoloading.md ../src/guide/security/best-practices.md ../src/guide/structure/domain.md ../src/guide/tutorial/console-applications.md ../src/internals/004-namespaces.md ../src/internals/007-exceptions.md ../src/internals/008-interfaces.md #, no-wrap msgid "References" -msgstr "" +msgstr "Referências" #. type: Title ## #: ../src/guide/index.md ../src/guide/tutorial/console-applications.md @@ -36,49 +31,49 @@ msgstr "Primeiros passos" #: ../src/guide/tutorial/console-applications.md #, no-wrap msgid "Console applications" -msgstr "" +msgstr "Aplicações de console" #. type: Plain text #: ../src/guide/tutorial/console-applications.md msgid "Console applications are mainly used to create utility, background processing and maintenance tasks." -msgstr "" +msgstr "Aplicações de console são usadas principalmente para criar utilitários, processamento em segundo plano e tarefas de manutenção." #. type: Plain text #: ../src/guide/tutorial/console-applications.md msgid "If you're using [yiisoft/app](https://github.com/yiisoft/app) or [yiisoft/app-api](https://github.com/yiisoft/app-api), console support is already included. You can access the entry point as:" -msgstr "" +msgstr "Se você usa [yiisoft/app](https://github.com/yiisoft/app) ou [yiisoft/app-api](https://github.com/yiisoft/app-api), o suporte a console já vem incluído. Você pode acessar o ponto de entrada assim:" #. type: Fenced code block #: ../src/guide/tutorial/console-applications.md #, no-wrap msgid "./yii\n" -msgstr "" +msgstr "./yii\n" #. type: Plain text #: ../src/guide/tutorial/console-applications.md msgid "If you want a standalone console-only application, use the [yiisoft/app-console](https://github.com/yiisoft/app-console) project template:" -msgstr "" +msgstr "Se você quer uma aplicação somente de console, use o template de projeto [yiisoft/app-console](https://github.com/yiisoft/app-console):" #. type: Fenced code block (sh) #: ../src/guide/tutorial/console-applications.md #, no-wrap msgid "composer create-project yiisoft/app-console your-project\n" -msgstr "" +msgstr "composer create-project yiisoft/app-console your-project\n" #. type: Plain text #: ../src/guide/tutorial/console-applications.md msgid "To add console support to an existing project from scratch, refer to the [yiisoft/yii-console package documentation](https://github.com/yiisoft/yii-console)." -msgstr "" +msgstr "Para adicionar suporte a console a um projeto existente do zero, consulte a [documentação do pacote yiisoft/yii-console](https://github.com/yiisoft/yii-console)." #. type: Plain text #: ../src/guide/tutorial/console-applications.md msgid "Out of the box only `serve` command is available. It's starting PHP built-in web server to serve the application locally." -msgstr "" +msgstr "De início, apenas o comando `serve` está disponível. Ele inicia o servidor web embutido do PHP para servir a aplicação localmente." #. type: Plain text #: ../src/guide/tutorial/console-applications.md msgid "Commands are executed with `symfony/console`. To create your own console command, you need to define a command:" -msgstr "" +msgstr "Os comandos são executados com `symfony/console`. Para criar seu próprio comando de console, você precisa definir um comando:" #. type: Fenced code block (php) #: ../src/guide/tutorial/console-applications.md @@ -119,11 +114,45 @@ msgid "" " }\n" "}\n" msgstr "" +"setHelp('This command serves for demo purpose')\n" +" ->addArgument('name', InputArgument::OPTIONAL, 'Name to greet', 'anonymous');\n" +" }\n" +"\n" +" protected function execute(InputInterface $input, OutputInterface $output): int\n" +" {\n" +" $io = new SymfonyStyle($input, $output);\n" +"\n" +" $name = $input->getArgument('name');\n" +" $io->success(\"Hello, $name!\");\n" +" return ExitCode::OK;\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/tutorial/console-applications.md msgid "Now register the command in `config/params.php`:" -msgstr "" +msgstr "Agora registre o comando em `config/params.php`:" #. type: Fenced code block (php) #: ../src/guide/tutorial/console-applications.md @@ -137,19 +166,26 @@ msgid "" " ], \n" "];\n" msgstr "" +"return [\n" +" 'yiisoft/yii-console' => [\n" +" 'commands' => [\n" +" 'demo:hello' => App\\Demo\\HelloCommand::class,\n" +" ],\n" +" ], \n" +"];\n" #. type: Plain text #: ../src/guide/tutorial/console-applications.md msgid "After it's done, the command could be executed as" -msgstr "" +msgstr "Feito isso, o comando pode ser executado assim" #. type: Fenced code block #: ../src/guide/tutorial/console-applications.md #, no-wrap msgid "./yii demo:hello Alice\n" -msgstr "" +msgstr "./yii demo:hello Alice\n" #. type: Bullet: '- ' #: ../src/guide/tutorial/console-applications.md msgid "[Symfony Console component guide](https://symfony.com/doc/current/components/console.html)" -msgstr "" +msgstr "[Guia do componente Symfony Console](https://symfony.com/doc/current/components/console.html)" diff --git a/_translations/po/pt-BR/guide_tutorial_docker.md.po b/_translations/po/pt-BR/guide_tutorial_docker.md.po index 4d93a378..b36b6268 100644 --- a/_translations/po/pt-BR/guide_tutorial_docker.md.po +++ b/_translations/po/pt-BR/guide_tutorial_docker.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-04-07 16:34+0000\n" "PO-Revision-Date: 2026-04-07 16:34+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -25,23 +25,23 @@ msgstr "Testes" #: ../src/guide/tutorial/docker.md #, no-wrap msgid "Docker in Application Templates" -msgstr "" +msgstr "Docker nos templates de aplicação" #. type: Plain text #: ../src/guide/tutorial/docker.md msgid "Both [yiisoft/app](https://github.com/yiisoft/app) and [yiisoft/app-api](https://github.com/yiisoft/app-api) come with a ready-to-use Docker setup based on [FrankenPHP](https://frankenphp.dev/) with Caddy as the built-in web server. The setup covers local development, testing, and production deployment through a set of environment files, Docker Compose configurations, a multi-stage Dockerfile, and a `Makefile` that wraps common operations." -msgstr "" +msgstr "Tanto o [yiisoft/app](https://github.com/yiisoft/app) quanto o [yiisoft/app-api](https://github.com/yiisoft/app-api) vêm com uma configuração Docker pronta para uso, baseada em [FrankenPHP](https://frankenphp.dev/) com Caddy como servidor web embutido. A configuração cobre desenvolvimento local, testes e deploy em produção por meio de um conjunto de arquivos de ambiente, configurações do Docker Compose, um Dockerfile multi-stage e um `Makefile` que encapsula as operações mais comuns." #. type: Title ## #: ../src/guide/tutorial/docker.md #, no-wrap msgid "Docker directory overview" -msgstr "" +msgstr "Visão geral do diretório docker" #. type: Plain text #: ../src/guide/tutorial/docker.md msgid "All Docker-related files live under the `docker/` directory:" -msgstr "" +msgstr "Todos os arquivos relacionados ao Docker ficam no diretório `docker/`:" #. type: Fenced code block #: ../src/guide/tutorial/docker.md @@ -65,33 +65,50 @@ msgid "" " ├── .gitignore # Excludes override.env from version control\n" " └── compose.yml # Production-specific Compose overrides (Docker Swarm)\n" msgstr "" +"docker/\n" +"├── .env # Variáveis do Compose (nome da stack, portas, nomes de imagens)\n" +"├── Dockerfile # Definição de imagem multi-stage\n" +"├── compose.yml # Arquivo Compose base (âncora compartilhada por todos os ambientes)\n" +"├── dev/\n" +"│ ├── .env # Variáveis de ambiente da aplicação para desenvolvimento\n" +"│ ├── .gitignore # Exclui override.env do controle de versão\n" +"│ ├── compose.yml # Overrides do Compose específicos de desenvolvimento\n" +"│ └── override.env.example # Template opcional de overrides locais do desenvolvedor\n" +"├── test/\n" +"│ ├── .env # Variáveis de ambiente da aplicação para testes\n" +"│ ├── .gitignore # Exclui override.env do controle de versão\n" +"│ └── compose.yml # Overrides do Compose específicos de testes\n" +"└── prod/\n" +" ├── .env # Variáveis de ambiente da aplicação para produção\n" +" ├── .gitignore # Exclui override.env do controle de versão\n" +" └── compose.yml # Overrides do Compose específicos de produção (Docker Swarm)\n" #. type: Plain text #: ../src/guide/tutorial/docker.md msgid "Each subdirectory (`dev/`, `test/`, `prod/`) corresponds to an environment stage and contains its own `.env` file with application-level configuration and a `compose.yml` that extends the base `docker/compose.yml`." -msgstr "" +msgstr "Cada subdiretório (`dev/`, `test/`, `prod/`) corresponde a um estágio de ambiente e contém seu próprio arquivo `.env` com a configuração da aplicação e um `compose.yml` que estende o `docker/compose.yml` base." #. type: Title ## #: ../src/guide/tutorial/docker.md #, no-wrap msgid "Environment files" -msgstr "" +msgstr "Arquivos de ambiente" #. type: Plain text #: ../src/guide/tutorial/docker.md msgid "The templates use two separate environment systems that serve different purposes and different runtimes." -msgstr "" +msgstr "Os templates usam dois sistemas de ambiente separados, com propósitos e runtimes diferentes." #. type: Title ### #: ../src/guide/tutorial/docker.md #, no-wrap msgid ".env.example (project root)" -msgstr "" +msgstr ".env.example (raiz do projeto)" #. type: Plain text #: ../src/guide/tutorial/docker.md msgid "The project root contains a `.env.example` file that serves as a template for local development **without Docker**:" -msgstr "" +msgstr "A raiz do projeto contém um arquivo `.env.example` que serve de template para desenvolvimento local **sem Docker**:" #. type: Fenced code block (ini) #: ../src/guide/tutorial/docker.md @@ -103,22 +120,27 @@ msgid "" "APP_ENV=dev\n" "APP_DEBUG=true\n" msgstr "" +"# Configuração do ambiente local.\n" +"# Copie este arquivo para .env e ajuste conforme necessário.\n" +"# Em produção, defina as variáveis de ambiente pela configuração do servidor ou do container.\n" +"APP_ENV=dev\n" +"APP_DEBUG=true\n" #. type: Plain text #: ../src/guide/tutorial/docker.md msgid "Copy it to create your local configuration file:" -msgstr "" +msgstr "Copie-o para criar seu arquivo de configuração local:" #. type: Fenced code block (sh) #: ../src/guide/tutorial/docker.md #, no-wrap msgid "cp .env.example .env\n" -msgstr "" +msgstr "cp .env.example .env\n" #. type: Plain text #: ../src/guide/tutorial/docker.md msgid "The `.env` file is loaded automatically by `src/bootstrap.php` using [phpdotenv](https://github.com/vlucas/phpdotenv) only when `APP_ENV` is not already present in the process environment. This means **Docker-provided environment variables always take precedence** over the root `.env` file — both workflows can coexist safely in the same project directory." -msgstr "" +msgstr "O arquivo `.env` é carregado automaticamente por `src/bootstrap.php` usando o [phpdotenv](https://github.com/vlucas/phpdotenv) somente quando `APP_ENV` ainda não está presente no ambiente do processo. Isso significa que **as variáveis de ambiente fornecidas pelo Docker sempre têm precedência** sobre o arquivo `.env` da raiz — os dois fluxos de trabalho podem coexistir com segurança no mesmo diretório do projeto." #. type: Plain text #: ../src/guide/tutorial/docker.md @@ -128,17 +150,20 @@ msgid "" "> `phpdotenv` is a development dependency and is not installed in production\n" "> (`composer install --no-dev`), so the root `.env` file has no effect on production containers.\n" msgstr "" +"> [!NOTE]\n" +"> `phpdotenv` é uma dependência de desenvolvimento e não é instalado em produção\n" +"> (`composer install --no-dev`), então o arquivo `.env` da raiz não tem efeito nos containers de produção.\n" #. type: Title ### #: ../src/guide/tutorial/docker.md #, no-wrap msgid "docker/.env" -msgstr "" +msgstr "docker/.env" #. type: Plain text #: ../src/guide/tutorial/docker.md msgid "This file contains variables used by the Compose files themselves — they are **not** passed into the running application container:" -msgstr "" +msgstr "Este arquivo contém variáveis usadas pelos próprios arquivos Compose — elas **não** são repassadas ao container da aplicação em execução:" #. type: Fenced code block (ini) #: ../src/guide/tutorial/docker.md @@ -160,6 +185,21 @@ msgid "" "IMAGE=app\n" "IMAGE_TAG=latest\n" msgstr "" +"# Variáveis para os arquivos compose.yml. Não disponíveis na aplicação.\n" +"\n" +"STACK_NAME=app\n" +"\n" +"# Desenvolvimento\n" +"\n" +"DEV_PORT=80\n" +"\n" +"# Produção\n" +"\n" +"PROD_HOST=app.example.com\n" +"PROD_SSH=\"ssh://docker-web\"\n" +"\n" +"IMAGE=app\n" +"IMAGE_TAG=latest\n" #. type: Plain text #: ../src/guide/tutorial/docker.md @@ -174,17 +214,25 @@ msgid "" "| `IMAGE` | Docker image name used during build and push. |\n" "| `IMAGE_TAG` | Docker image tag (`latest` by default; use a version string in CI/CD). |\n" msgstr "" +"| Variável | Finalidade |\n" +"|--------------|-------------------------------------------------------------------------|\n" +"| `STACK_NAME` | Nome do projeto Docker Compose e nome da stack do Docker Swarm. |\n" +"| `DEV_PORT` | Porta do host onde a aplicação é exposta em desenvolvimento (`make up`). |\n" +"| `PROD_HOST` | Hostname usado pelos labels do Caddy para HTTPS automático em produção. |\n" +"| `PROD_SSH` | Host Docker remoto para deploy em um nó Swarm via SSH. |\n" +"| `IMAGE` | Nome da imagem Docker usada no build e no push. |\n" +"| `IMAGE_TAG` | Tag da imagem Docker (`latest` por padrão; use uma versão no CI/CD). |\n" #. type: Title ### #: ../src/guide/tutorial/docker.md #, no-wrap msgid "docker/dev/.env" -msgstr "" +msgstr "docker/dev/.env" #. type: Plain text #: ../src/guide/tutorial/docker.md msgid "Contains application environment variables injected into the development container at runtime:" -msgstr "" +msgstr "Contém as variáveis de ambiente da aplicação injetadas no container de desenvolvimento em tempo de execução:" #. type: Fenced code block (ini) #: ../src/guide/tutorial/docker.md @@ -199,6 +247,14 @@ msgid "" "XDEBUG_MODE=develop\n" "COMPOSER_CACHE_DIR=/app/runtime/cache/composer\n" msgstr "" +"# Ambiente dev da aplicação.\n" +"# Note que as variáveis ficam disponíveis apenas na aplicação, não no compose.yml.\n" +"\n" +"APP_ENV=dev\n" +"APP_DEBUG=true\n" +"SERVER_NAME=:80\n" +"XDEBUG_MODE=develop\n" +"COMPOSER_CACHE_DIR=/app/runtime/cache/composer\n" #. type: Plain text #: ../src/guide/tutorial/docker.md @@ -212,17 +268,24 @@ msgid "" "| `XDEBUG_MODE` | Xdebug mode. Use `develop` for helpers and `debug` to enable step debugging. |\n" "| `COMPOSER_CACHE_DIR` | Moves Composer's cache into the mounted volume so it persists between runs. |\n" msgstr "" +"| Variável | Finalidade |\n" +"|-----------------------|--------------------------------------------------------------------------------------|\n" +"| `APP_ENV` | Ambiente da aplicação. `dev` ativa um comportamento amigável para o desenvolvedor. |\n" +"| `APP_DEBUG` | Ativa saída de erros detalhada e painéis de debug. |\n" +"| `SERVER_NAME` | Endereço do servidor Caddy — `:80` significa escutar em todas as interfaces na porta 80. |\n" +"| `XDEBUG_MODE` | Modo do Xdebug. Use `develop` para helpers e `debug` para ativar a depuração passo a passo. |\n" +"| `COMPOSER_CACHE_DIR` | Move o cache do Composer para o volume montado, para que persista entre execuções. |\n" #. type: Title ### #: ../src/guide/tutorial/docker.md #, no-wrap msgid "docker/test/.env" -msgstr "" +msgstr "docker/test/.env" #. type: Plain text #: ../src/guide/tutorial/docker.md msgid "Contains application environment variables for the test container:" -msgstr "" +msgstr "Contém as variáveis de ambiente da aplicação para o container de testes:" #. type: Fenced code block (ini) #: ../src/guide/tutorial/docker.md @@ -238,6 +301,15 @@ msgid "" "XDEBUG_MODE=coverage\n" "COMPOSER_CACHE_DIR=/app/runtime/cache/composer\n" msgstr "" +"# Ambiente test da aplicação.\n" +"# Note que as variáveis ficam disponíveis apenas na aplicação, não no compose.yml.\n" +"\n" +"APP_ENV=test\n" +"APP_DEBUG=false\n" +"APP_C3=true\n" +"SERVER_NAME=:80\n" +"XDEBUG_MODE=coverage\n" +"COMPOSER_CACHE_DIR=/app/runtime/cache/composer\n" #. type: Plain text #: ../src/guide/tutorial/docker.md @@ -252,17 +324,25 @@ msgid "" "| `XDEBUG_MODE` | `coverage` activates Xdebug's code coverage driver required for coverage reports. |\n" "| `COMPOSER_CACHE_DIR` | Persistent Composer cache inside the volume. |\n" msgstr "" +"| Variável | Finalidade |\n" +"|----------------------|-----------------------------------------------------------------------------------------------|\n" +"| `APP_ENV` | Define o ambiente como `test` para que a aplicação carregue a configuração específica de testes. |\n" +"| `APP_DEBUG` | Desativado nos testes para corresponder a um contexto de execução realista. |\n" +"| `APP_C3` | Ativa a coleta remota de cobertura de código com [c3](https://github.com/Codeception/c3). |\n" +"| `SERVER_NAME` | Endereço do servidor Caddy. |\n" +"| `XDEBUG_MODE` | `coverage` ativa o driver de cobertura de código do Xdebug, necessário para os relatórios de cobertura. |\n" +"| `COMPOSER_CACHE_DIR` | Cache persistente do Composer dentro do volume. |\n" #. type: Title ### #: ../src/guide/tutorial/docker.md #, no-wrap msgid "docker/prod/.env" -msgstr "" +msgstr "docker/prod/.env" #. type: Plain text #: ../src/guide/tutorial/docker.md msgid "Contains application environment variables for the production container:" -msgstr "" +msgstr "Contém as variáveis de ambiente da aplicação para o container de produção:" #. type: Fenced code block (ini) #: ../src/guide/tutorial/docker.md @@ -275,22 +355,28 @@ msgid "" "APP_DEBUG=false\n" "SERVER_NAME=:80\n" msgstr "" +"# Ambiente prod da aplicação.\n" +"# Note que as variáveis ficam disponíveis apenas na aplicação, não no compose.yml.\n" +"\n" +"APP_ENV=prod\n" +"APP_DEBUG=false\n" +"SERVER_NAME=:80\n" #. type: Plain text #: ../src/guide/tutorial/docker.md msgid "The production environment intentionally uses a minimal configuration. Secrets and host-specific overrides should be managed through deployment tooling and never committed to version control." -msgstr "" +msgstr "O ambiente de produção usa intencionalmente uma configuração mínima. Segredos e overrides específicos de host devem ser gerenciados pelas ferramentas de deploy e nunca commitados no controle de versão." #. type: Title ### #: ../src/guide/tutorial/docker.md #, no-wrap msgid "Override env files" -msgstr "" +msgstr "Arquivos env de override" #. type: Plain text #: ../src/guide/tutorial/docker.md msgid "Each environment directory contains a `.gitignore` that excludes an `override.env` file. This file is optional and, when present, is merged on top of the main `.env` for that environment:" -msgstr "" +msgstr "Cada diretório de ambiente contém um `.gitignore` que exclui um arquivo `override.env`. Esse arquivo é opcional e, quando presente, é mesclado por cima do `.env` principal daquele ambiente:" #. type: Fenced code block #: ../src/guide/tutorial/docker.md @@ -299,44 +385,46 @@ msgid "" "# docker/dev/override.env.example\n" "APP_HOST_PATH=/projects/yiisoft/app\n" msgstr "" +"# docker/dev/override.env.example\n" +"APP_HOST_PATH=/projects/yiisoft/app\n" #. type: Plain text #: ../src/guide/tutorial/docker.md msgid "Copy the example file to create your local overrides:" -msgstr "" +msgstr "Copie o arquivo de exemplo para criar seus overrides locais:" #. type: Fenced code block (sh) #: ../src/guide/tutorial/docker.md #, no-wrap msgid "cp docker/dev/override.env.example docker/dev/override.env\n" -msgstr "" +msgstr "cp docker/dev/override.env.example docker/dev/override.env\n" #. type: Plain text #: ../src/guide/tutorial/docker.md msgid "Use override files for developer-specific settings such as Xdebug IDE keys or local bind paths that should not be shared with the team." -msgstr "" +msgstr "Use arquivos de override para configurações específicas do desenvolvedor, como chaves de IDE do Xdebug ou caminhos locais de bind, que não devem ser compartilhados com o time." #. type: Title ## #: ../src/guide/tutorial/docker.md #, no-wrap msgid "Compose files" -msgstr "" +msgstr "Arquivos Compose" #. type: Plain text #: ../src/guide/tutorial/docker.md msgid "The Compose configuration is split across multiple files that Docker Compose merges at runtime. This approach avoids duplicating shared settings and keeps each environment's file focused and small." -msgstr "" +msgstr "A configuração do Compose é dividida em vários arquivos que o Docker Compose mescla em tempo de execução. Essa abordagem evita duplicar configurações compartilhadas e mantém o arquivo de cada ambiente pequeno e focado." #. type: Title ### #: ../src/guide/tutorial/docker.md #, no-wrap msgid "docker/compose.yml (base)" -msgstr "" +msgstr "docker/compose.yml (base)" #. type: Plain text #: ../src/guide/tutorial/docker.md msgid "The base file defines shared settings inherited by all environments:" -msgstr "" +msgstr "O arquivo base define configurações compartilhadas herdadas por todos os ambientes:" #. type: Fenced code block (yaml) #: ../src/guide/tutorial/docker.md @@ -351,27 +439,35 @@ msgid "" " caddy_data:\n" " caddy_config:\n" msgstr "" +"services:\n" +" app: &appconfig\n" +" extra_hosts:\n" +" - \"host.docker.internal:host-gateway\"\n" +"\n" +"volumes:\n" +" caddy_data:\n" +" caddy_config:\n" #. type: Plain text #: ../src/guide/tutorial/docker.md msgid "The `&appconfig` YAML anchor lets environment files reference and extend this service definition. The `host.docker.internal` entry maps to the Docker host so containers can reach services running on the host machine (for example, a local database)." -msgstr "" +msgstr "A âncora YAML `&appconfig` permite que os arquivos de ambiente referenciem e estendam essa definição de serviço. A entrada `host.docker.internal` aponta para o host Docker, para que os containers alcancem serviços rodando na máquina host (por exemplo, um banco de dados local)." #. type: Plain text #: ../src/guide/tutorial/docker.md msgid "The two named volumes (`caddy_data` and `caddy_config`) persist Caddy's certificate storage and configuration across container restarts." -msgstr "" +msgstr "Os dois volumes nomeados (`caddy_data` e `caddy_config`) persistem o armazenamento de certificados e a configuração do Caddy entre reinicializações do container." #. type: Title ### #: ../src/guide/tutorial/docker.md #, no-wrap msgid "docker/dev/compose.yml" -msgstr "" +msgstr "docker/dev/compose.yml" #. type: Plain text #: ../src/guide/tutorial/docker.md msgid "Extends the base file for local development:" -msgstr "" +msgstr "Estende o arquivo base para desenvolvimento local:" #. type: Fenced code block (yaml) #: ../src/guide/tutorial/docker.md @@ -399,58 +495,79 @@ msgid "" " - caddy_config:/config\n" " tty: true\n" msgstr "" +"services:\n" +" app:\n" +" build:\n" +" dockerfile: docker/Dockerfile\n" +" context: ..\n" +" target: dev\n" +" args:\n" +" USER_ID: ${UID}\n" +" GROUP_ID: ${GID}\n" +" env_file:\n" +" - path: ./dev/.env\n" +" - path: ./dev/override.env\n" +" required: false\n" +" ports:\n" +" - \"${DEV_PORT:-80}:80\"\n" +" volumes:\n" +" - ../:/app\n" +" - ../runtime:/app/runtime\n" +" - caddy_data:/data\n" +" - caddy_config:/config\n" +" tty: true\n" #. type: Plain text #: ../src/guide/tutorial/docker.md msgid "Key points:" -msgstr "" +msgstr "Pontos principais:" #. type: Bullet: '- ' #: ../src/guide/tutorial/docker.md msgid "**`target: dev`** — Selects the `dev` stage from the multi-stage Dockerfile." -msgstr "" +msgstr "**`target: dev`** — Seleciona o estágio `dev` do Dockerfile multi-stage." #. type: Bullet: '- ' #: ../src/guide/tutorial/docker.md msgid "**`USER_ID` / `GROUP_ID`** — Passed as build arguments so the container user matches the host user, preventing file permission issues on Linux." -msgstr "" +msgstr "**`USER_ID` / `GROUP_ID`** — Passados como argumentos de build para que o usuário do container corresponda ao usuário do host, evitando problemas de permissão de arquivos no Linux." #. type: Bullet: '- ' #: ../src/guide/tutorial/docker.md msgid "**`env_file`** — Loads `docker/dev/.env` and, optionally, the developer's local `override.env`." -msgstr "" +msgstr "**`env_file`** — Carrega `docker/dev/.env` e, opcionalmente, o `override.env` local do desenvolvedor." #. type: Bullet: '- ' #: ../src/guide/tutorial/docker.md msgid "**`ports`** — Exposes port 80 (or `DEV_PORT` from `docker/.env`) on the host." -msgstr "" +msgstr "**`ports`** — Expõe a porta 80 (ou `DEV_PORT` de `docker/.env`) no host." #. type: Bullet: '- ' #: ../src/guide/tutorial/docker.md msgid "**`volumes`** — Mounts the entire project into `/app` so code changes are reflected immediately without rebuilding the image." -msgstr "" +msgstr "**`volumes`** — Monta o projeto inteiro em `/app` para que mudanças no código sejam refletidas imediatamente, sem rebuild da imagem." #. type: Title ### #: ../src/guide/tutorial/docker.md #, no-wrap msgid "docker/test/compose.yml" -msgstr "" +msgstr "docker/test/compose.yml" #. type: Plain text #: ../src/guide/tutorial/docker.md msgid "Identical in structure to the dev file but loads `docker/test/.env` and does not expose ports to the host, since tests run entirely inside the container network." -msgstr "" +msgstr "Tem a mesma estrutura do arquivo dev, mas carrega `docker/test/.env` e não expõe portas para o host, já que os testes rodam inteiramente dentro da rede de containers." #. type: Title ### #: ../src/guide/tutorial/docker.md #, no-wrap msgid "docker/prod/compose.yml" -msgstr "" +msgstr "docker/prod/compose.yml" #. type: Plain text #: ../src/guide/tutorial/docker.md msgid "Targets production deployments using Docker Swarm:" -msgstr "" +msgstr "Voltado a deploys em produção usando Docker Swarm:" #. type: Fenced code block (yaml) #: ../src/guide/tutorial/docker.md @@ -496,11 +613,50 @@ msgid "" " caddy_public:\n" " external: true\n" msgstr "" +"services:\n" +" app:\n" +" image: ${IMAGE}:${IMAGE_TAG}\n" +" networks:\n" +" - caddy_public\n" +" volumes:\n" +" - runtime:/app/runtime\n" +" - caddy_data:/data\n" +" - caddy_config:/config\n" +" env_file:\n" +" - path: ./prod/.env\n" +" - path: ./prod/override.env\n" +" required: false\n" +" deploy:\n" +" replicas: 2\n" +" update_config:\n" +" delay: 10s\n" +" parallelism: 1\n" +" order: start-first\n" +" failure_action: rollback\n" +" monitor: 10s\n" +" rollback_config:\n" +" parallelism: 0\n" +" order: stop-first\n" +" restart_policy:\n" +" condition: on-failure\n" +" delay: 5s\n" +" max_attempts: 3\n" +" window: 120s\n" +" labels:\n" +" caddy: ${PROD_HOST:-app.example.com}\n" +" caddy.reverse_proxy: \"{{upstreams 80}}\"\n" +"\n" +"volumes:\n" +" runtime:\n" +"\n" +"networks:\n" +" caddy_public:\n" +" external: true\n" #. type: Plain text #: ../src/guide/tutorial/docker.md msgid "Instead of building an image, the production file references a pre-built image (`${IMAGE}:${IMAGE_TAG}`). The `deploy` block configures Docker Swarm behaviour: two replicas with a rolling `start-first` update strategy and automatic rollback on failure. The `caddy` labels are picked up by a [Caddy Docker Proxy](https://github.com/lucaslorentz/caddy-docker-proxy) running in the same Swarm to configure automatic HTTPS routing." -msgstr "" +msgstr "Em vez de fazer build de uma imagem, o arquivo de produção referencia uma imagem pré-construída (`${IMAGE}:${IMAGE_TAG}`). O bloco `deploy` configura o comportamento do Docker Swarm: duas réplicas com estratégia de atualização gradual `start-first` e rollback automático em caso de falha. Os labels `caddy` são lidos por um [Caddy Docker Proxy](https://github.com/lucaslorentz/caddy-docker-proxy) rodando no mesmo Swarm para configurar o roteamento HTTPS automático." #. type: Plain text #: ../src/guide/tutorial/docker.md @@ -510,17 +666,20 @@ msgid "" "> The `caddy_public` network must already exist on the Swarm before deploying.\n" "> See the [Docker Swarm deployment guide](../../cookbook/deployment/docker-swarm.md) for full setup instructions.\n" msgstr "" +"> [!NOTE]\n" +"> A rede `caddy_public` precisa existir no Swarm antes do deploy.\n" +"> Veja o [guia de deploy com Docker Swarm](../../cookbook/deployment/docker-swarm.md) para instruções completas de configuração.\n" #. type: Title ## #: ../src/guide/tutorial/docker.md #, no-wrap msgid "Multi-stage Dockerfile" -msgstr "" +msgstr "Dockerfile multi-stage" #. type: Plain text #: ../src/guide/tutorial/docker.md msgid "The `docker/Dockerfile` uses [multi-stage builds](https://docs.docker.com/build/building/multi-stage/) to produce lean images for each purpose from a single file, avoiding duplication of the base setup:" -msgstr "" +msgstr "O `docker/Dockerfile` usa [builds multi-stage](https://docs.docker.com/build/building/multi-stage/) para produzir imagens enxutas para cada finalidade a partir de um único arquivo, evitando duplicar a configuração base:" #. type: Fenced code block (dockerfile) #: ../src/guide/tutorial/docker.md @@ -576,11 +735,60 @@ msgid "" "COPY --from=prod-builder --chown=www-data:www-data /app /app\n" "USER www-data\n" msgstr "" +"FROM composer/composer:2-bin AS composer\n" +"\n" +"FROM dunglas/frankenphp:1-php8.2-bookworm AS base\n" +"\n" +"RUN apt update && apt -y install \\\n" +" unzip\n" +"\n" +"RUN install-php-extensions \\\n" +" opcache mbstring intl dom ctype curl phar openssl xml xmlwriter simplexml pdo\n" +"\n" +"ENV LC_ALL=C.UTF-8\n" +"\n" +"#\n" +"# Development\n" +"#\n" +"\n" +"FROM base AS dev\n" +"ARG USER_ID=10001\n" +"ARG GROUP_ID=10001\n" +"ARG USER_NAME=appuser\n" +"ARG GROUP_NAME=appuser\n" +"\n" +"RUN install-php-extensions xdebug\n" +"\n" +"COPY --from=composer /composer /usr/bin/composer\n" +"\n" +"RUN \\\n" +" groupadd --gid ${GROUP_ID} ${GROUP_NAME}; \\\n" +" useradd --gid ${GROUP_ID} --uid ${USER_ID} ${GROUP_NAME}; \\\n" +" setcap CAP_NET_BIND_SERVICE=+eip /usr/local/bin/frankenphp; \\\n" +" chown -R ${USER_NAME}:${GROUP_NAME} /data/caddy && \\\n" +" chown -R ${USER_NAME}:${GROUP_NAME} /config/caddy\n" +"USER ${USER_NAME}\n" +"\n" +"#\n" +"# Production\n" +"#\n" +"\n" +"FROM base AS prod-builder\n" +"COPY --from=composer /composer /usr/bin/composer\n" +"COPY .. /app\n" +"RUN --mount=type=cache,target=/tmp/cache \\\n" +" composer install --no-dev --no-progress --no-interaction --classmap-authoritative && \\\n" +" rm composer.lock composer.json\n" +"\n" +"FROM base AS prod\n" +"ENV APP_ENV=prod\n" +"COPY --from=prod-builder --chown=www-data:www-data /app /app\n" +"USER www-data\n" #. type: Plain text #: ../src/guide/tutorial/docker.md msgid "The Dockerfile defines four stages:" -msgstr "" +msgstr "O Dockerfile define quatro estágios:" #. type: Plain text #: ../src/guide/tutorial/docker.md @@ -594,6 +802,13 @@ msgid "" "| `prod-builder` | Extends `base`, copies the application source, and runs `composer install --no-dev` using a build cache. Removes `composer.lock` and `composer.json` afterwards to keep the final image clean. |\n" "| `prod` | Copies only the built application from `prod-builder` into a clean `base` image. This produces a small final image because the Composer binary and intermediate files are not included. |\n" msgstr "" +"| Estágio | Finalidade |\n" +"|----------------|--------------------------------------------------------------------------------------------------|\n" +"| `composer` | Copia o binário do Composer da imagem oficial para evitar instalá-lo nos outros estágios. |\n" +"| `base` | Instala o FrankenPHP, extensões PHP comuns e pacotes de sistema compartilhados por todos os ambientes. |\n" +"| `dev` | Estende `base` com Xdebug e Composer. Cria um usuário não root com o mesmo UID/GID do usuário do host para evitar problemas de permissão com volumes montados. |\n" +"| `prod-builder` | Estende `base`, copia o código-fonte da aplicação e executa `composer install --no-dev` usando um cache de build. Remove `composer.lock` e `composer.json` em seguida para manter a imagem final limpa. |\n" +"| `prod` | Copia apenas a aplicação construída de `prod-builder` para uma imagem `base` limpa. Isso gera uma imagem final pequena, porque o binário do Composer e os arquivos intermediários não são incluídos. |\n" #. type: Plain text #: ../src/guide/tutorial/docker.md @@ -603,28 +818,31 @@ msgid "" "> When building the production image you select a specific stage with `--target prod`. The `prod-builder`\n" "> stage is an intermediate step and is never pushed to a registry.\n" msgstr "" +"> [!TIP]\n" +"> Ao construir a imagem de produção, você seleciona um estágio específico com `--target prod`. O estágio `prod-builder`\n" +"> é um passo intermediário e nunca é enviado para um registry.\n" #. type: Plain text #: ../src/guide/tutorial/docker.md msgid "The `dev` target is selected when running `make up` or `make build`, while `make prod-build` targets `prod`." -msgstr "" +msgstr "O alvo `dev` é selecionado ao executar `make up` ou `make build`, enquanto `make prod-build` usa o alvo `prod`." #. type: Title ## #: ../src/guide/tutorial/docker.md #, no-wrap msgid "make commands" -msgstr "" +msgstr "Comandos make" #. type: Plain text #: ../src/guide/tutorial/docker.md msgid "The `Makefile` provides a convenient interface for all common Docker operations. Run `make` or `make help` to list available targets with their descriptions." -msgstr "" +msgstr "O `Makefile` oferece uma interface prática para todas as operações Docker comuns. Execute `make` ou `make help` para listar os alvos disponíveis com suas descrições." #. type: Title ### #: ../src/guide/tutorial/docker.md #, no-wrap msgid "Development" -msgstr "" +msgstr "Desenvolvimento" #. type: Plain text #: ../src/guide/tutorial/docker.md @@ -639,17 +857,25 @@ msgid "" "| `make clear` | Remove all development containers, networks, and volumes. |\n" "| `make shell` | Open an interactive Bash shell inside the running `app` container. |\n" msgstr "" +"| Comando | Descrição |\n" +"|---------------|----------------------------------------------------------------|\n" +"| `make build` | Faz o build (ou rebuild) da imagem Docker de desenvolvimento. |\n" +"| `make up` | Inicia o ambiente de desenvolvimento em modo detached. |\n" +"| `make down` | Para e remove containers, redes e serviços órfãos. |\n" +"| `make stop` | Para os containers em execução sem removê-los. |\n" +"| `make clear` | Remove todos os containers, redes e volumes de desenvolvimento. |\n" +"| `make shell` | Abre um shell Bash interativo dentro do container `app` em execução. |\n" #. type: Title ### #: ../src/guide/tutorial/docker.md #, no-wrap msgid "Running tools" -msgstr "" +msgstr "Executando ferramentas" #. type: Plain text #: ../src/guide/tutorial/docker.md msgid "Commands in this group run inside the development container using `docker compose run --rm`, so they work even when the container is not currently running:" -msgstr "" +msgstr "Os comandos deste grupo rodam dentro do container de desenvolvimento usando `docker compose run --rm`, então funcionam mesmo quando o container não está em execução:" #. type: Plain text #: ../src/guide/tutorial/docker.md @@ -664,6 +890,14 @@ msgid "" "| `make psalm` | Run [Psalm](https://psalm.dev/) static analysis. |\n" "| `make composer-dependency-analyser` | Run [Composer Dependency Analyser](https://github.com/shipmonk-rnd/composer-dependency-analyser). |\n" msgstr "" +"| Comando | Descrição |\n" +"|--------------------------------------|-------------------------------------------------|\n" +"| `make yii ` | Executa um comando de console `./yii`. |\n" +"| `make composer ` | Executa o Composer. |\n" +"| `make rector` | Executa o [Rector](https://getrector.com/) para refatoração automatizada de PHP e melhorias de qualidade de código. |\n" +"| `make cs-fix` | Executa o [PHP CS Fixer](https://cs.symfony.com/). |\n" +"| `make psalm` | Executa a análise estática do [Psalm](https://psalm.dev/). |\n" +"| `make composer-dependency-analyser` | Executa o [Composer Dependency Analyser](https://github.com/shipmonk-rnd/composer-dependency-analyser). |\n" #. type: Plain text #: ../src/guide/tutorial/docker.md @@ -675,12 +909,17 @@ msgid "" "| `make test-coverage` | Run tests and generate an HTML coverage report. |\n" "| `make codecept ` | Run any Codeception command with custom arguments. |\n" msgstr "" +"| Comando | Descrição |\n" +"|------------------------|-----------------------------------------------------------|\n" +"| `make test` | Executa a suíte de testes completa com Codeception. |\n" +"| `make test-coverage` | Executa os testes e gera um relatório de cobertura em HTML. |\n" +"| `make codecept ` | Executa qualquer comando do Codeception com argumentos personalizados. |\n" #. type: Title ### #: ../src/guide/tutorial/docker.md #, no-wrap msgid "Production" -msgstr "" +msgstr "Produção" #. type: Plain text #: ../src/guide/tutorial/docker.md @@ -692,6 +931,11 @@ msgid "" "| `make prod-push` | Push the built image to the registry defined by `IMAGE` and `IMAGE_TAG`. |\n" "| `make prod-deploy` | Deploy the stack to a remote Docker Swarm node defined by `PROD_SSH`. |\n" msgstr "" +"| Comando | Descrição |\n" +"|----------------------|-------------------------------------------------------------------------------------|\n" +"| `make prod-build` | Faz o build local da imagem Docker de produção (`--target prod`). |\n" +"| `make prod-push` | Envia a imagem construída para o registry definido por `IMAGE` e `IMAGE_TAG`. |\n" +"| `make prod-deploy` | Faz o deploy da stack em um nó Docker Swarm remoto definido por `PROD_SSH`. |\n" #. type: Plain text #: ../src/guide/tutorial/docker.md @@ -707,3 +951,12 @@ msgid "" "> make test -- Unit\n" "> ```\n" msgstr "" +"> [!TIP]\n" +"> A maioria dos comandos aceita argumentos adicionais. Por exemplo, para instalar um pacote específico:\n" +"> ```sh\n" +"> make composer require yiisoft/yii-db-mysql\n" +"> ```\n" +"> Para executar uma única suíte de testes:\n" +"> ```sh\n" +"> make test -- Unit\n" +"> ```\n" diff --git a/_translations/po/pt-BR/guide_tutorial_i18n.md.po b/_translations/po/pt-BR/guide_tutorial_i18n.md.po index 199fe64f..7e4039b0 100644 --- a/_translations/po/pt-BR/guide_tutorial_i18n.md.po +++ b/_translations/po/pt-BR/guide_tutorial_i18n.md.po @@ -8,106 +8,103 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-06-02 22:29+0000\n" "PO-Revision-Date: 2026-06-02 22:29+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Fenced code block (sh) -#: ../src/cookbook/using-yii-in-third-party-apps.md -#: ../src/guide/structure/designing-packages.md -#: ../src/guide/structure/module.md ../src/guide/structure/package.md -#: ../src/guide/tutorial/i18n.md +#: ../src/cookbook/using-yii-in-third-party-apps.md ../src/guide/structure/designing-packages.md ../src/guide/structure/module.md ../src/guide/structure/package.md ../src/guide/tutorial/i18n.md #, no-wrap msgid "composer yii-config-rebuild\n" -msgstr "" +msgstr "composer yii-config-rebuild\n" #. type: Title # #: ../src/guide/intro/upgrade-from-v1.md ../src/guide/tutorial/i18n.md #, no-wrap msgid "Internationalization" -msgstr "" +msgstr "Internacionalização" #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "Internationalization prepares an application for more than one locale. Localization is the locale-specific part: translated text, plural forms, date and number formats, and view templates for a locale such as `en-US` or `de`." -msgstr "" +msgstr "A internacionalização prepara uma aplicação para mais de um locale. A localização é a parte específica de cada locale: textos traduzidos, formas de plural, formatos de data e número e templates de view para um locale como `en-US` ou `de`." #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "In a Yii application, the usual parts are:" -msgstr "" +msgstr "Numa aplicação Yii, as partes habituais são:" #. type: Bullet: '- ' #: ../src/guide/tutorial/i18n.md msgid "locale selection for the current request;" -msgstr "" +msgstr "a escolha do idioma da requisição atual;" #. type: Bullet: '- ' #: ../src/guide/tutorial/i18n.md msgid "translated application messages;" -msgstr "" +msgstr "as mensagens traduzidas da aplicação;" #. type: Bullet: '- ' #: ../src/guide/tutorial/i18n.md msgid "plural and parameter formatting;" -msgstr "" +msgstr "a formatação de plurais e parâmetros;" #. type: Bullet: '- ' #: ../src/guide/tutorial/i18n.md msgid "localized view templates for pages that need different markup." -msgstr "" +msgstr "templates de view localizados para páginas que precisam de marcação diferente." #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "This tutorial assumes a new [yiisoft/app](https://github.com/yiisoft/app) project." -msgstr "" +msgstr "Este tutorial parte de um projeto novo do [yiisoft/app](https://github.com/yiisoft/app)." #. type: Title ## #: ../src/guide/tutorial/i18n.md #, no-wrap msgid "Install packages" -msgstr "" +msgstr "Instalando os pacotes" #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "`yiisoft/app` already includes `yiisoft/i18n` and `yiisoft/translator`. Install PHP-file message storage:" -msgstr "" +msgstr "O `yiisoft/app` já inclui `yiisoft/i18n` e `yiisoft/translator`. Instale o armazenamento de mensagens em arquivos PHP:" #. type: Fenced code block (sh) #: ../src/guide/tutorial/i18n.md #, no-wrap msgid "composer require yiisoft/translator-message-php\n" -msgstr "" +msgstr "composer require yiisoft/translator-message-php\n" #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "Install the extractor as a development dependency:" -msgstr "" +msgstr "Instale o extrator como dependência de desenvolvimento:" #. type: Fenced code block (sh) #: ../src/guide/tutorial/i18n.md #, no-wrap msgid "composer require --dev yiisoft/translator-extractor\n" -msgstr "" +msgstr "composer require --dev yiisoft/translator-extractor\n" #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "The examples use ICU message formatting for plural forms. Make sure the PHP `intl` extension is enabled. For simple placeholders only, use `Yiisoft\\Translator\\SimpleMessageFormatter` in the configuration below." -msgstr "" +msgstr "Os exemplos usam a formatação de mensagens ICU para as formas de plural. Confira se a extensão `intl` do PHP está habilitada. Se você só precisa de placeholders simples, use `Yiisoft\\Translator\\SimpleMessageFormatter` na configuração abaixo." #. type: Title ## #: ../src/guide/tutorial/i18n.md #, no-wrap msgid "Configure application locale" -msgstr "" +msgstr "Configurando o idioma da aplicação" #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "The application template keeps basic application settings in `config/common/application.php`. Set the source locale there:" -msgstr "" +msgstr "O template da aplicação guarda as configurações básicas em `config/common/application.php`. Defina ali o idioma de origem:" #. type: Fenced code block (php) #: ../src/guide/tutorial/i18n.md @@ -123,6 +120,15 @@ msgid "" " 'name' => 'My Project',\n" "];\n" msgstr "" +" 'UTF-8',\n" +" 'locale' => 'en-US',\n" +" 'name' => 'My Project',\n" +"];\n" #. type: Plain text #: ../src/guide/tutorial/i18n.md @@ -132,11 +138,14 @@ msgid "" "When your application chooses locale per request, set the selected locale on the view as shown in\n" "[Choosing locale per request](#choosing-locale-per-request).\n" msgstr "" +"O layout padrão usa esse valor no atributo `` por meio de `ApplicationParams`.\n" +"Quando a aplicação escolhe o idioma por requisição, defina o idioma escolhido na view, como mostrado em\n" +"[Escolhendo o idioma por requisição](#escolhendo-o-idioma-por-requisicao).\n" #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "Configure translator defaults in `config/common/params.php`:" -msgstr "" +msgstr "Configure os padrões do tradutor em `config/common/params.php`:" #. type: Fenced code block (php) #: ../src/guide/tutorial/i18n.md @@ -148,22 +157,27 @@ msgid "" " 'defaultCategory' => 'app',\n" "],\n" msgstr "" +"'yiisoft/translator' => [\n" +" 'locale' => 'en-US',\n" +" 'fallbackLocale' => 'en-US',\n" +" 'defaultCategory' => 'app',\n" +"],\n" #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "`locale` is the default translation locale. `fallbackLocale` is used when a translation is missing for the current locale. `defaultCategory` is the category used when a call to `translate()` does not specify one." -msgstr "" +msgstr "`locale` é o idioma padrão das traduções. `fallbackLocale` é usado quando falta uma tradução para o idioma atual. `defaultCategory` é a categoria usada quando uma chamada a `translate()` não especifica nenhuma." #. type: Title ## #: ../src/guide/tutorial/i18n.md #, no-wrap msgid "Configure message storage" -msgstr "" +msgstr "Configurando o armazenamento de mensagens" #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "Create `config/common/di/translator.php`:" -msgstr "" +msgstr "Crie `config/common/di/translator.php`:" #. type: Fenced code block (php) #: ../src/guide/tutorial/i18n.md @@ -196,16 +210,42 @@ msgid "" " ],\n" "];\n" msgstr "" +" [\n" +" 'definition' => static function (Aliases $aliases) use ($params): CategorySource {\n" +" $messageSource = new MessageSource($aliases->get('@root/messages'));\n" +"\n" +" return new CategorySource(\n" +" $params['yiisoft/translator']['defaultCategory'],\n" +" $messageSource,\n" +" new IntlMessageFormatter(),\n" +" $messageSource,\n" +" );\n" +" },\n" +" 'tags' => ['translation.categorySource'],\n" +" ],\n" +"];\n" #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "This registers the `app` category. The `MessageSource` reads PHP arrays from the `messages/` directory and writes extracted messages back to the same directory." -msgstr "" +msgstr "Isso registra a categoria `app`. O `MessageSource` lê arrays PHP do diretório `messages/` e grava as mensagens extraídas de volta no mesmo diretório." #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "Create the source and target message files:" -msgstr "" +msgstr "Crie os arquivos de mensagens de origem e de destino:" #. type: Fenced code block #: ../src/guide/tutorial/i18n.md @@ -217,11 +257,16 @@ msgid "" "└── en-US/\n" " └── app.php\n" msgstr "" +"messages/\n" +"├── de/\n" +"│ └── app.php\n" +"└── en-US/\n" +" └── app.php\n" #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "`messages/en-US/app.php`:" -msgstr "" +msgstr "`messages/en-US/app.php`:" #. type: Fenced code block (php) #: ../src/guide/tutorial/i18n.md @@ -235,11 +280,18 @@ msgid "" " 'cart.items' => '{count, plural, =0{No items} one{# item} other{# items}}',\n" "];\n" msgstr "" +" 'Home',\n" +" 'home.welcome' => 'Welcome to Yii3',\n" +" 'cart.items' => '{count, plural, =0{No items} one{# item} other{# items}}',\n" +"];\n" #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "`messages/de/app.php`:" -msgstr "" +msgstr "`messages/de/app.php`:" #. type: Fenced code block (php) #: ../src/guide/tutorial/i18n.md @@ -253,17 +305,24 @@ msgid "" " 'cart.items' => '{count, plural, =0{Keine Artikel} one{# Artikel} other{# Artikel}}',\n" "];\n" msgstr "" +" 'Home',\n" +" 'home.welcome' => 'Willkommen bei Yii3',\n" +" 'cart.items' => '{count, plural, =0{Keine Artikel} one{# Artikel} other{# Artikel}}',\n" +"];\n" #. type: Title ## #: ../src/guide/tutorial/i18n.md #, no-wrap msgid "Translate messages" -msgstr "" +msgstr "Traduzindo mensagens" #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "Inject `Yiisoft\\Translator\\TranslatorInterface` where you prepare data for a response. For the default home page action, update `src/Web/HomePage/Action.php`:" -msgstr "" +msgstr "Injete `Yiisoft\\Translator\\TranslatorInterface` onde você prepara os dados de uma resposta. Para a action padrão da página inicial, altere `src/Web/HomePage/Action.php`:" #. type: Fenced code block (php) #: ../src/guide/tutorial/i18n.md @@ -295,11 +354,36 @@ msgid "" " }\n" "}\n" msgstr "" +"viewRenderer->render(__DIR__ . '/template', [\n" +" 'itemCount' => 3,\n" +" 'translator' => $this->translator,\n" +" ]);\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "Use the translator in `src/Web/HomePage/template.php`:" -msgstr "" +msgstr "Use o tradutor em `src/Web/HomePage/template.php`:" #. type: Fenced code block (php) #: ../src/guide/tutorial/i18n.md @@ -330,22 +414,46 @@ msgid "" "

translate('cart.items', ['count' => $itemCount])) ?>

\n" "\n" msgstr "" +"setTitle($translator->translate('home.title'));\n" +"?>\n" +"\n" +"
\n" +"

translate('home.welcome')) ?>

\n" +"\n" +"

translate('cart.items', ['count' => $itemCount])) ?>

\n" +"
\n" #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "Escape translated text before output. Store trusted HTML separately or render it from a view template." -msgstr "" +msgstr "Escape o texto traduzido antes de exibi-lo. Guarde HTML confiável separadamente ou renderize-o a partir de um template de view." #. type: Title ## #: ../src/guide/tutorial/i18n.md #, no-wrap msgid "Choosing locale per request" -msgstr "" +msgstr "Escolhendo o idioma por requisição" #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "For a web application, choose locale early in the middleware stack and apply it to both the translator and the view. The example below uses the `lang` query parameter and a fixed allow list:" -msgstr "" +msgstr "Numa aplicação web, escolha o idioma cedo na pilha de middlewares e aplique-o tanto ao tradutor quanto à view. O exemplo abaixo usa o parâmetro `lang` da query string e uma lista fixa de idiomas permitidos:" #. type: Fenced code block (php) #: ../src/guide/tutorial/i18n.md @@ -394,11 +502,53 @@ msgid "" " }\n" "}\n" msgstr "" +"getLocale($request);\n" +"\n" +" $this->translator->setLocale($locale);\n" +" $this->view->setLocale($locale);\n" +"\n" +" return $handler->handle($request);\n" +" }\n" +"\n" +" private function getLocale(ServerRequestInterface $request): string\n" +" {\n" +" $locale = $request->getQueryParams()['lang'] ?? null;\n" +"\n" +" return is_string($locale) && in_array($locale, self::SUPPORTED_LOCALES, true)\n" +" ? $locale\n" +" : self::DEFAULT_LOCALE;\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "Register the middleware in `config/common/routes.php` or in the route group that needs localized output. Add middleware before the route action:" -msgstr "" +msgstr "Registre o middleware em `config/common/routes.php` ou no grupo de rotas que precisa de saída localizada. Adicione o middleware antes da action da rota:" #. type: Fenced code block (php) #: ../src/guide/tutorial/i18n.md @@ -414,27 +564,36 @@ msgid "" " ->name('home'),\n" "];\n" msgstr "" +"use App\\Web\\Middleware\\LocaleMiddleware;\n" +"use Yiisoft\\Router\\Route;\n" +"\n" +"return [\n" +" Route::get('/')\n" +" ->middleware(LocaleMiddleware::class)\n" +" ->action(App\\Web\\HomePage\\Action::class)\n" +" ->name('home'),\n" +"];\n" #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "Update `src/Web/Shared/Layout/Main/layout.php` to read the locale from the current view state:" -msgstr "" +msgstr "Altere `src/Web/Shared/Layout/Main/layout.php` para ler o idioma do estado atual da view:" #. type: Fenced code block (php) #: ../src/guide/tutorial/i18n.md #, no-wrap msgid "getLocale()) ?>\">\n" -msgstr "" +msgstr "getLocale()) ?>\">\n" #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "Use the same approach when locale is stored in a session, a cookie, a user profile, or a route parameter." -msgstr "" +msgstr "Use a mesma abordagem quando o idioma estiver guardado na sessão, num cookie, no perfil do usuário ou num parâmetro de rota." #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "`yiisoft/i18n` provides `Yiisoft\\I18n\\Locale` for working with BCP 47 locale codes:" -msgstr "" +msgstr "O `yiisoft/i18n` oferece `Yiisoft\\I18n\\Locale` para trabalhar com códigos de locale BCP 47:" #. type: Fenced code block (php) #: ../src/guide/tutorial/i18n.md @@ -448,52 +607,59 @@ msgid "" "echo $locale->region(); // DE\n" "echo $locale->fallbackLocale()->asString(); // de\n" msgstr "" +"use Yiisoft\\I18n\\Locale;\n" +"\n" +"$locale = new Locale('de-DE');\n" +"\n" +"echo $locale->language(); // de\n" +"echo $locale->region(); // DE\n" +"echo $locale->fallbackLocale()->asString(); // de\n" #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "This is useful when you need to derive a language fallback or inspect locale parts before choosing a supported locale." -msgstr "" +msgstr "Isso é útil quando você precisa derivar um idioma de reserva ou inspecionar as partes do locale antes de escolher um idioma suportado." #. type: Title ## #: ../src/guide/tutorial/i18n.md #, no-wrap msgid "Localized view files" -msgstr "" +msgstr "Arquivos de view localizados" #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "Use message translation for labels, headings, buttons, validation messages, and short paragraphs. Use localized view files when a page needs different markup or a different amount of text for each locale." -msgstr "" +msgstr "Use tradução de mensagens para rótulos, títulos, botões, mensagens de validação e parágrafos curtos. Use arquivos de view localizados quando uma página precisa de marcação diferente ou de uma quantidade diferente de texto para cada idioma." #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "`yiisoft/view` looks for localized files in a locale subdirectory next to the original view file. For example, when `src/Web/HomePage/template.php` is rendered with locale `de-DE`, Yii checks:" -msgstr "" +msgstr "O `yiisoft/view` procura arquivos localizados num subdiretório com o nome do locale, ao lado do arquivo de view original. Por exemplo, quando `src/Web/HomePage/template.php` é renderizado com o locale `de-DE`, o Yii verifica:" #. type: Bullet: '1. ' #: ../src/guide/tutorial/i18n.md msgid "`src/Web/HomePage/de-DE/template.php`" -msgstr "" +msgstr "`src/Web/HomePage/de-DE/template.php`" #. type: Bullet: '2. ' #: ../src/guide/tutorial/i18n.md msgid "`src/Web/HomePage/de/template.php`" -msgstr "" +msgstr "`src/Web/HomePage/de/template.php`" #. type: Bullet: '3. ' #: ../src/guide/tutorial/i18n.md msgid "`src/Web/HomePage/template.php`" -msgstr "" +msgstr "`src/Web/HomePage/template.php`" #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "The fallback to the two-letter language code is automatic." -msgstr "" +msgstr "O fallback para o código de idioma de duas letras é automático." #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "You can set the locale for a single render call:" -msgstr "" +msgstr "Você pode definir o idioma para uma única chamada de renderização:" #. type: Fenced code block (php) #: ../src/guide/tutorial/i18n.md @@ -503,27 +669,30 @@ msgid "" " ->withLocale('de-DE')\n" " ->render(__DIR__ . '/template');\n" msgstr "" +"return $this->viewRenderer\n" +" ->withLocale('de-DE')\n" +" ->render(__DIR__ . '/template');\n" #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "When the locale is set on `WebView` in middleware, the same locale is applied to views rendered by `WebViewRenderer`." -msgstr "" +msgstr "Quando o idioma é definido no `WebView` dentro de um middleware, o mesmo idioma é aplicado às views renderizadas pelo `WebViewRenderer`." #. type: Title ## #: ../src/guide/tutorial/i18n.md #, no-wrap msgid "Extract messages" -msgstr "" +msgstr "Extraindo mensagens" #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "Configure the extractor so it can read existing messages and write new IDs to the same message storage." -msgstr "" +msgstr "Configure o extrator para que ele consiga ler as mensagens existentes e gravar novos IDs no mesmo armazenamento de mensagens." #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "Create `config/common/di/translator-extractor.php`:" -msgstr "" +msgstr "Crie `config/common/di/translator-extractor.php`:" #. type: Fenced code block (php) #: ../src/guide/tutorial/i18n.md @@ -562,27 +731,59 @@ msgid "" " ],\n" "];\n" msgstr "" +" [\n" +" '__construct()' => [\n" +" [\n" +" DynamicReference::to([\n" +" 'class' => ExtractorCategorySource::class,\n" +" '__construct()' => [\n" +" $params['yiisoft/translator']['defaultCategory'],\n" +" DynamicReference::to(\n" +" static fn (Aliases $aliases): MessageSource => new MessageSource($aliases->get('@root/messages')),\n" +" ),\n" +" DynamicReference::to(\n" +" static fn (Aliases $aliases): MessageSource => new MessageSource($aliases->get('@root/messages')),\n" +" ),\n" +" ],\n" +" ]),\n" +" ],\n" +" ],\n" +" ],\n" +"];\n" #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "Rebuild config after adding the extractor configuration file:" -msgstr "" +msgstr "Reconstrua a configuração depois de adicionar o arquivo de configuração do extrator:" #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "Extract messages from application source files:" -msgstr "" +msgstr "Extraia as mensagens dos arquivos-fonte da aplicação:" #. type: Fenced code block (sh) #: ../src/guide/tutorial/i18n.md #, no-wrap msgid "./yii translator/extract src --languages=en-US,de\n" -msgstr "" +msgstr "./yii translator/extract src --languages=en-US,de\n" #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "The command scans calls such as:" -msgstr "" +msgstr "O comando procura chamadas como:" #. type: Fenced code block (php) #: ../src/guide/tutorial/i18n.md @@ -591,11 +792,13 @@ msgid "" "$translator->translate('home.welcome');\n" "$translator->translate('cart.items', ['count' => $itemCount]);\n" msgstr "" +"$translator->translate('home.welcome');\n" +"$translator->translate('cart.items', ['count' => $itemCount]);\n" #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "It writes missing IDs to:" -msgstr "" +msgstr "Ele grava os IDs que faltam em:" #. type: Fenced code block #: ../src/guide/tutorial/i18n.md @@ -604,49 +807,51 @@ msgid "" "messages/en-US/app.php\n" "messages/de/app.php\n" msgstr "" +"messages/en-US/app.php\n" +"messages/de/app.php\n" #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "After extraction, edit target language files and replace source IDs with translated text." -msgstr "" +msgstr "Depois da extração, edite os arquivos dos idiomas de destino e troque os IDs de origem pelo texto traduzido." #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "Use `--category` when a call belongs to another category:" -msgstr "" +msgstr "Use `--category` quando uma chamada pertence a outra categoria:" #. type: Fenced code block (sh) #: ../src/guide/tutorial/i18n.md #, no-wrap msgid "./yii translator/extract src --languages=en-US,de --category=shop\n" -msgstr "" +msgstr "./yii translator/extract src --languages=en-US,de --category=shop\n" #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "The extractor excludes `vendor/` by default. Use `--only` or `--except` when you need a narrower scan:" -msgstr "" +msgstr "O extrator exclui `vendor/` por padrão. Use `--only` ou `--except` quando precisar de uma varredura mais restrita:" #. type: Fenced code block (sh) #: ../src/guide/tutorial/i18n.md #, no-wrap msgid "./yii translator/extract src --languages=en-US,de --only=**/*.php --except=**/runtime/**\n" -msgstr "" +msgstr "./yii translator/extract src --languages=en-US,de --only=**/*.php --except=**/runtime/**\n" #. type: Title ## #: ../src/guide/tutorial/i18n.md #, no-wrap msgid "Working with categories" -msgstr "" +msgstr "Trabalhando com categorias" #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "The default `app` category is enough for most application messages. Add categories when a package or a large feature owns its own message files." -msgstr "" +msgstr "A categoria padrão `app` basta para a maioria das mensagens da aplicação. Adicione categorias quando um pacote ou um recurso grande tem seus próprios arquivos de mensagens." #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "For a `shop` category, create another tagged category source:" -msgstr "" +msgstr "Para uma categoria `shop`, crie outro category source com a tag:" #. type: Fenced code block (php) #: ../src/guide/tutorial/i18n.md @@ -666,22 +871,35 @@ msgid "" " 'tags' => ['translation.categorySource'],\n" "],\n" msgstr "" +"'translation.shop' => [\n" +" 'definition' => static function (Aliases $aliases): CategorySource {\n" +" $messageSource = new MessageSource($aliases->get('@root/messages'));\n" +"\n" +" return new CategorySource(\n" +" 'shop',\n" +" $messageSource,\n" +" new IntlMessageFormatter(),\n" +" $messageSource,\n" +" );\n" +" },\n" +" 'tags' => ['translation.categorySource'],\n" +"],\n" #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "Translate with the category name:" -msgstr "" +msgstr "Traduza informando o nome da categoria:" #. type: Fenced code block (php) #: ../src/guide/tutorial/i18n.md #, no-wrap msgid "$translator->translate('checkout.submit', category: 'shop');\n" -msgstr "" +msgstr "$translator->translate('checkout.submit', category: 'shop');\n" #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "The message files are stored as:" -msgstr "" +msgstr "Os arquivos de mensagens ficam assim:" #. type: Fenced code block #: ../src/guide/tutorial/i18n.md @@ -690,8 +908,10 @@ msgid "" "messages/de/shop.php\n" "messages/en-US/shop.php\n" msgstr "" +"messages/de/shop.php\n" +"messages/en-US/shop.php\n" #. type: Plain text #: ../src/guide/tutorial/i18n.md msgid "Keep message IDs stable. Changing an ID creates a new translation task for every locale." -msgstr "" +msgstr "Mantenha os IDs de mensagens estáveis. Mudar um ID cria uma nova tarefa de tradução para cada idioma." diff --git a/_translations/po/pt-BR/guide_tutorial_mailing.md.po b/_translations/po/pt-BR/guide_tutorial_mailing.md.po index 458d56bd..ac5f6052 100644 --- a/_translations/po/pt-BR/guide_tutorial_mailing.md.po +++ b/_translations/po/pt-BR/guide_tutorial_mailing.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2025-09-04 11:19+0500\n" "PO-Revision-Date: 2025-09-04 11:19+0500\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,33 +19,33 @@ msgstr "" #: en/tutorial/mailing.md #, no-wrap msgid "Mailing" -msgstr "" +msgstr "Envio de e-mails" #. type: Plain text #: en/tutorial/mailing.md msgid "Yii simplifies the composition and sending of email messages using the [yiisoft/mailer](https://github.com/yiisoft/mailer) package. This package provides content composition functionality and a basic interface for sending emails. By default, the package includes a file mailer that writes email contents into a file instead of sending them. This is particularly useful during the initial stages of application development." -msgstr "" +msgstr "O Yii simplifica a composição e o envio de e-mails com o pacote [yiisoft/mailer](https://github.com/yiisoft/mailer). Esse pacote oferece a composição do conteúdo e uma interface básica para enviar e-mails. Por padrão, o pacote inclui um mailer de arquivo, que grava o conteúdo dos e-mails num arquivo em vez de enviá-los. Isso é especialmente útil nas fases iniciais do desenvolvimento da aplicação." #. type: Plain text #: en/tutorial/mailing.md msgid "To send actual emails, you can use the [Symfony Mailer](https://github.com/yiisoft/mailer-symfony) implementation, which is used in the examples below." -msgstr "" +msgstr "Para enviar e-mails de verdade, você pode usar a implementação com [Symfony Mailer](https://github.com/yiisoft/mailer-symfony), que é a usada nos exemplos abaixo." #. type: Title ## #: en/tutorial/mailing.md #, no-wrap msgid "Configuring the Mailer" -msgstr "" +msgstr "Configurando o mailer" #. type: Plain text #: en/tutorial/mailing.md msgid "The mailer service allows you to create a message instance, populate it with data, and send it. Typically, you get an instance from the DI container as `Yiisoft\\Mailer\\MailerInterface`." -msgstr "" +msgstr "O serviço de mailer permite criar uma instância de mensagem, preenchê-la com dados e enviá-la. Normalmente, você obtém uma instância do container de DI como `Yiisoft\\Mailer\\MailerInterface`." #. type: Plain text #: en/tutorial/mailing.md msgid "You can also create an instance manually as follows:" -msgstr "" +msgstr "Você também pode criar uma instância manualmente:" #. type: Fenced code block (php) #: en/tutorial/mailing.md @@ -62,38 +62,48 @@ msgid "" " $transport,\n" ");\n" msgstr "" +"\n" +"use Yiisoft\\Mailer\\Symfony\\Mailer;\n" +"\n" +"/**\n" +" * @var \\Symfony\\Component\\Mailer\\Transport\\TransportInterface $transport\n" +" */\n" +"\n" +"$mailer = new \\Yiisoft\\Mailer\\Symfony\\Mailer(\n" +" $transport,\n" +");\n" #. type: Plain text #: en/tutorial/mailing.md msgid "The `Yiisoft\\Mailer\\MailerInterface` provides two main methods:" -msgstr "" +msgstr "A `Yiisoft\\Mailer\\MailerInterface` oferece dois métodos principais:" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`send()` - Sends the given email message." -msgstr "" +msgstr "`send()` - Envia a mensagem de e-mail informada." #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`sendMultiple()` - Sends many messages at once." -msgstr "" +msgstr "`sendMultiple()` - Envia várias mensagens de uma vez." #. type: Title ## #: en/tutorial/mailing.md #, no-wrap msgid "Creating a Message" -msgstr "" +msgstr "Criando uma mensagem" #. type: Title ### #: en/tutorial/mailing.md #, no-wrap msgid "Simple Text Message" -msgstr "" +msgstr "Mensagem de texto simples" #. type: Plain text #: en/tutorial/mailing.md msgid "To create a simple message with a text body, use `Yiisoft\\Mailer\\Message`:" -msgstr "" +msgstr "Para criar uma mensagem simples com corpo em texto, use `Yiisoft\\Mailer\\Message`:" #. type: Fenced code block (php) #: en/tutorial/mailing.md @@ -106,12 +116,18 @@ msgid "" " textBody: 'Plain text content'\n" ");\n" msgstr "" +"$message = new \\Yiisoft\\Mailer\\Message(\n" +" from: 'from@domain.com',\n" +" to: 'to@domain.com',\n" +" subject: 'Message subject',\n" +" textBody: 'Plain text content'\n" +");\n" #. type: Title ### #: en/tutorial/mailing.md #, no-wrap msgid "Simple HTML Message" -msgstr "" +msgstr "Mensagem HTML simples" #. type: Fenced code block (php) #: en/tutorial/mailing.md @@ -124,17 +140,23 @@ msgid "" " htmlBody: 'HTML content'\n" ");\n" msgstr "" +"$message = new \\Yiisoft\\Mailer\\Message(\n" +" from: 'from@domain.com',\n" +" to: 'to@domain.com',\n" +" subject: 'Message subject',\n" +" htmlBody: 'HTML content'\n" +");\n" #. type: Title ### #: en/tutorial/mailing.md #, no-wrap msgid "HTML Message from template" -msgstr "" +msgstr "Mensagem HTML a partir de um template" #. type: Plain text #: en/tutorial/mailing.md msgid "For this example, we will use package rendering package [view](https://github.com/yiisoft/view)." -msgstr "" +msgstr "Neste exemplo, vamos usar o pacote de renderização [view](https://github.com/yiisoft/view)." #. type: Fenced code block (php) #: en/tutorial/mailing.md @@ -156,17 +178,32 @@ msgid "" " htmlBody: $content\n" ");\n" msgstr "" +"/**\n" +" * @var \\Yiisoft\\View\\View $view\n" +" */\n" +"\n" +"$content = $view->render('path/to/view.php', [\n" +" 'name' => 'name',\n" +" 'code' => 'code',\n" +"]);\n" +"\n" +"$message = new \\Yiisoft\\Mailer\\Message(\n" +" from: 'from@domain.com',\n" +" to: 'to@domain.com',\n" +" subject: 'Subject',\n" +" htmlBody: $content\n" +");\n" #. type: Title ### #: en/tutorial/mailing.md #, no-wrap msgid "Using Layouts" -msgstr "" +msgstr "Usando layouts" #. type: Plain text #: en/tutorial/mailing.md msgid "You can also pass parameters to layouts from your template message:" -msgstr "" +msgstr "Você também pode passar parâmetros para os layouts a partir do template da mensagem:" #. type: Fenced code block (php) #: en/tutorial/mailing.md @@ -193,17 +230,37 @@ msgid "" " htmlBody: $content\n" ");\n" msgstr "" +"/**\n" +" * @var \\Yiisoft\\View\\View $view\n" +" * @var array $layoutParameters\n" +" */\n" +"\n" +"$messageBody = $view->render('path/to/view.php', [\n" +" 'name' => 'name',\n" +" 'code' => 'code',\n" +"]);\n" +"\n" +"$layoutParameters['content'] = $messageBody;\n" +"\n" +"$content = $view->render('path/to/layout.php', $layoutParameters);\n" +"\n" +"$message = new \\Yiisoft\\Mailer\\Message(\n" +" from: 'from@domain.com',\n" +" to: 'to@domain.com',\n" +" subject: 'Subject',\n" +" htmlBody: $content\n" +");\n" #. type: Title ### #: en/tutorial/mailing.md #, no-wrap msgid "Layout Example" -msgstr "" +msgstr "Exemplo de layout" #. type: Plain text #: en/tutorial/mailing.md msgid "You can wrap the view rendering result in a layout, similar to how layouts work in web applications. This is useful for setting up shared content like CSS styles:" -msgstr "" +msgstr "Você pode envolver o resultado da renderização da view num layout, do mesmo jeito que os layouts funcionam em aplicações web. Isso é útil para definir conteúdo compartilhado, como estilos CSS:" #. type: Fenced code block (php) #: en/tutorial/mailing.md @@ -229,204 +286,223 @@ msgid "" "\n" "\n" msgstr "" +"\n" +"\n" +"\n" +"\n" +" \n" +"\n" +"\n" +"\n" +"\n" +"\n" +"
\n" +"--
\n" +"Mailed by Yii\n" +"
\n" +"\n" +"\n" +"\n" #. type: Title ## #: en/tutorial/mailing.md #, no-wrap msgid "Adding More Data" -msgstr "" +msgstr "Adicionando mais dados" #. type: Plain text #: en/tutorial/mailing.md msgid "The `Yiisoft\\Mailer\\MessageInterface` provides several methods to customize your message:" -msgstr "" +msgstr "A `Yiisoft\\Mailer\\MessageInterface` oferece vários métodos para personalizar a mensagem:" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`withCharset()` - Returns a new instance with the specified charset." -msgstr "" +msgstr "`withCharset()` - Retorna uma nova instância com o charset informado." #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`withFrom()` - Returns a new instance with the specified sender email address." -msgstr "" +msgstr "`withFrom()` - Retorna uma nova instância com o endereço de e-mail do remetente informado." #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`withTo()` - Returns a new instance with the specified recipient(s) email address." -msgstr "" +msgstr "`withTo()` - Retorna uma nova instância com o(s) endereço(s) de e-mail do(s) destinatário(s) informado(s)." #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`withReplyTo()` - Returns a new instance with the specified reply-to address." -msgstr "" +msgstr "`withReplyTo()` - Retorna uma nova instância com o endereço de resposta (reply-to) informado." #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`withCc()` - Returns a new instance with the specified Cc (extra copy receiver) addresses." -msgstr "" +msgstr "`withCc()` - Retorna uma nova instância com os endereços em Cc (destinatários de cópia) informados." #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`withBcc()` - Returns a new instance with the specified Bcc (hidden copy receiver) addresses." -msgstr "" +msgstr "`withBcc()` - Retorna uma nova instância com os endereços em Bcc (destinatários de cópia oculta) informados." #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`withSubject()` - Returns a new instance with the specified message subject." -msgstr "" +msgstr "`withSubject()` - Retorna uma nova instância com o assunto da mensagem informado." #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`withDate()` - Returns a new instance with the specified date when the message was sent." -msgstr "" +msgstr "`withDate()` - Retorna uma nova instância com a data de envio da mensagem informada." #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`withPriority()` - Returns a new instance with the specified priority of this message." -msgstr "" +msgstr "`withPriority()` - Retorna uma nova instância com a prioridade da mensagem informada." #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`withReturnPath()` - Returns a new instance with the specified return-path (the bounce address) of this message." -msgstr "" +msgstr "`withReturnPath()` - Retorna uma nova instância com o return-path (endereço de bounce) da mensagem informado." #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`withSender()` - Returns a new instance with the specified actual sender email address." -msgstr "" +msgstr "`withSender()` - Retorna uma nova instância com o endereço de e-mail do remetente real informado." #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`withHtmlBody()` - Returns a new instance with the specified message HTML content." -msgstr "" +msgstr "`withHtmlBody()` - Retorna uma nova instância com o conteúdo HTML da mensagem informado." #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`withTextBody()` - Returns a new instance with the specified message plain text content." -msgstr "" +msgstr "`withTextBody()` - Retorna uma nova instância com o conteúdo em texto puro da mensagem informado." #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`withAddedHeader()` - Returns a new instance with the specified added custom header value." -msgstr "" +msgstr "`withAddedHeader()` - Retorna uma nova instância com o valor de header personalizado adicionado." #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`withHeader()` - Returns a new instance with the specified custom header value." -msgstr "" +msgstr "`withHeader()` - Retorna uma nova instância com o valor de header personalizado informado." #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`withHeaders()` - Returns a new instance with the specified custom header values." -msgstr "" +msgstr "`withHeaders()` - Retorna uma nova instância com os valores de headers personalizados informados." #. type: Plain text #: en/tutorial/mailing.md msgid "These methods are immutable, meaning they return a new instance of the message with the updated data." -msgstr "" +msgstr "Esses métodos são imutáveis, ou seja, retornam uma nova instância da mensagem com os dados atualizados." #. type: Plain text #: en/tutorial/mailing.md msgid "Note `with` prefix. It indicates that the method is immutable and returns a new instance of the class with the changed data." -msgstr "" +msgstr "Repare no prefixo `with`. Ele indica que o método é imutável e retorna uma nova instância da classe com os dados alterados." #. type: Title ### #: en/tutorial/mailing.md #, no-wrap msgid "Getters" -msgstr "" +msgstr "Getters" #. type: Plain text #: en/tutorial/mailing.md msgid "The following getters are available to retrieve message data:" -msgstr "" +msgstr "Os getters a seguir estão disponíveis para obter os dados da mensagem:" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`getCharset()` - Returns the charset of this message." -msgstr "" +msgstr "`getCharset()` - Retorna o charset da mensagem." #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`getFrom()` - Returns the message sender email address." -msgstr "" +msgstr "`getFrom()` - Retorna o endereço de e-mail do remetente da mensagem." #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`getTo()` - Returns the message recipient(s) email address." -msgstr "" +msgstr "`getTo()` - Retorna o(s) endereço(s) de e-mail do(s) destinatário(s) da mensagem." #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`getReplyTo()` - Returns the reply-to address of this message." -msgstr "" +msgstr "`getReplyTo()` - Retorna o endereço de resposta (reply-to) da mensagem." #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`getCc()` - Returns the Cc (extra copy receiver) addresses of this message." -msgstr "" +msgstr "`getCc()` - Retorna os endereços em Cc (destinatários de cópia) da mensagem." #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`getBcc()` - Returns the Bcc (hidden copy receiver) addresses of this message." -msgstr "" +msgstr "`getBcc()` - Retorna os endereços em Bcc (destinatários de cópia oculta) da mensagem." #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`getSubject()` - Returns the message subject." -msgstr "" +msgstr "`getSubject()` - Retorna o assunto da mensagem." #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`getDate()` - Returns the date when the message was sent, or null if it wasn't set." -msgstr "" +msgstr "`getDate()` - Retorna a data de envio da mensagem, ou null se ela não foi definida." #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`getPriority()` - Returns the priority of this message." -msgstr "" +msgstr "`getPriority()` - Retorna a prioridade da mensagem." #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`getReturnPath()` - Returns the return-path (the bounce address) of this message." -msgstr "" +msgstr "`getReturnPath()` - Retorna o return-path (endereço de bounce) da mensagem." #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`getSender()` - Returns the message actual sender email address." -msgstr "" +msgstr "`getSender()` - Retorna o endereço de e-mail do remetente real da mensagem." #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`getHtmlBody()` - Returns the message HTML body." -msgstr "" +msgstr "`getHtmlBody()` - Retorna o corpo HTML da mensagem." #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`getTextBody()` - Returns the message text body." -msgstr "" +msgstr "`getTextBody()` - Retorna o corpo em texto da mensagem." #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`getHeader()` - Returns all values for the specified header." -msgstr "" +msgstr "`getHeader()` - Retorna todos os valores do header informado." #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`__toString()` - Returns string representation of this message." -msgstr "" +msgstr "`__toString()` - Retorna a representação em string da mensagem." #. type: Title ## #: en/tutorial/mailing.md #, no-wrap msgid "Attaching Files" -msgstr "" +msgstr "Anexando arquivos" #. type: Plain text #: en/tutorial/mailing.md msgid "You can attach files to your message using the `withAttached()` method:" -msgstr "" +msgstr "Você pode anexar arquivos à mensagem com o método `withAttached()`:" #. type: Fenced code block (php) #: en/tutorial/mailing.md @@ -444,17 +520,28 @@ msgid "" " File::fromContent('Attachment content', 'attach.txt', 'text/plain'),\n" ");\n" msgstr "" +"use Yiisoft\\Mailer\\File;\n" +"\n" +"// Anexa um arquivo do sistema de arquivos local\n" +"$message = $message->withAttached(\n" +" File::fromPath('/path/to/source/file.pdf'),\n" +");\n" +"\n" +"// Cria um anexo na hora\n" +"$message = $message->withAttached(\n" +" File::fromContent('Attachment content', 'attach.txt', 'text/plain'),\n" +");\n" #. type: Title ## #: en/tutorial/mailing.md #, no-wrap msgid "Embedding Images" -msgstr "" +msgstr "Incorporando imagens" #. type: Plain text #: en/tutorial/mailing.md msgid "You can embed images into the message content using the `withEmbedded()` method. This is particularly useful when composing messages with views:" -msgstr "" +msgstr "Você pode incorporar imagens ao conteúdo da mensagem com o método `withEmbedded()`. Isso é especialmente útil ao compor mensagens com views:" #. type: Fenced code block (php) #: en/tutorial/mailing.md @@ -476,28 +563,43 @@ msgid "" " embeddings: $logo\n" " );\n" msgstr "" +"$logo = 'path/to/logo';\n" +"$htmlBody = $this->view->render(\n" +" __DIR__ . 'template.php',\n" +" [\n" +" 'content' => $content,\n" +" 'logoCid' => $logo->cid(),\n" +" ],\n" +");\n" +"return new \\Yiisoft\\Mailer\\Message(\n" +" from: 'from@domain.com',\n" +" to: 'to@domain.com',\n" +" subject: 'Message subject',\n" +" htmlBody: $htmlBody,\n" +" embeddings: $logo\n" +" );\n" #. type: Plain text #: en/tutorial/mailing.md msgid "In your view or layout template, you can reference the embedded image using its CID:" -msgstr "" +msgstr "No template da view ou do layout, você pode referenciar a imagem incorporada pelo seu CID:" #. type: Fenced code block (php) #: en/tutorial/mailing.md #, no-wrap msgid "\">\n" -msgstr "" +msgstr "\">\n" #. type: Title ## #: en/tutorial/mailing.md #, no-wrap msgid "Sending a Message" -msgstr "" +msgstr "Enviando uma mensagem" #. type: Plain text #: en/tutorial/mailing.md msgid "To send an email message:" -msgstr "" +msgstr "Para enviar uma mensagem de e-mail:" #. type: Fenced code block (php) #: en/tutorial/mailing.md @@ -521,17 +623,34 @@ msgid "" "\n" "$mailer->send($message);\n" msgstr "" +"/**\n" +" * @var \\Yiisoft\\View\\View $view\n" +" */\n" +"\n" +"$content = $view->render('path/to/view.php', [\n" +" 'name' => 'name',\n" +" 'code' => 'code',\n" +"]);\n" +"\n" +"$message = new \\Yiisoft\\Mailer\\Message(\n" +" from: 'from@domain.com',\n" +" to: 'to@domain.com',\n" +" subject: 'Subject',\n" +" htmlBody: $content\n" +");\n" +"\n" +"$mailer->send($message);\n" #. type: Title ## #: en/tutorial/mailing.md #, no-wrap msgid "Sending Multiple Messages" -msgstr "" +msgstr "Enviando várias mensagens" #. type: Plain text #: en/tutorial/mailing.md msgid "You can send multiple messages at once:" -msgstr "" +msgstr "Você pode enviar várias mensagens de uma vez:" #. type: Fenced code block (php) #: en/tutorial/mailing.md @@ -547,53 +666,62 @@ msgid "" "\n" "$result = $mailer->sendMultiple($messages);\n" msgstr "" +"$messages = [];\n" +"\n" +"foreach ($users as $user) {\n" +" $messages[] = (new \\Yiisoft\\Mailer\\Message())\n" +" // ...\n" +" ->withTo($user->email);\n" +"}\n" +"\n" +"$result = $mailer->sendMultiple($messages);\n" #. type: Plain text #: en/tutorial/mailing.md msgid "The `sendMultiple()` method returns a `Yiisoft\\Mailer\\SendResults` object containing arrays of successfully sent and failed messages." -msgstr "" +msgstr "O método `sendMultiple()` retorna um objeto `Yiisoft\\Mailer\\SendResults` com arrays das mensagens enviadas com sucesso e das que falharam." #. type: Title ## #: en/tutorial/mailing.md #, no-wrap msgid "Implementing your own mail driver" -msgstr "" +msgstr "Implementando seu próprio driver de e-mail" #. type: Plain text #: en/tutorial/mailing.md msgid "To create a custom mail solution, implement the `Yiisoft\\Mailer\\MailerInterface` and `Yiisoft\\Mailer\\MessageInterface` interfaces." -msgstr "" +msgstr "Para criar uma solução de e-mail personalizada, implemente as interfaces `Yiisoft\\Mailer\\MailerInterface` e `Yiisoft\\Mailer\\MessageInterface`." #. type: Title ## #: en/tutorial/mailing.md #, no-wrap msgid "For Development" -msgstr "" +msgstr "Para desenvolvimento" #. type: Plain text #: en/tutorial/mailing.md msgid "For local or test development, you can use simplified implementations of the mailer that does not send emails. The package provides these implementations:" -msgstr "" +msgstr "Em desenvolvimento local ou em testes, você pode usar implementações simplificadas do mailer que não enviam e-mails. O pacote oferece estas implementações:" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`Yiisoft\\Mailer\\StubMailer` - A simple mailer that stores messages in a local array." -msgstr "" +msgstr "`Yiisoft\\Mailer\\StubMailer` - Um mailer simples que guarda as mensagens num array local." #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`Yiisoft\\Mailer\\FileMailer` - A mock mailer that saves email messages as files instead of sending them." -msgstr "" +msgstr "`Yiisoft\\Mailer\\FileMailer` - Um mailer de mentira que grava as mensagens de e-mail em arquivos em vez de enviá-las." #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`Yiisoft\\Mailer\\NullMailer` - A mailer that discards messages without sending or storing them." -msgstr "" +msgstr "`Yiisoft\\Mailer\\NullMailer` - Um mailer que descarta as mensagens sem enviá-las nem guardá-las." #. type: Plain text #: en/tutorial/mailing.md msgid "To use one of these mailers, configure it in your development environment file Example: `environments/local/di.php`" -msgstr "" +msgstr "Para usar um desses mailers, configure-o no arquivo de ambiente de desenvolvimento. Exemplo: `environments/local/di.php`" #. type: Fenced code block (php) #: en/tutorial/mailing.md @@ -604,3 +732,7 @@ msgid "" "];\n" "\n" msgstr "" +"return [\n" +" Yiisoft\\Mailer\\MailerInterface::class => Yiisoft\\Mailer\\StubMailer::class, //ou qualquer outro\n" +"];\n" +"\n" diff --git a/_translations/po/pt-BR/guide_tutorial_performance-tuning.md.po b/_translations/po/pt-BR/guide_tutorial_performance-tuning.md.po index fa738a44..7384aa06 100644 --- a/_translations/po/pt-BR/guide_tutorial_performance-tuning.md.po +++ b/_translations/po/pt-BR/guide_tutorial_performance-tuning.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-06-05 20:33+0000\n" "PO-Revision-Date: 2026-06-05 20:33+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,106 +19,106 @@ msgstr "" #: ../src/guide/tutorial/performance-tuning.md #, no-wrap msgid "Performance tuning" -msgstr "" +msgstr "Ajuste de desempenho" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "There are many factors affecting the performance of your application. Some are environmental, some are related to your code, while some others are related to Yii itself. In this section, we will count most of these factors and explain how you can improve your application performance by adjusting these factors." -msgstr "" +msgstr "Muitos fatores afetam o desempenho da sua aplicação. Alguns são do ambiente, outros estão ligados ao seu código, e outros ao próprio Yii. Nesta seção, listamos a maioria desses fatores e explicamos como você pode melhorar o desempenho da aplicação ajustando cada um deles." #. type: Title ## #: ../src/guide/tutorial/performance-tuning.md #, no-wrap msgid "Optimizing your PHP Environment" -msgstr "" +msgstr "Otimizando o ambiente PHP" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "A well-configured PHP environment is important. To get maximum performance:" -msgstr "" +msgstr "Um ambiente PHP bem configurado é importante. Para obter o máximo de desempenho:" #. type: Bullet: '- ' #: ../src/guide/tutorial/performance-tuning.md msgid "Use the latest stable PHP version. Major releases of PHP may bring significant performance improvements." -msgstr "" +msgstr "Use a versão estável mais recente do PHP. Versões principais do PHP podem trazer ganhos de desempenho significativos." #. type: Bullet: '- ' #: ../src/guide/tutorial/performance-tuning.md msgid "Enable bytecode caching with [Opcache](https://secure.php.net/opcache). Bytecode caching avoids the time spent on parsing and including PHP scripts for every incoming request." -msgstr "" +msgstr "Ative o cache de bytecode com o [Opcache](https://secure.php.net/opcache). O cache de bytecode evita o tempo gasto para analisar e incluir os scripts PHP a cada requisição." #. type: Bullet: '- ' #: ../src/guide/tutorial/performance-tuning.md msgid "[Tune `realpath()` cache](https://github.com/samdark/realpath_cache_tuner)." -msgstr "" +msgstr "[Ajuste o cache do `realpath()`](https://github.com/samdark/realpath_cache_tuner)." #. type: Bullet: '- ' #: ../src/guide/tutorial/performance-tuning.md msgid "Make sure [XDebug](https://xdebug.org/) isn't installed in the production environment." -msgstr "" +msgstr "Garanta que o [XDebug](https://xdebug.org/) não esteja instalado no ambiente de produção." #. type: Bullet: '- ' #: ../src/guide/tutorial/performance-tuning.md msgid "Try [PHP 7 preloading](https://wiki.php.net/rfc/preload)." -msgstr "" +msgstr "Experimente o [preload do PHP 7](https://wiki.php.net/rfc/preload)." #. type: Title ## #: ../src/guide/tutorial/performance-tuning.md #, no-wrap msgid "Optimizing your code" -msgstr "" +msgstr "Otimizando o seu código" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "Beyond environment configuration, there are code-level optimizations that can improve your application's performance:" -msgstr "" +msgstr "Além da configuração do ambiente, há otimizações no nível do código que podem melhorar o desempenho da aplicação:" #. type: Bullet: '- ' #: ../src/guide/tutorial/performance-tuning.md msgid "Look out for [algorithm complexity](https://en.wikipedia.org/wiki/Time_complexity). Especially give attention to `foreach` within `foreach` loops but look out for using [heavy PHP functions](https://stackoverflow.com/questions/2473989/list-of-big-o-for-php-functions) in loops as well." -msgstr "" +msgstr "Fique atento à [complexidade dos algoritmos](https://en.wikipedia.org/wiki/Time_complexity). Preste atenção especial a loops `foreach` dentro de `foreach`, mas também ao uso de [funções PHP pesadas](https://stackoverflow.com/questions/2473989/list-of-big-o-for-php-functions) dentro de loops." #. type: Bullet: '- ' #: ../src/guide/tutorial/performance-tuning.md msgid "[Speeding up array_merge()](https://www.exakat.io/speeding-up-array_merge/)" -msgstr "" +msgstr "[Acelerando o array_merge()](https://www.exakat.io/speeding-up-array_merge/)" #. type: Bullet: '- ' #: ../src/guide/tutorial/performance-tuning.md msgid "[Move that foreach() inside the method](https://www.exakat.io/move-that-foreach-inside-the-method/)" -msgstr "" +msgstr "[Mova aquele foreach() para dentro do método](https://www.exakat.io/move-that-foreach-inside-the-method/)" #. type: Bullet: '- ' #: ../src/guide/tutorial/performance-tuning.md msgid "[Array, classes and anonymous classes memory usage](https://www.exakat.io/array-classes-and-anonymous-memory-usage/)" -msgstr "" +msgstr "[Uso de memória de arrays, classes e classes anônimas](https://www.exakat.io/array-classes-and-anonymous-memory-usage/)" #. type: Bullet: '- ' #: ../src/guide/tutorial/performance-tuning.md msgid "Use fully qualified function names with leading backslashes to optimize opcache performance. When calling [certain global functions](https://github.com/php/php-src/blob/944b6b6bbd6f05ad905f5f4ad07445792bee4027/Zend/zend_compile.c#L4291-L4353) from within a namespace, PHP first searches in the current namespace before falling back to the global namespace. Adding a leading backslash (e.g., `\\count()` instead of `count()`) tells PHP to directly use the global function, avoiding the namespace lookup and improving opcache efficiency. This optimization is best implemented automatically using tools like [PHP-CS-Fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer) with the `native_function_invocation` rule." -msgstr "" +msgstr "Use nomes de funções totalmente qualificados, com barra invertida no início, para otimizar o desempenho do opcache. Ao chamar [certas funções globais](https://github.com/php/php-src/blob/944b6b6bbd6f05ad905f5f4ad07445792bee4027/Zend/zend_compile.c#L4291-L4353) de dentro de um namespace, o PHP primeiro procura no namespace atual antes de recorrer ao namespace global. Adicionar a barra invertida no início (por exemplo, `\\count()` em vez de `count()`) diz ao PHP para usar diretamente a função global, evitando a busca no namespace e melhorando a eficiência do opcache. O melhor é aplicar essa otimização automaticamente com ferramentas como o [PHP-CS-Fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer), usando a regra `native_function_invocation`." #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "The above optimizations would give you a significant performance boost only if the code in question is executed frequently. That is usually the case for big loops or batch processing." -msgstr "" +msgstr "As otimizações acima só trazem um ganho de desempenho significativo se o código em questão for executado com frequência. Normalmente é o caso de loops grandes ou de processamento em lote." #. type: Title ## #: ../src/guide/tutorial/performance-tuning.md #, no-wrap msgid "Using caching techniques" -msgstr "" +msgstr "Usando técnicas de cache" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "You can use various caching techniques to significantly improve the performance of your application. For example, if your application allows users to enter text in Markdown format, you may consider caching the parsed Markdown content to avoid parsing the same Markdown text repeatedly in every request. Please refer to the [Caching](../caching/overview.md) section to learn about the caching support provided by Yii." -msgstr "" +msgstr "Você pode usar várias técnicas de cache para melhorar bastante o desempenho da aplicação. Por exemplo, se a sua aplicação permite que os usuários digitem texto em Markdown, considere guardar em cache o conteúdo Markdown já processado, para não processar o mesmo texto repetidamente a cada requisição. Consulte a seção de [Cache](../caching/overview.md) para conhecer o suporte a cache oferecido pelo Yii." #. type: Title ## #: ../src/guide/tutorial/performance-tuning.md #, no-wrap msgid "Optimizing session storage" -msgstr "" +msgstr "Otimizando o armazenamento de sessões" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md @@ -130,11 +130,16 @@ msgid "" "initial request to release a session file. This is fine for development and probably small projects. But when it comes \n" "to handling massive concurrent requests, it's better to use more sophisticated storage, such as Redis.\n" msgstr "" +"Por padrão, os dados de sessão são guardados em arquivos. A implementação trava o arquivo desde a abertura da sessão até o momento em que ela é\n" +"fechada, seja por `$session->close()` ou no fim da requisição.\n" +"Enquanto o arquivo de sessão está travado, todas as outras requisições que tentam usar a mesma sessão ficam bloqueadas, esperando a\n" +"requisição inicial liberar o arquivo de sessão. Isso serve para desenvolvimento e, provavelmente, para projetos pequenos. Mas quando se trata\n" +"de lidar com muitas requisições concorrentes, é melhor usar um armazenamento mais sofisticado, como o Redis.\n" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "It could be done either by [configuring PHP via php.ini](https://www.digitalocean.com/community/tutorials/how-to-set-up-a-redis-server-as-a-session-handler-for-php-on-ubuntu-14-04) or [implementing SessionHandlerInterface](https://www.sitepoint.com/saving-php-sessions-in-redis/) and configuring session service as follows:" -msgstr "" +msgstr "Isso pode ser feito [configurando o PHP via php.ini](https://www.digitalocean.com/community/tutorials/how-to-set-up-a-redis-server-as-a-session-handler-for-php-on-ubuntu-14-04) ou [implementando a SessionHandlerInterface](https://www.sitepoint.com/saving-php-sessions-in-redis/) e configurando o serviço de sessão assim:" #. type: Fenced code block (php) #: ../src/guide/tutorial/performance-tuning.md @@ -145,139 +150,143 @@ msgid "" " '__construct()' => [[], $myCustomSessionHandler],\n" "],\n" msgstr "" +"\\Yiisoft\\Session\\SessionInterface::class => [\n" +" 'class' => \\Yiisoft\\Session\\Session::class,\n" +" '__construct()' => [[], $myCustomSessionHandler],\n" +"],\n" #. type: Title ## #: ../src/guide/tutorial/performance-tuning.md #, no-wrap msgid "Optimizing databases" -msgstr "" +msgstr "Otimizando bancos de dados" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "Executing DB queries and fetching data from databases are often the main performance bottleneck in a Web application. Although using [data caching](../caching/data.md) techniques may ease the performance hit, it doesn't fully solve the problem. When the database has enormous amounts of data and the cached data are invalid, fetching the latest data could be prohibitively expensive without a proper database and query design." -msgstr "" +msgstr "Executar consultas e buscar dados no banco de dados costuma ser o principal gargalo de desempenho de uma aplicação web. Embora técnicas de [cache de dados](../caching/data.md) possam amenizar o impacto, elas não resolvem totalmente o problema. Quando o banco de dados tem uma quantidade enorme de dados e os dados em cache ficam inválidos, buscar os dados mais recentes pode ficar caro demais sem um bom projeto de banco de dados e de consultas." #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "A general technique to improve the performance of DB queries is to create indices for table columns that need to be filtered by. For example, if you need to look for a user record by `username`, you should create an index on `username`. Note that while indexing can make SELECT queries much faster, it will slow down INSERT, UPDATE and DELETE queries." -msgstr "" +msgstr "Uma técnica geral para melhorar o desempenho das consultas é criar índices nas colunas das tabelas usadas em filtros. Por exemplo, se você precisa buscar o registro de um usuário pelo `username`, crie um índice em `username`. Note que, embora a indexação possa deixar as consultas SELECT muito mais rápidas, ela deixa as consultas INSERT, UPDATE e DELETE mais lentas." #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "For complex DB queries, it's recommended that you create database views to save the query parsing and preparation time." -msgstr "" +msgstr "Para consultas complexas, é recomendável criar views no banco de dados para economizar o tempo de análise e preparação da consulta." #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "Last but not least, use `LIMIT` in your `SELECT` queries. This avoids fetching an overwhelming amount of data from the database and exhausting the memory allocated to PHP." -msgstr "" +msgstr "Por último, mas não menos importante, use `LIMIT` nas suas consultas `SELECT`. Isso evita buscar uma quantidade excessiva de dados no banco e esgotar a memória alocada para o PHP." #. type: Title ## #: ../src/guide/tutorial/performance-tuning.md #, no-wrap msgid "Optimizing composer autoloader" -msgstr "" +msgstr "Otimizando o autoloader do Composer" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "Because Composer autoloader is used to include most third-party class files, you should consider optimizing it by executing the following command:" -msgstr "" +msgstr "Como o autoloader do Composer é usado para incluir a maioria dos arquivos de classes de terceiros, considere otimizá-lo executando o seguinte comando:" #. type: Fenced code block #: ../src/guide/tutorial/performance-tuning.md #, no-wrap msgid "composer dumpautoload -o\n" -msgstr "" +msgstr "composer dumpautoload -o\n" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "Additionally, you may consider using [authoritative class maps](https://getcomposer.org/doc/articles/autoloader-optimization.md#optimization-level-2-a-authoritative-class-maps) and [APCu cache](https://getcomposer.org/doc/articles/autoloader-optimization.md#optimization-level-2-b-apcu-cache). Note that both optimizations may or may not be suitable for your particular case." -msgstr "" +msgstr "Além disso, você pode considerar o uso de [class maps autoritativos](https://getcomposer.org/doc/articles/autoloader-optimization.md#optimization-level-2-a-authoritative-class-maps) e do [cache APCu](https://getcomposer.org/doc/articles/autoloader-optimization.md#optimization-level-2-b-apcu-cache). Note que essas duas otimizações podem ou não ser adequadas ao seu caso." #. type: Title ## #: ../src/guide/tutorial/performance-tuning.md #, no-wrap msgid "Processing data offline" -msgstr "" +msgstr "Processando dados offline" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "When a request involves some resource-intensive operations, you should think of ways to perform those operations in offline mode without having users wait for them to finish." -msgstr "" +msgstr "Quando uma requisição envolve operações que consomem muitos recursos, pense em formas de executá-las em modo offline, sem fazer os usuários esperarem que terminem." #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "There are two methods to process data offline: pull and push." -msgstr "" +msgstr "Há dois métodos para processar dados offline: pull e push." #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "In the pull method, whenever a request involves some complex operation, you create a task and save it in a persistent storage, such as a database. You then use a separate process (such as a cron job) to pull the tasks and process them. This method is straightforward to implement, but it has some drawbacks. For example, the task process needs to periodically pull from the task storage. If the pull frequency is too low, the tasks may be processed with great delay, but if the frequency is too high, it will introduce high overhead." -msgstr "" +msgstr "No método pull, sempre que uma requisição envolve alguma operação complexa, você cria uma tarefa e a salva num armazenamento persistente, como um banco de dados. Depois, usa um processo separado (como um cron job) para buscar as tarefas e processá-las. Esse método é simples de implementar, mas tem algumas desvantagens. Por exemplo, o processo de tarefas precisa consultar periodicamente o armazenamento de tarefas. Se a frequência for baixa demais, as tarefas podem ser processadas com muito atraso; se for alta demais, gera muito overhead." #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "In the push method, you would use a message queue (e.g., RabbitMQ, ActiveMQ, Amazon SQS, etc.) to manage the tasks. Whenever a new task is put in the queue, it will initiate or notify the task handling process to trigger the task processing." -msgstr "" +msgstr "No método push, você usa uma fila de mensagens (por exemplo, RabbitMQ, ActiveMQ, Amazon SQS etc.) para gerenciar as tarefas. Sempre que uma nova tarefa entra na fila, ela inicia ou notifica o processo responsável, que dispara o processamento da tarefa." #. type: Title ## #: ../src/guide/tutorial/performance-tuning.md #, no-wrap msgid "Using preloading" -msgstr "" +msgstr "Usando preload" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "As of PHP 7.4.0, PHP can be configured to preload scripts into the opcache when the engine starts. You can read more in the [documentation](https://www.php.net/manual/en/opcache.preloading.php) and the corresponding [RFC](https://wiki.php.net/rfc/preload)." -msgstr "" +msgstr "A partir do PHP 7.4.0, o PHP pode ser configurado para pré-carregar scripts no opcache quando o engine inicia. Saiba mais na [documentação](https://www.php.net/manual/en/opcache.preloading.php) e na [RFC](https://wiki.php.net/rfc/preload) correspondente." #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "Note that the optimal tradeoff between performance and memory may vary with the application. \"Preload everything\" may be the easiest strategy, but not necessarily the best strategy." -msgstr "" +msgstr "Note que o equilíbrio ideal entre desempenho e memória pode variar conforme a aplicação. \"Pré-carregar tudo\" pode ser a estratégia mais fácil, mas não necessariamente a melhor." #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "For example, we conducted a simple [yiisoft/app](https://github.com/yiisoft/app) application template benchmark. Without preloading and with preloading of the entire composer class map." -msgstr "" +msgstr "Por exemplo, fizemos um benchmark simples do template de aplicação [yiisoft/app](https://github.com/yiisoft/app): sem preload e com preload de todo o class map do Composer." #. type: Title ### #: ../src/guide/tutorial/performance-tuning.md #, no-wrap msgid "Preloading benchmarks" -msgstr "" +msgstr "Benchmarks de preload" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "The application template benchmark includes configuring classes to injected dependencies in the bootstrap script." -msgstr "" +msgstr "O benchmark do template de aplicação inclui a configuração das classes para as dependências injetadas no script de bootstrap." #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "For both variants, [ApacheBench](https://httpd.apache.org/docs/2.4/programs/ab.html) was used with the following run parameters:" -msgstr "" +msgstr "Nas duas variantes, foi usado o [ApacheBench](https://httpd.apache.org/docs/2.4/programs/ab.html) com os seguintes parâmetros de execução:" #. type: Fenced code block (shell) #: ../src/guide/tutorial/performance-tuning.md #, no-wrap msgid "ab -n 1000 -c 10 -t 10\n" -msgstr "" +msgstr "ab -n 1000 -c 10 -t 10\n" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "Also, the debug mode was disabled. And an optimized autoloader of the [Composer](https://getcomposer.org) was used, and development dependencies weren't used:" -msgstr "" +msgstr "Além disso, o modo debug estava desativado. Também foi usado um autoloader otimizado do [Composer](https://getcomposer.org), sem as dependências de desenvolvimento:" #. type: Fenced code block (shell) #: ../src/guide/tutorial/performance-tuning.md #, no-wrap msgid "composer install --optimize-autoloader --no-dev\n" -msgstr "" +msgstr "composer install --optimize-autoloader --no-dev\n" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "With preloading enabled, the entire composer class map (825 files) was used:" -msgstr "" +msgstr "Com o preload ativado, foi usado todo o class map do Composer (825 arquivos):" #. type: Fenced code block (php) #: ../src/guide/tutorial/performance-tuning.md @@ -289,12 +298,17 @@ msgid "" " opcache_compile_file($file);\n" "}\n" msgstr "" +"$files = require 'vendor/composer/autoload_classmap.php';\n" +"\n" +"foreach (array_unique($files) as $file) {\n" +" opcache_compile_file($file);\n" +"}\n" #. type: Title #### #: ../src/guide/tutorial/performance-tuning.md #, no-wrap msgid "Test results" -msgstr "" +msgstr "Resultados dos testes" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md @@ -305,40 +319,44 @@ msgid "" "| Without preloading | 0 | 12.32 mb | 1.71 mb | 27.63 ms | 36.55 rq/s |\n" "| With preloading | 825 | 17.86 mb | 1.82 mb | 26.21 ms | 38.42 rq/s |\n" msgstr "" +"| Benchmark | Arquivos pré-carregados | Memória do Opcache usada | Memória usada por requisição | Tempo por requisição | Requisições por segundo |\n" +"|--------------------|-------------------------|--------------------------|------------------------------|----------------------|-------------------------|\n" +"| Sem preload | 0 | 12.32 mb | 1.71 mb | 27.63 ms | 36.55 rq/s |\n" +"| Com preload | 825 | 17.86 mb | 1.82 mb | 26.21 ms | 38.42 rq/s |\n" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "As you can see, the test results aren't much different, since this is just a clean application template that contains a few classes. More discussion of preloading, including benchmarks, can be found in the [composer's issue](https://github.com/composer/composer/issues/7777)." -msgstr "" +msgstr "Como você pode ver, os resultados não são muito diferentes, já que este é apenas um template de aplicação limpo, com poucas classes. Mais discussões sobre preload, incluindo benchmarks, estão na [issue do Composer](https://github.com/composer/composer/issues/7777)." #. type: Title ## #: ../src/guide/tutorial/performance-tuning.md #, no-wrap msgid "Performance profiling" -msgstr "" +msgstr "Profiling de desempenho" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "You should profile your code to find out the performance bottlenecks and take appropriate measures accordingly. The following profiling tools may be useful:" -msgstr "" +msgstr "Faça o profiling do seu código para encontrar os gargalos de desempenho e tomar as medidas adequadas. As seguintes ferramentas de profiling podem ser úteis:" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md #, no-wrap msgid "\n" -msgstr "" +msgstr "\n" #. type: Bullet: '- ' #: ../src/guide/tutorial/performance-tuning.md msgid "[Blackfire](https://blackfire.io/)" -msgstr "" +msgstr "[Blackfire](https://blackfire.io/)" #. type: Bullet: '- ' #: ../src/guide/tutorial/performance-tuning.md msgid "[XHProf](https://secure.php.net/manual/en/book.xhprof.php)" -msgstr "" +msgstr "[XHProf](https://secure.php.net/manual/en/book.xhprof.php)" #. type: Bullet: '- ' #: ../src/guide/tutorial/performance-tuning.md msgid "[XDebug profiler](https://xdebug.org/docs/profiler)" -msgstr "" +msgstr "[Profiler do XDebug](https://xdebug.org/docs/profiler)" diff --git a/_translations/po/pt-BR/guide_tutorial_using-with-event-loop.md.po b/_translations/po/pt-BR/guide_tutorial_using-with-event-loop.md.po index 527f548c..7ea76308 100644 --- a/_translations/po/pt-BR/guide_tutorial_using-with-event-loop.md.po +++ b/_translations/po/pt-BR/guide_tutorial_using-with-event-loop.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-10-07 15:22+0000\n" "PO-Revision-Date: 2026-10-07 15:22+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,7 +19,7 @@ msgstr "" #: ../src/guide/tutorial/using-with-event-loop.md #, no-wrap msgid "Using Yii with event loop" -msgstr "" +msgstr "Usando o Yii com event loop" #. type: Plain text #: ../src/guide/tutorial/using-with-event-loop.md @@ -31,27 +31,32 @@ msgid "" "have to take much care about memory leaks or properly clean up context. On the other side, initializing everything for\n" "every request takes time and overall consumes up to 50% of processing resources.\n" msgstr "" +"O ciclo normal de execução de uma requisição web em PHP consiste em preparar o ambiente, receber a requisição, processá-la para gerar uma resposta\n" +"e enviar o resultado. Depois que a resposta é enviada, a execução termina e o contexto se perde. Então, na requisição\n" +" seguinte, toda a sequência se repete. Essa abordagem tem uma grande vantagem na facilidade de desenvolvimento, já que o desenvolvedor não\n" +"precisa se preocupar muito com vazamentos de memória nem com limpar o contexto corretamente. Por outro lado, inicializar tudo a\n" +"cada requisição leva tempo e, no total, consome até 50% dos recursos de processamento.\n" #. type: Plain text #: ../src/guide/tutorial/using-with-event-loop.md msgid "There is an alternative way of running an application. Event loop. The idea is to initialize everything possible at once and then process a number of requests using it. Such an approach is usually called event loop." -msgstr "" +msgstr "Existe outra forma de rodar uma aplicação: o event loop. A ideia é inicializar tudo o que for possível uma única vez e depois processar várias requisições usando esse contexto. Essa abordagem costuma ser chamada de event loop." #. type: Plain text #: ../src/guide/tutorial/using-with-event-loop.md msgid "There are multiple tools that could be used to achieve it. Notably, [FrankenPHP](https://frankenphp.dev/), [Rapira](https://rapira.rs/), [RoadRunner](https://roadrunner.dev/) and [Swoole](https://www.swoole.com/)." -msgstr "" +msgstr "Há várias ferramentas que permitem fazer isso. As principais são [FrankenPHP](https://frankenphp.dev/), [Rapira](https://rapira.rs/), [RoadRunner](https://roadrunner.dev/) e [Swoole](https://www.swoole.com/)." #. type: Title ## #: ../src/guide/tutorial/using-with-event-loop.md #, no-wrap msgid "Event loop implications" -msgstr "" +msgstr "Implicações do event loop" #. type: Plain text #: ../src/guide/tutorial/using-with-event-loop.md msgid "Event loop worker basically looks like the following:" -msgstr "" +msgstr "Um worker de event loop basicamente tem esta cara:" #. type: Fenced code block (php) #: ../src/guide/tutorial/using-with-event-loop.md @@ -63,43 +68,48 @@ msgid "" " emit($response);\n" "}\n" msgstr "" +"initializeContext();\n" +"while ($request = getRequest()) {\n" +" $response = process($request);\n" +" emit($response);\n" +"}\n" #. type: Plain text #: ../src/guide/tutorial/using-with-event-loop.md msgid "Usually, there are multiple workers processing requests at the same time as with traditional php-fpm." -msgstr "" +msgstr "Normalmente, há vários workers processando requisições ao mesmo tempo, como no php-fpm tradicional." #. type: Plain text #: ../src/guide/tutorial/using-with-event-loop.md msgid "That means that there's more to consider when developing applications." -msgstr "" +msgstr "Isso significa que há mais coisas a considerar ao desenvolver aplicações." #. type: Title ### #: ../src/guide/tutorial/using-with-event-loop.md #, no-wrap msgid "Processing is blocking" -msgstr "" +msgstr "O processamento é bloqueante" #. type: Plain text #: ../src/guide/tutorial/using-with-event-loop.md msgid "Worker process requests one by one that's current processing is blocking processing next request. That means that long-running processes, same as in general PHP applications, should be put into a background via using a queue." -msgstr "" +msgstr "O worker processa as requisições uma a uma, ou seja, o processamento atual bloqueia o processamento da próxima requisição. Isso significa que processos demorados, assim como em aplicações PHP comuns, devem ir para segundo plano usando uma fila." #. type: Title ### #: ../src/guide/tutorial/using-with-event-loop.md #, no-wrap msgid "Services and state" -msgstr "" +msgstr "Serviços e estado" #. type: Plain text #: ../src/guide/tutorial/using-with-event-loop.md msgid "Since the context in the event loop is shared between all request-responses processed by a single worker, all changes in the state of a service made by the previous request may affect the current request. Moreover, it can be a security problem if data from one user is available to another user." -msgstr "" +msgstr "Como o contexto no event loop é compartilhado entre todas as requisições e respostas processadas por um mesmo worker, qualquer mudança no estado de um serviço feita pela requisição anterior pode afetar a requisição atual. Além disso, isso pode ser um problema de segurança se os dados de um usuário ficarem disponíveis para outro." #. type: Plain text #: ../src/guide/tutorial/using-with-event-loop.md msgid "There are two ways of dealing with it. First, you can avoid having state by making services stateless. PHP's `readonly` keyword may be handy for it. Second, you can reset the services' state at the end of the request processing. In this case, a state resetter will help you:" -msgstr "" +msgstr "Há duas formas de lidar com isso. A primeira é evitar estado, tornando os serviços stateless. A palavra-chave `readonly` do PHP pode ajudar nisso. A segunda é redefinir o estado dos serviços ao fim do processamento da requisição. Nesse caso, um state resetter vai ajudar você:" #. type: Fenced code block (php) #: ../src/guide/tutorial/using-with-event-loop.md @@ -113,29 +123,36 @@ msgid "" " $resetter->reset(); // We should reset the state of such services on every request.\n" "}\n" msgstr "" +"initializeContext();\n" +"$resetter = $container->get(\\Yiisoft\\Di\\StateResetter::class);\n" +"while ($request = getRequest()) {\n" +" $response = process($request);\n" +" emit($response);\n" +" $resetter->reset(); // Precisamos redefinir o estado desses serviços a cada requisição.\n" +"}\n" #. type: Title ## #: ../src/guide/tutorial/using-with-event-loop.md #, no-wrap msgid "Integrations" -msgstr "" +msgstr "Integrações" #. type: Bullet: '- ' #: ../src/guide/tutorial/using-with-event-loop.md msgid "[FrankenPHP](using-yii-with-frankenphp.md)" -msgstr "" +msgstr "[FrankenPHP](using-yii-with-frankenphp.md)" #. type: Bullet: '- ' #: ../src/guide/tutorial/using-with-event-loop.md msgid "[Rapira](using-yii-with-rapira.md)" -msgstr "" +msgstr "[Rapira](using-yii-with-rapira.md)" #. type: Bullet: '- ' #: ../src/guide/tutorial/using-with-event-loop.md msgid "[RoadRunner](using-yii-with-roadrunner.md)" -msgstr "" +msgstr "[RoadRunner](using-yii-with-roadrunner.md)" #. type: Bullet: '- ' #: ../src/guide/tutorial/using-with-event-loop.md msgid "[Swoole](using-yii-with-swoole.md)" -msgstr "" +msgstr "[Swoole](using-yii-with-swoole.md)" diff --git a/_translations/po/pt-BR/guide_tutorial_using-yii-with-frankenphp.md.po b/_translations/po/pt-BR/guide_tutorial_using-yii-with-frankenphp.md.po index cd472d30..7459bd23 100644 --- a/_translations/po/pt-BR/guide_tutorial_using-yii-with-frankenphp.md.po +++ b/_translations/po/pt-BR/guide_tutorial_using-yii-with-frankenphp.md.po @@ -8,41 +8,30 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-10-07 15:22+0000\n" "PO-Revision-Date: 2026-10-07 15:22+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/cookbook/making-http-requests.md -#: ../src/cookbook/sentry-integration.md -#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md -#: ../src/guide/tutorial/using-yii-with-frankenphp.md -#: ../src/guide/tutorial/using-yii-with-rapira.md -#: ../src/guide/tutorial/using-yii-with-roadrunner.md -#: ../src/guide/tutorial/using-yii-with-swoole.md ../src/guide/views/asset.md -#: ../src/guide/views/view.md ../src/guide/views/widget.md +#: ../src/cookbook/making-http-requests.md ../src/cookbook/sentry-integration.md ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md ../src/guide/tutorial/using-yii-with-frankenphp.md ../src/guide/tutorial/using-yii-with-rapira.md ../src/guide/tutorial/using-yii-with-roadrunner.md ../src/guide/tutorial/using-yii-with-swoole.md ../src/guide/views/asset.md ../src/guide/views/view.md ../src/guide/views/widget.md #, no-wrap msgid "Installation" -msgstr "" +msgstr "Instalação" #. type: Title ## -#: ../src/cookbook/sentry-integration.md ../src/guide/concept/configuration.md -#: ../src/guide/tutorial/using-yii-with-frankenphp.md -#: ../src/guide/tutorial/using-yii-with-rapira.md -#: ../src/guide/tutorial/using-yii-with-roadrunner.md -#: ../src/guide/views/view-injections.md +#: ../src/cookbook/sentry-integration.md ../src/guide/concept/configuration.md ../src/guide/tutorial/using-yii-with-frankenphp.md ../src/guide/tutorial/using-yii-with-rapira.md ../src/guide/tutorial/using-yii-with-roadrunner.md ../src/guide/views/view-injections.md #, no-wrap msgid "Configuration" -msgstr "" +msgstr "Configuração" #. type: Title # #: ../src/guide/tutorial/using-yii-with-frankenphp.md #, no-wrap msgid "Using Yii with FrankenPHP" -msgstr "" +msgstr "Usando o Yii com FrankenPHP" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-frankenphp.md @@ -52,27 +41,30 @@ msgid "" "[worker mode](using-with-event-loop.md), allowing the framework bootstrap to happen once per worker instead of\n" "once per request.\n" msgstr "" +"O [FrankenPHP](https://frankenphp.dev/) é um servidor de aplicação PHP com o Caddy embutido. Ele pode rodar o Yii em\n" +"[modo worker](using-with-event-loop.md), o que faz o bootstrap do framework acontecer uma vez por worker em vez de\n" +"uma vez por requisição.\n" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-frankenphp.md msgid "The [FrankenPHP runner](https://github.com/yiisoft/yii-runner-frankenphp) requires PHP 8.1–8.5. Install FrankenPHP using its [installation instructions](https://frankenphp.dev/docs/), or use the Docker setup in the Yii application templates described below." -msgstr "" +msgstr "O [runner para FrankenPHP](https://github.com/yiisoft/yii-runner-frankenphp) exige PHP 8.1–8.5. Instale o FrankenPHP seguindo as [instruções de instalação](https://frankenphp.dev/docs/) dele, ou use a configuração Docker dos templates de aplicação do Yii, descrita abaixo." #. type: Plain text #: ../src/guide/tutorial/using-yii-with-frankenphp.md msgid "Install the runner package with Composer:" -msgstr "" +msgstr "Instale o pacote do runner com o Composer:" #. type: Fenced code block (shell) #: ../src/guide/tutorial/using-yii-with-frankenphp.md #, no-wrap msgid "composer require yiisoft/yii-runner-frankenphp\n" -msgstr "" +msgstr "composer require yiisoft/yii-runner-frankenphp\n" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-frankenphp.md msgid "FrankenPHP works especially well in containerized deployments and is the runtime used by the Yii application templates Docker setup described in [Docker in application templates](docker.md)." -msgstr "" +msgstr "O FrankenPHP funciona especialmente bem em deploys com containers e é o runtime usado pela configuração Docker dos templates de aplicação do Yii, descrita em [Docker nos templates de aplicação](docker.md)." #. type: Plain text #: ../src/guide/tutorial/using-yii-with-frankenphp.md @@ -82,23 +74,25 @@ msgid "" "> This runner is for worker mode. To use FrankenPHP in classic mode, keep `public/index.php` and\n" "> [yiisoft/yii-runner-http](https://github.com/yiisoft/yii-runner-http), the default HTTP runner in the templates.\n" msgstr "" +"> [!NOTE]\n" +"> Este runner é para o modo worker. Para usar o FrankenPHP no modo clássico, mantenha o `public/index.php` e o\n" +"> [yiisoft/yii-runner-http](https://github.com/yiisoft/yii-runner-http), o runner HTTP padrão dos templates.\n" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-frankenphp.md msgid "First, configure the worker entry script." -msgstr "" +msgstr "Primeiro, configure o script de entrada do worker." #. type: Title ### -#: ../src/guide/tutorial/using-yii-with-frankenphp.md -#: ../src/guide/tutorial/using-yii-with-rapira.md +#: ../src/guide/tutorial/using-yii-with-frankenphp.md ../src/guide/tutorial/using-yii-with-rapira.md #, no-wrap msgid "Worker entry script" -msgstr "" +msgstr "Script de entrada do worker" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-frankenphp.md msgid "Create `/worker.php` in the project root:" -msgstr "" +msgstr "Crie `/worker.php` na raiz do projeto:" #. type: Fenced code block (php) #: ../src/guide/tutorial/using-yii-with-frankenphp.md @@ -147,23 +141,64 @@ msgid "" ");\n" "$runner->run();\n" msgstr "" +"setLevels([\n" +" LogLevel::EMERGENCY,\n" +" LogLevel::ERROR,\n" +" LogLevel::WARNING,\n" +" ]),\n" +" ],\n" +" ),\n" +" new PlainTextRenderer(),\n" +" ),\n" +");\n" +"$runner->run();\n" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-frankenphp.md msgid "The runner bootstraps the application once and then keeps processing requests in worker mode. Unlike classic `public/index.php`, this script is not executed per request." -msgstr "" +msgstr "O runner faz o bootstrap da aplicação uma vez e depois continua processando requisições em modo worker. Diferente do `public/index.php` clássico, este script não é executado a cada requisição." #. type: Title ### -#: ../src/guide/tutorial/using-yii-with-frankenphp.md -#: ../src/guide/tutorial/using-yii-with-rapira.md +#: ../src/guide/tutorial/using-yii-with-frankenphp.md ../src/guide/tutorial/using-yii-with-rapira.md #, no-wrap msgid "Server configuration" -msgstr "" +msgstr "Configuração do servidor" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-frankenphp.md msgid "FrankenPHP is configured through a `Caddyfile`. For production, it may look like the following:" -msgstr "" +msgstr "O FrankenPHP é configurado por um `Caddyfile`. Em produção, ele pode ficar assim:" #. type: Fenced code block (caddyfile) #: ../src/guide/tutorial/using-yii-with-frankenphp.md @@ -188,16 +223,34 @@ msgid "" " }\n" "}\n" msgstr "" +"{\n" +" skip_install_trust\n" +"\n" +" frankenphp {\n" +"\n" +" }\n" +"}\n" +"\n" +"{$SERVER_NAME::80} {\n" +" encode zstd br gzip\n" +" php_server {\n" +" root /app/public\n" +" worker {\n" +" match *\n" +" file /app/worker.php\n" +" }\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-frankenphp.md msgid "This configuration tells FrankenPHP to serve the `public` directory and handle all requests with `worker.php`. Static assets are still served from `public`, while PHP requests are processed through the long-running worker." -msgstr "" +msgstr "Essa configuração diz ao FrankenPHP para servir o diretório `public` e atender todas as requisições com o `worker.php`. Os assets estáticos continuam sendo servidos de `public`, enquanto as requisições PHP são processadas pelo worker de longa duração." #. type: Plain text #: ../src/guide/tutorial/using-yii-with-frankenphp.md msgid "For development, add `watch` so FrankenPHP reloads workers when PHP files change:" -msgstr "" +msgstr "Em desenvolvimento, adicione `watch` para que o FrankenPHP recarregue os workers quando arquivos PHP mudarem:" #. type: Fenced code block (caddyfile) #: ../src/guide/tutorial/using-yii-with-frankenphp.md @@ -223,37 +276,56 @@ msgid "" " }\n" "}\n" msgstr "" +"{\n" +" skip_install_trust\n" +"\n" +" frankenphp {\n" +"\n" +" }\n" +"}\n" +"\n" +"{$SERVER_NAME::80} {\n" +" encode zstd br gzip\n" +" php_server {\n" +" root /app/public\n" +" worker {\n" +" match *\n" +" file /app/worker.php\n" +" watch /app/**/*.php\n" +" }\n" +" }\n" +"}\n" #. type: Title ### #: ../src/guide/tutorial/using-yii-with-frankenphp.md #, no-wrap msgid "Docker setup in Yii application templates" -msgstr "" +msgstr "Configuração Docker nos templates de aplicação do Yii" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-frankenphp.md msgid "Yii application templates already ship with a FrankenPHP-based Docker setup. To switch the application to worker mode, update the files inside the Docker layout instead of relying on `public/index.php`." -msgstr "" +msgstr "Os templates de aplicação do Yii já vêm com uma configuração Docker baseada no FrankenPHP. Para passar a aplicação para o modo worker, altere os arquivos da estrutura Docker em vez de depender do `public/index.php`." #. type: Plain text #: ../src/guide/tutorial/using-yii-with-frankenphp.md msgid "Create `/worker.php` in the project root as shown above, then update the Caddy configuration used by the container. For development, edit `docker/dev/Caddyfile`:" -msgstr "" +msgstr "Crie `/worker.php` na raiz do projeto como mostrado acima e depois altere a configuração do Caddy usada pelo container. Em desenvolvimento, edite `docker/dev/Caddyfile`:" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-frankenphp.md msgid "For production, use the same configuration without `watch` in `docker/Caddyfile`:" -msgstr "" +msgstr "Em produção, use a mesma configuração sem `watch` em `docker/Caddyfile`:" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-frankenphp.md msgid "The templates use `dunglas/frankenphp` as the base image in `docker/Dockerfile`, mount the project into `/app` in development, and pass runtime configuration through environment files such as `docker/dev/.env` and `docker/prod/.env`. The default value of `SERVER_NAME` in these files is `:80`, which matches the examples above." -msgstr "" +msgstr "Os templates usam `dunglas/frankenphp` como imagem base em `docker/Dockerfile`, montam o projeto em `/app` no desenvolvimento e passam a configuração de runtime por arquivos de ambiente como `docker/dev/.env` e `docker/prod/.env`. O valor padrão de `SERVER_NAME` nesses arquivos é `:80`, que corresponde aos exemplos acima." #. type: Plain text #: ../src/guide/tutorial/using-yii-with-frankenphp.md msgid "After changing `worker.php` and the relevant `Caddyfile`, rebuild the image and restart the environment:" -msgstr "" +msgstr "Depois de alterar o `worker.php` e o `Caddyfile` correspondente, reconstrua a imagem e reinicie o ambiente:" #. type: Fenced code block (shell) #: ../src/guide/tutorial/using-yii-with-frankenphp.md @@ -262,109 +334,105 @@ msgid "" "make build\n" "make up\n" msgstr "" +"make build\n" +"make up\n" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-frankenphp.md msgid "In production, rebuild and deploy the production image using the project's production Docker workflow." -msgstr "" +msgstr "Em produção, reconstrua a imagem de produção e faça o deploy usando o fluxo Docker de produção do projeto." #. type: Plain text #: ../src/guide/tutorial/using-yii-with-frankenphp.md msgid "If you switch fully to worker mode, `public/index.php` and `yiisoft/yii-runner-http` are no longer needed." -msgstr "" +msgstr "Se você passar totalmente para o modo worker, o `public/index.php` e o `yiisoft/yii-runner-http` deixam de ser necessários." #. type: Title ## -#: ../src/guide/tutorial/using-yii-with-frankenphp.md -#: ../src/guide/tutorial/using-yii-with-rapira.md -#: ../src/guide/tutorial/using-yii-with-roadrunner.md -#: ../src/guide/tutorial/using-yii-with-swoole.md +#: ../src/guide/tutorial/using-yii-with-frankenphp.md ../src/guide/tutorial/using-yii-with-rapira.md ../src/guide/tutorial/using-yii-with-roadrunner.md ../src/guide/tutorial/using-yii-with-swoole.md #, no-wrap msgid "Starting a server" -msgstr "" +msgstr "Iniciando o servidor" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-frankenphp.md msgid "The exact start command depends on how you run FrankenPHP:" -msgstr "" +msgstr "O comando exato para iniciar depende de como você roda o FrankenPHP:" #. type: Bullet: '- ' #: ../src/guide/tutorial/using-yii-with-frankenphp.md msgid "In the Yii application templates, run `make build` and `make up` after updating `worker.php` and the relevant `Caddyfile`." -msgstr "" +msgstr "Nos templates de aplicação do Yii, execute `make build` e `make up` depois de alterar o `worker.php` e o `Caddyfile` correspondente." #. type: Bullet: '- ' #: ../src/guide/tutorial/using-yii-with-frankenphp.md msgid "With the standalone binary, run the following command from the directory containing your `Caddyfile`:" -msgstr "" +msgstr "Com o binário standalone, execute o seguinte comando no diretório que contém o seu `Caddyfile`:" #. type: Fenced code block (shell) #: ../src/guide/tutorial/using-yii-with-frankenphp.md #, no-wrap msgid "frankenphp run --config Caddyfile\n" -msgstr "" +msgstr "frankenphp run --config Caddyfile\n" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-frankenphp.md msgid "The example configuration uses `/app` as the application root. Adjust `/app/public`, `/app/worker.php`, and the watch path to match your installation. See the [FrankenPHP configuration reference](https://frankenphp.dev/docs/config/) for other deployment options." -msgstr "" +msgstr "A configuração de exemplo usa `/app` como raiz da aplicação. Ajuste `/app/public`, `/app/worker.php` e o caminho do watch conforme a sua instalação. Veja a [referência de configuração do FrankenPHP](https://frankenphp.dev/docs/config/) para outras opções de deploy." #. type: Title ## -#: ../src/guide/tutorial/using-yii-with-frankenphp.md -#: ../src/guide/tutorial/using-yii-with-rapira.md -#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#: ../src/guide/tutorial/using-yii-with-frankenphp.md ../src/guide/tutorial/using-yii-with-rapira.md ../src/guide/tutorial/using-yii-with-roadrunner.md #, no-wrap msgid "On worker scope" -msgstr "" +msgstr "Sobre o escopo do worker" #. type: Bullet: '- ' #: ../src/guide/tutorial/using-yii-with-frankenphp.md msgid "Each worker's memory is isolated from other workers." -msgstr "" +msgstr "A memória de cada worker é isolada da dos outros workers." #. type: Bullet: '- ' #: ../src/guide/tutorial/using-yii-with-frankenphp.md msgid "A single worker handles multiple requests, so services created inside it may keep state between requests." -msgstr "" +msgstr "Um único worker atende várias requisições, então os serviços criados dentro dele podem manter estado entre requisições." #. type: Bullet: '- ' #: ../src/guide/tutorial/using-yii-with-frankenphp.md msgid "At each iteration of the event loop, every stateful service should be reset." -msgstr "" +msgstr "A cada iteração do event loop, todo serviço com estado deve ser redefinido." #. type: Plain text #: ../src/guide/tutorial/using-yii-with-frankenphp.md msgid "For the general implications of long-running workers, see [Using Yii with event loop](using-with-event-loop.md)." -msgstr "" +msgstr "Para as implicações gerais de workers de longa duração, veja [Usando o Yii com event loop](using-with-event-loop.md)." #. type: Title ## #: ../src/guide/tutorial/using-yii-with-frankenphp.md #, no-wrap msgid "Worker mode notes" -msgstr "" +msgstr "Notas sobre o modo worker" #. type: Bullet: '- ' #: ../src/guide/tutorial/using-yii-with-frankenphp.md msgid "Use the `MAX_REQUESTS` environment variable to limit how many requests a worker handles before restart." -msgstr "" +msgstr "Use a variável de ambiente `MAX_REQUESTS` para limitar quantas requisições um worker atende antes de ser reiniciado." #. type: Bullet: '- ' #: ../src/guide/tutorial/using-yii-with-frankenphp.md msgid "The runner calls `Yiisoft\\Di\\StateResetter::reset()` after each request. Register resetters for your stateful services as described in the [Yii DI documentation](https://github.com/yiisoft/di#resetting-services-state)." -msgstr "" +msgstr "O runner chama `Yiisoft\\Di\\StateResetter::reset()` depois de cada requisição. Registre resetters para os seus serviços com estado, como descrito na [documentação do Yii DI](https://github.com/yiisoft/di#resetting-services-state)." #. type: Title ## -#: ../src/guide/tutorial/using-yii-with-frankenphp.md -#: ../src/guide/tutorial/using-yii-with-rapira.md +#: ../src/guide/tutorial/using-yii-with-frankenphp.md ../src/guide/tutorial/using-yii-with-rapira.md #, no-wrap msgid "Additional configuration" -msgstr "" +msgstr "Configuração adicional" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-frankenphp.md msgid "`FrankenPHPApplicationRunner` is configured by default for Yii application templates and follows the [dependency container configuration](../concept/configuration.md#container-configuration) concept." -msgstr "" +msgstr "O `FrankenPHPApplicationRunner` vem configurado por padrão para os templates de aplicação do Yii e segue o conceito de [configuração do container de dependências](../concept/configuration.md#configuracao-do-container)." #. type: Plain text #: ../src/guide/tutorial/using-yii-with-frankenphp.md msgid "The constructor allows overriding the default bootstrap, events, DI, params, and error-handler configuration. You can also provide a custom config instance with `withConfig()` and a custom container with `withContainer()`." -msgstr "" +msgstr "O construtor permite sobrescrever a configuração padrão de bootstrap, eventos, DI, params e tratamento de erros. Você também pode fornecer uma instância de configuração personalizada com `withConfig()` e um container personalizado com `withContainer()`." diff --git a/_translations/po/pt-BR/guide_tutorial_using-yii-with-rapira.md.po b/_translations/po/pt-BR/guide_tutorial_using-yii-with-rapira.md.po index 19374038..0805ae6c 100644 --- a/_translations/po/pt-BR/guide_tutorial_using-yii-with-rapira.md.po +++ b/_translations/po/pt-BR/guide_tutorial_using-yii-with-rapira.md.po @@ -8,80 +8,60 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-10-07 20:23+0000\n" "PO-Revision-Date: 2026-10-07 20:23+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/cookbook/making-http-requests.md -#: ../src/cookbook/sentry-integration.md -#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md -#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md -#: ../src/guide/tutorial/using-yii-with-frankenphp.md -#: ../src/guide/tutorial/using-yii-with-rapira.md -#: ../src/guide/tutorial/using-yii-with-roadrunner.md -#: ../src/guide/tutorial/using-yii-with-swoole.md ../src/guide/views/asset.md -#: ../src/guide/views/view.md ../src/guide/views/widget.md +#: ../src/cookbook/making-http-requests.md ../src/cookbook/sentry-integration.md ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md ../src/guide/tutorial/using-yii-with-frankenphp.md ../src/guide/tutorial/using-yii-with-rapira.md ../src/guide/tutorial/using-yii-with-roadrunner.md ../src/guide/tutorial/using-yii-with-swoole.md ../src/guide/views/asset.md ../src/guide/views/view.md ../src/guide/views/widget.md #, no-wrap msgid "Installation" -msgstr "" +msgstr "Instalação" #. type: Title ## -#: ../src/cookbook/sentry-integration.md ../src/guide/concept/configuration.md -#: ../src/guide/tutorial/using-yii-with-frankenphp.md -#: ../src/guide/tutorial/using-yii-with-rapira.md -#: ../src/guide/tutorial/using-yii-with-roadrunner.md -#: ../src/guide/views/view-injections.md +#: ../src/cookbook/sentry-integration.md ../src/guide/concept/configuration.md ../src/guide/tutorial/using-yii-with-frankenphp.md ../src/guide/tutorial/using-yii-with-rapira.md ../src/guide/tutorial/using-yii-with-roadrunner.md ../src/guide/views/view-injections.md #, no-wrap msgid "Configuration" -msgstr "" +msgstr "Configuração" #. type: Title ### -#: ../src/guide/tutorial/using-yii-with-frankenphp.md -#: ../src/guide/tutorial/using-yii-with-rapira.md +#: ../src/guide/tutorial/using-yii-with-frankenphp.md ../src/guide/tutorial/using-yii-with-rapira.md #, no-wrap msgid "Worker entry script" -msgstr "" +msgstr "Script de entrada do worker" #. type: Title ### -#: ../src/guide/tutorial/using-yii-with-frankenphp.md -#: ../src/guide/tutorial/using-yii-with-rapira.md +#: ../src/guide/tutorial/using-yii-with-frankenphp.md ../src/guide/tutorial/using-yii-with-rapira.md #, no-wrap msgid "Server configuration" -msgstr "" +msgstr "Configuração do servidor" #. type: Title ## -#: ../src/guide/tutorial/using-yii-with-frankenphp.md -#: ../src/guide/tutorial/using-yii-with-rapira.md -#: ../src/guide/tutorial/using-yii-with-roadrunner.md -#: ../src/guide/tutorial/using-yii-with-swoole.md +#: ../src/guide/tutorial/using-yii-with-frankenphp.md ../src/guide/tutorial/using-yii-with-rapira.md ../src/guide/tutorial/using-yii-with-roadrunner.md ../src/guide/tutorial/using-yii-with-swoole.md #, no-wrap msgid "Starting a server" -msgstr "" +msgstr "Iniciando o servidor" #. type: Title ## -#: ../src/guide/tutorial/using-yii-with-frankenphp.md -#: ../src/guide/tutorial/using-yii-with-rapira.md -#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#: ../src/guide/tutorial/using-yii-with-frankenphp.md ../src/guide/tutorial/using-yii-with-rapira.md ../src/guide/tutorial/using-yii-with-roadrunner.md #, no-wrap msgid "On worker scope" -msgstr "" +msgstr "Sobre o escopo do worker" #. type: Title ## -#: ../src/guide/tutorial/using-yii-with-frankenphp.md -#: ../src/guide/tutorial/using-yii-with-rapira.md +#: ../src/guide/tutorial/using-yii-with-frankenphp.md ../src/guide/tutorial/using-yii-with-rapira.md #, no-wrap msgid "Additional configuration" -msgstr "" +msgstr "Configuração adicional" #. type: Title # #: ../src/guide/tutorial/using-yii-with-rapira.md #, no-wrap msgid "Using Yii with Rapira" -msgstr "" +msgstr "Usando o Yii com Rapira" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-rapira.md @@ -92,37 +72,41 @@ msgid "" "Worker and dispatcher modes initialize the application once per worker and reuse it for subsequent requests.\n" "See [Using Yii with event loop](using-with-event-loop.md) for the implications of keeping the application in memory.\n" msgstr "" +"O [Rapira](https://rapira.rs/) é um servidor de aplicação PHP escrito em Rust que embute o interpretador PHP.\n" +"O [runner do Yii para Rapira](https://github.com/yiisoft/yii-runner-rapira) suporta os modos classic, worker e dispatcher.\n" +"Os modos worker e dispatcher inicializam a aplicação uma vez por worker e a reaproveitam nas requisições seguintes.\n" +"Veja [Usando o Yii com event loop](using-with-event-loop.md) para as implicações de manter a aplicação na memória.\n" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-rapira.md msgid "The runner requires PHP 8.4–8.5. Install the Rapira binary following the [Rapira installation instructions](https://rapira.rs/docs/intro/installation), using a PHP version supported by the runner. The Composer packages provide the Yii integration; the server binary must be installed separately." -msgstr "" +msgstr "O runner exige PHP 8.4–8.5. Instale o binário do Rapira seguindo as [instruções de instalação do Rapira](https://rapira.rs/docs/intro/installation), com uma versão do PHP suportada pelo runner. Os pacotes do Composer fornecem a integração com o Yii; o binário do servidor precisa ser instalado à parte." #. type: Plain text #: ../src/guide/tutorial/using-yii-with-rapira.md msgid "Install the runner and its contract package in your Yii application:" -msgstr "" +msgstr "Instale o runner e o pacote de contratos dele na sua aplicação Yii:" #. type: Fenced code block (shell) #: ../src/guide/tutorial/using-yii-with-rapira.md #, no-wrap msgid "composer require yiisoft/yii-runner-rapira:@dev rapira/contract:@dev\n" -msgstr "" +msgstr "composer require yiisoft/yii-runner-rapira:@dev rapira/contract:@dev\n" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-rapira.md msgid "These stability flags allow the development versions used by the runner's installation instructions." -msgstr "" +msgstr "Essas flags de estabilidade permitem as versões de desenvolvimento usadas nas instruções de instalação do runner." #. type: Plain text #: ../src/guide/tutorial/using-yii-with-rapira.md msgid "The following example assumes an application based on `yiisoft/app` or `yiisoft/app-api`, with `App\\Environment` and `src/bootstrap.php` provided by the template." -msgstr "" +msgstr "O exemplo a seguir supõe uma aplicação baseada em `yiisoft/app` ou `yiisoft/app-api`, com `App\\Environment` e `src/bootstrap.php` fornecidos pelo template." #. type: Plain text #: ../src/guide/tutorial/using-yii-with-rapira.md msgid "Create `worker.php` in the application root:" -msgstr "" +msgstr "Crie `worker.php` na raiz da aplicação:" #. type: Fenced code block (php) #: ../src/guide/tutorial/using-yii-with-rapira.md @@ -164,16 +148,51 @@ msgid "" ");\n" "$runner->run();\n" msgstr "" +"setLevels([\n" +" LogLevel::EMERGENCY,\n" +" LogLevel::ERROR,\n" +" LogLevel::WARNING,\n" +" ]),\n" +" ],\n" +" ),\n" +" new PlainTextRenderer(),\n" +" ),\n" +");\n" +"$runner->run();\n" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-rapira.md msgid "The runner creates the container, starts the application, converts incoming requests to PSR-7 requests, and emits responses. It detects the Rapira execution mode, so the same entry script can be used with all three modes." -msgstr "" +msgstr "O runner cria o container, inicia a aplicação, converte as requisições recebidas em requisições PSR-7 e emite as respostas. Ele detecta o modo de execução do Rapira, então o mesmo script de entrada serve para os três modos." #. type: Plain text #: ../src/guide/tutorial/using-yii-with-rapira.md msgid "Create `rapira.toml` next to `worker.php`:" -msgstr "" +msgstr "Crie `rapira.toml` ao lado de `worker.php`:" #. type: Fenced code block (toml) #: ../src/guide/tutorial/using-yii-with-rapira.md @@ -187,70 +206,77 @@ msgid "" "mode = \"worker\"\n" "max_requests = 1000\n" msgstr "" +"[http]\n" +"listen = \"127.0.0.1:8000\"\n" +"\n" +"[http.pool]\n" +"entrypoint = \"worker.php\"\n" +"mode = \"worker\"\n" +"max_requests = 1000\n" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-rapira.md msgid "This configuration listens on the loopback interface and recycles each worker after 1,000 requests. For serving files from `public`, follow Rapira's [static file configuration](https://rapira.rs/docs/static-files). See the [configuration reference](https://rapira.rs/docs/configuration) for the other server and pool settings." -msgstr "" +msgstr "Essa configuração escuta na interface de loopback e recicla cada worker depois de 1.000 requisições. Para servir arquivos de `public`, siga a [configuração de arquivos estáticos](https://rapira.rs/docs/static-files) do Rapira. Veja a [referência de configuração](https://rapira.rs/docs/configuration) para as outras opções do servidor e do pool." #. type: Plain text #: ../src/guide/tutorial/using-yii-with-rapira.md msgid "Run the following command from the application root:" -msgstr "" +msgstr "Execute o seguinte comando na raiz da aplicação:" #. type: Fenced code block (shell) #: ../src/guide/tutorial/using-yii-with-rapira.md #, no-wrap msgid "rapira serve rapira.toml\n" -msgstr "" +msgstr "rapira serve rapira.toml\n" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-rapira.md msgid "Open `http://127.0.0.1:8000` to access the application. Restart the server after changing application code or configuration." -msgstr "" +msgstr "Abra `http://127.0.0.1:8000` para acessar a aplicação. Reinicie o servidor depois de alterar o código ou a configuração da aplicação." #. type: Title ## #: ../src/guide/tutorial/using-yii-with-rapira.md #, no-wrap msgid "Execution modes" -msgstr "" +msgstr "Modos de execução" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-rapira.md msgid "Set `mode` in the `[http.pool]` section of `rapira.toml` to choose how requests are processed:" -msgstr "" +msgstr "Defina `mode` na seção `[http.pool]` do `rapira.toml` para escolher como as requisições são processadas:" #. type: Bullet: '- ' #: ../src/guide/tutorial/using-yii-with-rapira.md msgid "`classic` initializes the application for each request, similarly to PHP-FPM." -msgstr "" +msgstr "`classic` inicializa a aplicação a cada requisição, como no PHP-FPM." #. type: Bullet: '- ' #: ../src/guide/tutorial/using-yii-with-rapira.md msgid "`worker` keeps the application in memory and receives requests through PHP's SAPI superglobals." -msgstr "" +msgstr "`worker` mantém a aplicação na memória e recebe as requisições pelas superglobais da SAPI do PHP." #. type: Bullet: '- ' #: ../src/guide/tutorial/using-yii-with-rapira.md msgid "`dispatcher` keeps the application in memory and receives request objects through Rapira's dispatcher API. The Yii runner processes these requests sequentially within each worker." -msgstr "" +msgstr "`dispatcher` mantém a aplicação na memória e recebe objetos de requisição pela API de dispatcher do Rapira. O runner do Yii processa essas requisições sequencialmente dentro de cada worker." #. type: Plain text #: ../src/guide/tutorial/using-yii-with-rapira.md msgid "See [Rapira execution modes](https://rapira.rs/docs/execution-modes) for details." -msgstr "" +msgstr "Veja [os modos de execução do Rapira](https://rapira.rs/docs/execution-modes) para mais detalhes." #. type: Plain text #: ../src/guide/tutorial/using-yii-with-rapira.md msgid "In worker and dispatcher modes, services may retain state between requests. The runner calls `Yiisoft\\Di\\StateResetter::reset()` after each request, but you must configure resetters for your own stateful services. See the [Yii DI documentation](https://github.com/yiisoft/di#resetting-services-state)." -msgstr "" +msgstr "Nos modos worker e dispatcher, os serviços podem manter estado entre requisições. O runner chama `Yiisoft\\Di\\StateResetter::reset()` depois de cada requisição, mas você precisa configurar resetters para os seus próprios serviços com estado. Veja a [documentação do Yii DI](https://github.com/yiisoft/di#resetting-services-state)." #. type: Plain text #: ../src/guide/tutorial/using-yii-with-rapira.md msgid "The `max_requests` setting limits how long a worker lives; it does not replace resetting request-specific state." -msgstr "" +msgstr "A opção `max_requests` limita quanto tempo um worker vive; ela não substitui a redefinição do estado específico de cada requisição." #. type: Plain text #: ../src/guide/tutorial/using-yii-with-rapira.md msgid "`RapiraApplicationRunner` uses the application templates' web configuration groups by default. Its constructor accepts alternative groups, configuration directories, and a temporary error handler. Use `withConfig()` to supply a custom configuration instance or `withContainer()` to supply a PSR-11 container. See the [runner documentation](https://github.com/yiisoft/yii-runner-rapira#configuration) for examples." -msgstr "" +msgstr "O `RapiraApplicationRunner` usa por padrão os grupos de configuração web dos templates de aplicação. O construtor aceita grupos alternativos, diretórios de configuração e um error handler temporário. Use `withConfig()` para fornecer uma instância de configuração personalizada ou `withContainer()` para fornecer um container PSR-11. Veja a [documentação do runner](https://github.com/yiisoft/yii-runner-rapira#configuration) para exemplos." diff --git a/_translations/po/pt-BR/guide_tutorial_using-yii-with-roadrunner.md.po b/_translations/po/pt-BR/guide_tutorial_using-yii-with-roadrunner.md.po index ec4518b1..0f4e3dd0 100644 --- a/_translations/po/pt-BR/guide_tutorial_using-yii-with-roadrunner.md.po +++ b/_translations/po/pt-BR/guide_tutorial_using-yii-with-roadrunner.md.po @@ -8,54 +8,42 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-09-25 14:35+0000\n" "PO-Revision-Date: 2026-09-25 14:35+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/cookbook/making-http-requests.md -#: ../src/cookbook/sentry-integration.md -#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md -#: ../src/guide/tutorial/using-yii-with-frankenphp.md -#: ../src/guide/tutorial/using-yii-with-roadrunner.md -#: ../src/guide/tutorial/using-yii-with-swoole.md ../src/guide/views/asset.md -#: ../src/guide/views/view.md ../src/guide/views/widget.md +#: ../src/cookbook/making-http-requests.md ../src/cookbook/sentry-integration.md ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md ../src/guide/tutorial/using-yii-with-frankenphp.md ../src/guide/tutorial/using-yii-with-roadrunner.md ../src/guide/tutorial/using-yii-with-swoole.md ../src/guide/views/asset.md ../src/guide/views/view.md ../src/guide/views/widget.md #, no-wrap msgid "Installation" -msgstr "" +msgstr "Instalação" #. type: Title ## -#: ../src/cookbook/sentry-integration.md ../src/guide/concept/configuration.md -#: ../src/guide/tutorial/using-yii-with-frankenphp.md -#: ../src/guide/tutorial/using-yii-with-roadrunner.md -#: ../src/guide/views/view-injections.md +#: ../src/cookbook/sentry-integration.md ../src/guide/concept/configuration.md ../src/guide/tutorial/using-yii-with-frankenphp.md ../src/guide/tutorial/using-yii-with-roadrunner.md ../src/guide/views/view-injections.md #, no-wrap msgid "Configuration" -msgstr "" +msgstr "Configuração" #. type: Title ## -#: ../src/guide/tutorial/using-yii-with-frankenphp.md -#: ../src/guide/tutorial/using-yii-with-roadrunner.md -#: ../src/guide/tutorial/using-yii-with-swoole.md +#: ../src/guide/tutorial/using-yii-with-frankenphp.md ../src/guide/tutorial/using-yii-with-roadrunner.md ../src/guide/tutorial/using-yii-with-swoole.md #, no-wrap msgid "Starting a server" -msgstr "" +msgstr "Iniciando o servidor" #. type: Title ## -#: ../src/guide/tutorial/using-yii-with-frankenphp.md -#: ../src/guide/tutorial/using-yii-with-roadrunner.md +#: ../src/guide/tutorial/using-yii-with-frankenphp.md ../src/guide/tutorial/using-yii-with-roadrunner.md #, no-wrap msgid "On worker scope" -msgstr "" +msgstr "Sobre o escopo do worker" #. type: Title # #: ../src/guide/tutorial/using-yii-with-roadrunner.md #, no-wrap msgid "Using Yii with RoadRunner" -msgstr "" +msgstr "Usando o Yii com RoadRunner" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-roadrunner.md @@ -66,38 +54,42 @@ msgid "" "[event loop](using-with-event-loop.md) and allows not re-initializing a framework for each request that improves\n" "performance significantly.\n" msgstr "" +"O [RoadRunner](https://roadrunner.dev/) é um servidor de aplicação escrito em Go que se integra bem ao PHP. Ele roda\n" +"o PHP como workers, e cada worker pode atender várias requisições. Esse modo de operação costuma ser chamado de\n" +"[event loop](using-with-event-loop.md) e evita reinicializar o framework a cada requisição, o que melhora\n" +"bastante o desempenho.\n" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-roadrunner.md msgid "RoadRunner works on Linux, macOS and Windows. The best way to install it is to use a Composer:" -msgstr "" +msgstr "O RoadRunner funciona no Linux, macOS e Windows. A melhor forma de instalá-lo é pelo Composer:" #. type: Fenced code block #: ../src/guide/tutorial/using-yii-with-roadrunner.md #, no-wrap msgid "composer require yiisoft/yii-runner-roadrunner\n" -msgstr "" +msgstr "composer require yiisoft/yii-runner-roadrunner\n" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-roadrunner.md msgid "After installation is done, run" -msgstr "" +msgstr "Terminada a instalação, execute" #. type: Fenced code block #: ../src/guide/tutorial/using-yii-with-roadrunner.md #, no-wrap msgid "./vendor/bin/rr get\n" -msgstr "" +msgstr "./vendor/bin/rr get\n" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-roadrunner.md msgid "That would download ready to use RoadRunner server `rr` binary." -msgstr "" +msgstr "Isso baixa o binário `rr` do servidor RoadRunner, pronto para uso." #. type: Plain text #: ../src/guide/tutorial/using-yii-with-roadrunner.md msgid "First, we need to configure the server itself. Create `/.rr.yaml` and add the following config:" -msgstr "" +msgstr "Primeiro, precisamos configurar o próprio servidor. Crie `/.rr.yaml` e adicione a seguinte configuração:" #. type: Fenced code block (yaml) #: ../src/guide/tutorial/using-yii-with-roadrunner.md @@ -129,6 +121,31 @@ msgid "" " mode: production\n" " level: warn\n" msgstr "" +"version: '3'\n" +"\n" +"server:\n" +" command: \"php worker.php\"\n" +"\n" +"rpc:\n" +" listen: tcp://127.0.0.1:6001\n" +"\n" +"http:\n" +" address: :8080\n" +" pool:\n" +" debug: false # defina como true apenas no desenvolvimento local\n" +" supervisor:\n" +" max_worker_memory: 192\n" +" middleware: [static, gzip, headers, sendfile]\n" +" static:\n" +" dir: \"public\"\n" +" forbid: [\".php\", \".htaccess\"]\n" +" headers:\n" +" response:\n" +" \"Cache-Control\": \"no-cache\"\n" +"\n" +"logs:\n" +" mode: production\n" +" level: warn\n" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-roadrunner.md @@ -137,38 +154,40 @@ msgid "" "> [!INFO]\n" "> Read more about TLS, HTTP/2, HTTP/3 configuration and other middleware [on the RoadRunner docs](https://docs.roadrunner.dev/docs/http/http).\n" msgstr "" +"> [!INFO]\n" +"> Saiba mais sobre configuração de TLS, HTTP/2, HTTP/3 e outros middlewares [na documentação do RoadRunner](https://docs.roadrunner.dev/docs/http/http).\n" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-roadrunner.md msgid "We're specifying that the entry script is `worker.php`, the server listens on port 8080, `public` directory files are served statically except `.php` and `.htaccess`. The `max_worker_memory` is a soft limit: if a worker exceeds 192 MB, it will restart after finishing its current request. Also, we're sending an additional header." -msgstr "" +msgstr "Estamos definindo que o script de entrada é o `worker.php`, que o servidor escuta na porta 8080 e que os arquivos do diretório `public` são servidos estaticamente, exceto `.php` e `.htaccess`. O `max_worker_memory` é um limite flexível: se um worker passar de 192 MB, ele reinicia depois de terminar a requisição atual. Também estamos enviando um header adicional." #. type: Title ## #: ../src/guide/tutorial/using-yii-with-roadrunner.md #, no-wrap msgid "KV cache" -msgstr "" +msgstr "Cache KV" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-roadrunner.md msgid "RoadRunner has a [KV plugin](https://docs.roadrunner.dev/docs/key-value/overview-kv) that can be used as a PSR-16 cache storage. It is useful when the application already runs under RoadRunner and needs a cache shared by workers." -msgstr "" +msgstr "O RoadRunner tem um [plugin KV](https://docs.roadrunner.dev/docs/key-value/overview-kv) que pode ser usado como armazenamento de cache PSR-16. Ele é útil quando a aplicação já roda no RoadRunner e precisa de um cache compartilhado entre os workers." #. type: Plain text #: ../src/guide/tutorial/using-yii-with-roadrunner.md msgid "Install the PHP bridge and Yii cache package:" -msgstr "" +msgstr "Instale a ponte PHP e o pacote de cache do Yii:" #. type: Fenced code block #: ../src/guide/tutorial/using-yii-with-roadrunner.md #, no-wrap msgid "composer require spiral/roadrunner-kv yiisoft/cache\n" -msgstr "" +msgstr "composer require spiral/roadrunner-kv yiisoft/cache\n" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-roadrunner.md msgid "Add a KV storage to `.rr.yaml`:" -msgstr "" +msgstr "Adicione um armazenamento KV ao `.rr.yaml`:" #. type: Fenced code block (yaml) #: ../src/guide/tutorial/using-yii-with-roadrunner.md @@ -180,16 +199,21 @@ msgid "" " config:\n" " interval: 60\n" msgstr "" +"kv:\n" +" cache:\n" +" driver: memory\n" +" config:\n" +" interval: 60\n" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-roadrunner.md msgid "The `memory` driver stores values inside the RoadRunner process, so its data is lost when RoadRunner stops. For persistent cache storage, use another KV driver from the RoadRunner documentation." -msgstr "" +msgstr "O driver `memory` guarda os valores dentro do processo do RoadRunner, então os dados se perdem quando o RoadRunner para. Para um armazenamento de cache persistente, use outro driver KV da documentação do RoadRunner." #. type: Plain text #: ../src/guide/tutorial/using-yii-with-roadrunner.md msgid "Create `config/common/di/roadrunner-kv.php`:" -msgstr "" +msgstr "Crie `config/common/di/roadrunner-kv.php`:" #. type: Fenced code block (php) #: ../src/guide/tutorial/using-yii-with-roadrunner.md @@ -217,11 +241,32 @@ msgid "" " YiiCacheInterface::class => Cache::class,\n" "];\n" msgstr "" +" static function (): StorageInterface {\n" +" $factory = new Factory(RPC::create('tcp://127.0.0.1:6001'));\n" +"\n" +" return $factory->select('cache');\n" +" },\n" +"\n" +" SimpleCacheInterface::class => StorageInterface::class,\n" +" YiiCacheInterface::class => Cache::class,\n" +"];\n" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-roadrunner.md msgid "Now services can use `Yiisoft\\Cache\\CacheInterface` the same way as with other cache backends:" -msgstr "" +msgstr "Agora os serviços podem usar `Yiisoft\\Cache\\CacheInterface` do mesmo jeito que com outros backends de cache:" #. type: Fenced code block (php) #: ../src/guide/tutorial/using-yii-with-roadrunner.md @@ -247,11 +292,30 @@ msgid "" " }\n" "}\n" msgstr "" +"use Yiisoft\\Cache\\CacheInterface;\n" +"\n" +"final readonly class FeedService\n" +"{\n" +" public function __construct(\n" +" private CacheInterface $cache,\n" +" ) {\n" +" }\n" +"\n" +" public function latest(): array\n" +" {\n" +" return $this->cache->getOrSet('feed-latest', fn (): array => $this->loadLatest(), 60);\n" +" }\n" +"\n" +" private function loadLatest(): array\n" +" {\n" +" return [];\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-roadrunner.md msgid "Create `/worker.php`:" -msgstr "" +msgstr "Crie `/worker.php`:" #. type: Fenced code block (php) #: ../src/guide/tutorial/using-yii-with-roadrunner.md @@ -275,30 +339,46 @@ msgid "" " environment: Environment::appEnv()\n" "))->run();\n" msgstr "" +"run();\n" #. type: Plain text -#: ../src/guide/tutorial/using-yii-with-roadrunner.md -#: ../src/guide/tutorial/using-yii-with-swoole.md +#: ../src/guide/tutorial/using-yii-with-roadrunner.md ../src/guide/tutorial/using-yii-with-swoole.md msgid "To start a server, execute the following command:" -msgstr "" +msgstr "Para iniciar o servidor, execute o seguinte comando:" #. type: Fenced code block #: ../src/guide/tutorial/using-yii-with-roadrunner.md #, no-wrap msgid "./rr serve\n" -msgstr "" +msgstr "./rr serve\n" #. type: Bullet: '- ' #: ../src/guide/tutorial/using-yii-with-roadrunner.md msgid "Each worker's scope is isolated from other workers. Memory isn't shared." -msgstr "" +msgstr "O escopo de cada worker é isolado dos outros workers. A memória não é compartilhada." #. type: Bullet: '- ' #: ../src/guide/tutorial/using-yii-with-roadrunner.md msgid "A single worker serves multiple requests where the scope is shared." -msgstr "" +msgstr "Um único worker atende várias requisições, e nelas o escopo é compartilhado." #. type: Bullet: '- ' #: ../src/guide/tutorial/using-yii-with-roadrunner.md msgid "At each iteration of the event loop, every service that depends on state should be reset." -msgstr "" +msgstr "A cada iteração do event loop, todo serviço que depende de estado deve ser redefinido." diff --git a/_translations/po/pt-BR/guide_tutorial_using-yii-with-swoole.md.po b/_translations/po/pt-BR/guide_tutorial_using-yii-with-swoole.md.po index fd52dfbd..3f3526c7 100644 --- a/_translations/po/pt-BR/guide_tutorial_using-yii-with-swoole.md.po +++ b/_translations/po/pt-BR/guide_tutorial_using-yii-with-swoole.md.po @@ -8,54 +8,41 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-10-07 20:23+0000\n" "PO-Revision-Date: 2026-10-07 20:23+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/cookbook/making-http-requests.md -#: ../src/cookbook/sentry-integration.md -#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md -#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md -#: ../src/guide/tutorial/using-yii-with-frankenphp.md -#: ../src/guide/tutorial/using-yii-with-rapira.md -#: ../src/guide/tutorial/using-yii-with-roadrunner.md -#: ../src/guide/tutorial/using-yii-with-swoole.md ../src/guide/views/asset.md -#: ../src/guide/views/view.md ../src/guide/views/widget.md +#: ../src/cookbook/making-http-requests.md ../src/cookbook/sentry-integration.md ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md ../src/guide/tutorial/using-yii-with-frankenphp.md ../src/guide/tutorial/using-yii-with-rapira.md ../src/guide/tutorial/using-yii-with-roadrunner.md ../src/guide/tutorial/using-yii-with-swoole.md ../src/guide/views/asset.md ../src/guide/views/view.md ../src/guide/views/widget.md #, no-wrap msgid "Installation" -msgstr "" +msgstr "Instalação" #. type: Title ## -#: ../src/guide/runtime/sessions.md -#: ../src/guide/tutorial/using-yii-with-swoole.md +#: ../src/guide/runtime/sessions.md ../src/guide/tutorial/using-yii-with-swoole.md #, no-wrap msgid "Sessions" msgstr "Sessões" #. type: Title ## -#: ../src/guide/tutorial/using-yii-with-frankenphp.md -#: ../src/guide/tutorial/using-yii-with-rapira.md -#: ../src/guide/tutorial/using-yii-with-roadrunner.md -#: ../src/guide/tutorial/using-yii-with-swoole.md +#: ../src/guide/tutorial/using-yii-with-frankenphp.md ../src/guide/tutorial/using-yii-with-rapira.md ../src/guide/tutorial/using-yii-with-roadrunner.md ../src/guide/tutorial/using-yii-with-swoole.md #, no-wrap msgid "Starting a server" -msgstr "" +msgstr "Iniciando o servidor" #. type: Plain text -#: ../src/guide/tutorial/using-yii-with-roadrunner.md -#: ../src/guide/tutorial/using-yii-with-swoole.md +#: ../src/guide/tutorial/using-yii-with-roadrunner.md ../src/guide/tutorial/using-yii-with-swoole.md msgid "To start a server, execute the following command:" -msgstr "" +msgstr "Para iniciar o servidor, execute o seguinte comando:" #. type: Title # #: ../src/guide/tutorial/using-yii-with-swoole.md #, no-wrap msgid "Using Yii with Swoole" -msgstr "" +msgstr "Usando o Yii com Swoole" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-swoole.md @@ -64,71 +51,73 @@ msgid "" "[Swoole](https://www.swoole.com/) is a PHP extension for event-driven, coroutine-based network applications. It\n" "includes an HTTP server, coroutine APIs, and runtime hooks for common blocking I/O functions.\n" msgstr "" +"O [Swoole](https://www.swoole.com/) é uma extensão PHP para aplicações de rede orientadas a eventos e baseadas em corrotinas. Ela\n" +"inclui um servidor HTTP, APIs de corrotinas e hooks de runtime para as funções de I/O bloqueantes mais comuns.\n" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-swoole.md msgid "Swoole allows Yii request handlers to run as workers. Each worker may handle multiple requests. Such an operation mode is often called [event loop](using-with-event-loop.md) and allows not re-initializing a framework for each request that improves performance significantly." -msgstr "" +msgstr "O Swoole permite que os handlers de requisição do Yii rodem como workers. Cada worker pode atender várias requisições. Esse modo de operação costuma ser chamado de [event loop](using-with-event-loop.md) e evita reinicializar o framework a cada requisição, o que melhora bastante o desempenho." #. type: Plain text #: ../src/guide/tutorial/using-yii-with-swoole.md msgid "Swoole supports Linux, macOS, Cygwin, and WSL. Install the extension through PECL:" -msgstr "" +msgstr "O Swoole suporta Linux, macOS, Cygwin e WSL. Instale a extensão pelo PECL:" #. type: Fenced code block (bash) #: ../src/guide/tutorial/using-yii-with-swoole.md #, no-wrap msgid "pecl install swoole\n" -msgstr "" +msgstr "pecl install swoole\n" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-swoole.md msgid "If PECL doesn't enable the extension automatically, add it to your `php.ini`:" -msgstr "" +msgstr "Se o PECL não habilitar a extensão automaticamente, adicione-a ao seu `php.ini`:" #. type: Fenced code block (ini) #: ../src/guide/tutorial/using-yii-with-swoole.md #, no-wrap msgid "extension=swoole.so\n" -msgstr "" +msgstr "extension=swoole.so\n" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-swoole.md msgid "Check that PHP loads the extension:" -msgstr "" +msgstr "Confira se o PHP carrega a extensão:" #. type: Fenced code block (bash) #: ../src/guide/tutorial/using-yii-with-swoole.md #, no-wrap msgid "php --ri swoole\n" -msgstr "" +msgstr "php --ri swoole\n" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-swoole.md msgid "The Swoole project also provides a [Docker image](https://github.com/swoole/docker-swoole) and documents source builds with optional features such as OpenSSL, sockets, MySQL, PostgreSQL, and curl hooks." -msgstr "" +msgstr "O projeto Swoole também oferece uma [imagem Docker](https://github.com/swoole/docker-swoole) e documenta builds a partir do código-fonte com recursos opcionais, como hooks para OpenSSL, sockets, MySQL, PostgreSQL e curl." #. type: Title ## #: ../src/guide/tutorial/using-yii-with-swoole.md #, no-wrap msgid "Putting up a server" -msgstr "" +msgstr "Subindo um servidor" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-swoole.md msgid "Swoole passes `Swoole\\Http\\Request` and `Swoole\\Http\\Response` objects to request callbacks. Yii handles PSR-7 requests and responses, so add a converter package:" -msgstr "" +msgstr "O Swoole passa objetos `Swoole\\Http\\Request` e `Swoole\\Http\\Response` para os callbacks de requisição. O Yii trabalha com requisições e respostas PSR-7, então adicione um pacote conversor:" #. type: Fenced code block (shell) #: ../src/guide/tutorial/using-yii-with-swoole.md #, no-wrap msgid "composer require ilexn/swoole-convert-psr7\n" -msgstr "" +msgstr "composer require ilexn/swoole-convert-psr7\n" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-swoole.md msgid "Create an entry script, `server.php`:" -msgstr "" +msgstr "Crie um script de entrada, `server.php`:" #. type: Fenced code block (php) #: ../src/guide/tutorial/using-yii-with-swoole.md @@ -223,40 +212,128 @@ msgid "" "\n" "$server->start();\n" msgstr "" +"setLevels([\n" +" LogLevel::EMERGENCY,\n" +" LogLevel::ERROR,\n" +" LogLevel::WARNING,\n" +" ]),\n" +" ],\n" +" ),\n" +" new HtmlRenderer(),\n" +" ),\n" +");\n" +"\n" +"$container = $runner->getContainer();\n" +"$application = $container->get(Application::class);\n" +"$errorCatcher = $container->get(ErrorCatcher::class);\n" +"\n" +"$serverRequestFactory = new SwooleServerRequestConverter(\n" +" $container->get(ServerRequestFactoryInterface::class),\n" +" $container->get(UriFactoryInterface::class),\n" +" $container->get(UploadedFileFactoryInterface::class),\n" +" $container->get(StreamFactoryInterface::class)\n" +");\n" +"\n" +"$server = new Server('0.0.0.0', 9501);\n" +"\n" +"$server->on('start', static function (Server $server) use ($application) {\n" +" $application->start();\n" +" echo \"Swoole http server is started at http://127.0.0.1:9501\\n\";\n" +"});\n" +"\n" +"$server->on('request', static function (\n" +" Request $request,\n" +" Response $response\n" +") use ($serverRequestFactory, $application, $errorCatcher, $container) {\n" +" try {\n" +" $psr7Request = $serverRequestFactory->createFromSwoole($request);\n" +" $psr7Response = $application->handle($psr7Request);\n" +" (new SwooleResponseConverter($response))->send($psr7Response);\n" +" } catch (Throwable $throwable) {\n" +" $handler = new ThrowableHandler($throwable);\n" +" $psr7Response = $errorCatcher->process($request, $handler);\n" +" (new SwooleResponseConverter($response))->send($psr7Response);\n" +" }\n" +" $application->afterEmit($psr7Response);\n" +" $container->get(StateResetter::class)->reset();\n" +"});\n" +"\n" +"$server->on('shutdown', static function (Server $server) use ($application) {\n" +" $application->shutdown();\n" +"});\n" +"\n" +"$server->start();\n" #. type: Fenced code block #: ../src/guide/tutorial/using-yii-with-swoole.md #, no-wrap msgid "php server.php\n" -msgstr "" +msgstr "php server.php\n" #. type: Title ## #: ../src/guide/tutorial/using-yii-with-swoole.md #, no-wrap msgid "On scope" -msgstr "" +msgstr "Sobre o escopo" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-swoole.md msgid "A scope is shared, so at each iteration of the event loop every service that depends on state should be reset." -msgstr "" +msgstr "O escopo é compartilhado, então a cada iteração do event loop todo serviço que depende de estado deve ser redefinido." #. type: Plain text #: ../src/guide/tutorial/using-yii-with-swoole.md msgid "Avoid native PHP sessions, including `Yiisoft\\Session\\Session`, when Swoole coroutines handle overlapping requests within one worker: they share session state and can expose one user's data to another request." -msgstr "" +msgstr "Evite as sessões nativas do PHP, incluindo `Yiisoft\\Session\\Session`, quando corrotinas do Swoole atendem requisições simultâneas dentro de um mesmo worker: elas compartilham o estado da sessão e podem expor os dados de um usuário a outra requisição." #. type: Plain text #: ../src/guide/tutorial/using-yii-with-swoole.md msgid "For requests handled one at a time, close the session and reset services between requests. `yiisoft/session` prevents stale session ID reuse, but does not isolate overlapping coroutines." -msgstr "" +msgstr "Para requisições atendidas uma por vez, feche a sessão e redefina os serviços entre as requisições. O `yiisoft/session` impede o reuso de IDs de sessão antigos, mas não isola corrotinas simultâneas." #. type: Plain text #: ../src/guide/tutorial/using-yii-with-swoole.md msgid "For authentication, consider tokens such as [JWT](https://jwt.io/introduction) instead of native sessions, especially for APIs. If you need session features, use an implementation that isolates each coroutine's session data; changing the native storage handler to Redis is not enough." -msgstr "" +msgstr "Para autenticação, considere tokens como [JWT](https://jwt.io/introduction) em vez de sessões nativas, principalmente em APIs. Se você precisa de recursos de sessão, use uma implementação que isole os dados de sessão de cada corrotina; trocar o handler de armazenamento nativo para Redis não basta." #. type: Plain text #: ../src/guide/tutorial/using-yii-with-swoole.md msgid "See the [Swoole guidance](https://github.com/swoole/swoole-src/issues/4478#issuecomment-962840796) and [Yii session discussion](https://github.com/yiisoft/session/issues/25)." -msgstr "" +msgstr "Veja as [orientações do Swoole](https://github.com/swoole/swoole-src/issues/4478#issuecomment-962840796) e a [discussão sobre sessões no Yii](https://github.com/yiisoft/session/issues/25)." diff --git a/_translations/po/pt-BR/guide_views_asset.md.po b/_translations/po/pt-BR/guide_views_asset.md.po index d4fc1fc1..e4d8cceb 100644 --- a/_translations/po/pt-BR/guide_views_asset.md.po +++ b/_translations/po/pt-BR/guide_views_asset.md.po @@ -8,104 +8,96 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-05-05 22:01+0000\n" "PO-Revision-Date: 2026-05-05 22:01+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md -#: ../src/guide/views/asset.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md ../src/guide/views/asset.md #, no-wrap msgid "Troubleshooting" -msgstr "" +msgstr "Solução de problemas" #. type: Title ## -#: ../src/cookbook/making-http-requests.md -#: ../src/cookbook/sentry-integration.md -#: ../src/guide/tutorial/using-yii-with-frankenphp.md -#: ../src/guide/tutorial/using-yii-with-roadrunner.md -#: ../src/guide/tutorial/using-yii-with-swoole.md ../src/guide/views/asset.md -#: ../src/guide/views/view.md ../src/guide/views/widget.md +#: ../src/cookbook/making-http-requests.md ../src/cookbook/sentry-integration.md ../src/guide/tutorial/using-yii-with-frankenphp.md ../src/guide/tutorial/using-yii-with-roadrunner.md ../src/guide/tutorial/using-yii-with-swoole.md ../src/guide/views/asset.md ../src/guide/views/view.md ../src/guide/views/widget.md #, no-wrap msgid "Installation" -msgstr "" +msgstr "Instalação" #. type: Title # #: ../src/guide/views/asset.md #, no-wrap msgid "Assets" -msgstr "" +msgstr "Assets" #. type: Plain text #: ../src/guide/views/asset.md msgid "Asset management is crucial for modern web applications. Assets include CSS stylesheets, JavaScript files, images, fonts, and other static resources. Yii3 provides a comprehensive asset management system through the `yiisoft/assets` package that handles dependencies, optimization, and deployment of these resources." -msgstr "" +msgstr "O gerenciamento de assets é essencial em aplicações web modernas. Assets incluem folhas de estilo CSS, arquivos JavaScript, imagens, fontes e outros recursos estáticos. O Yii3 oferece um sistema completo de gerenciamento de assets por meio do pacote `yiisoft/assets`, que cuida das dependências, da otimização e da publicação desses recursos." #. type: Plain text #: ../src/guide/views/asset.md msgid "The asset management functionality is provided by the `yiisoft/assets` package:" -msgstr "" +msgstr "A funcionalidade de gerenciamento de assets vem do pacote `yiisoft/assets`:" #. type: Fenced code block (bash) #: ../src/guide/views/asset.md #, no-wrap msgid "composer require yiisoft/assets\n" -msgstr "" +msgstr "composer require yiisoft/assets\n" #. type: Plain text #: ../src/guide/views/asset.md msgid "This package is included by default in the `yiisoft/app` application template." -msgstr "" +msgstr "Esse pacote já vem incluído por padrão no template de aplicação `yiisoft/app`." #. type: Title ## -#: ../src/guide/views/asset.md ../src/guide/views/view.md -#: ../src/guide/views/widget.md +#: ../src/guide/views/asset.md ../src/guide/views/view.md ../src/guide/views/widget.md #, no-wrap msgid "Basic Concepts" -msgstr "" +msgstr "Conceitos básicos" #. type: Title ### #: ../src/guide/views/asset.md #, no-wrap msgid "Asset Bundles" -msgstr "" +msgstr "Asset bundles" #. type: Plain text #: ../src/guide/views/asset.md msgid "An asset bundle is a collection of related asset files (CSS, JavaScript, images) that are logically grouped together. Asset bundles can depend on other bundles, allowing for proper dependency management." -msgstr "" +msgstr "Um asset bundle é um conjunto de arquivos de asset relacionados (CSS, JavaScript, imagens) agrupados logicamente. Asset bundles podem depender de outros bundles, o que permite gerenciar as dependências corretamente." #. type: Title ### #: ../src/guide/views/asset.md #, no-wrap msgid "Asset Manager" -msgstr "" +msgstr "Asset Manager" #. type: Plain text #: ../src/guide/views/asset.md msgid "The Asset Manager is responsible for: - Resolving asset bundle dependencies - Publishing assets from protected directories to web-accessible locations - Combining and minifying assets (when configured) - Generating proper URLs for assets" -msgstr "" +msgstr "O Asset Manager é responsável por: - Resolver as dependências dos asset bundles - Publicar assets de diretórios protegidos em locais acessíveis pela web - Combinar e minificar assets (quando configurado) - Gerar as URLs corretas dos assets" #. type: Title ## #: ../src/guide/views/asset.md #, no-wrap msgid "Creating Asset Bundles" -msgstr "" +msgstr "Criando asset bundles" #. type: Title ### #: ../src/guide/views/asset.md #, no-wrap msgid "Basic Asset Bundle" -msgstr "" +msgstr "Asset bundle básico" #. type: Plain text #: ../src/guide/views/asset.md msgid "Here's a simple asset bundle definition:" -msgstr "" +msgstr "Esta é uma definição simples de asset bundle:" #. type: Fenced code block (php) #: ../src/guide/views/asset.md @@ -140,12 +132,40 @@ msgid "" " ];\n" "}\n" msgstr "" +" 'print'],\n" +" ['css/admin/mobile.css', 'media' => 'screen and (max-width: 768px)'],\n" +" ];\n" +" \n" +" // Arquivos JavaScript com atributos\n" +" public array $js = [\n" +" 'js/admin/core.js',\n" +" ['js/admin/charts.js', 'defer' => true],\n" +" ['js/admin/analytics.js', 'async' => true],\n" +" ];\n" +" \n" +" // Opções globais para todos os arquivos JS deste bundle\n" +" public array $jsOptions = [\n" +" 'data-admin' => 'true',\n" +" ];\n" +" \n" +" // Opções globais para todos os arquivos CSS deste bundle\n" +" public array $cssOptions = [\n" +" 'data-bundle' => 'admin',\n" +" ];\n" +" \n" +" public array $depends = [\n" +" MainAsset::class,\n" +" ChartJsAsset::class,\n" +" ];\n" +"}\n" #. type: Title ## #: ../src/guide/views/asset.md #, no-wrap msgid "Using Asset Bundles" -msgstr "" +msgstr "Usando asset bundles" #. type: Title ### #: ../src/guide/views/asset.md #, no-wrap msgid "In Controllers" -msgstr "" +msgstr "Em controllers" #. type: Plain text #: ../src/guide/views/asset.md msgid "Register asset bundles in your controllers or views:" -msgstr "" +msgstr "Registre os asset bundles nos seus controllers ou views:" #. type: Fenced code block (php) #: ../src/guide/views/asset.md @@ -299,17 +374,56 @@ msgid "" " }\n" "}\n" msgstr "" +"assetManager->register(MainAsset::class);\n" +" \n" +" return $this->viewRenderer->render('index', [\n" +" 'title' => 'Home Page',\n" +" ]);\n" +" }\n" +" \n" +" public function admin(): ResponseInterface\n" +" {\n" +" // Registra vários asset bundles\n" +" $this->assetManager->registerMany([\n" +" MainAsset::class,\n" +" AdminAsset::class,\n" +" ]);\n" +" \n" +" return $this->viewRenderer->render('admin/dashboard');\n" +" }\n" +"}\n" #. type: Title ### #: ../src/guide/views/asset.md #, no-wrap msgid "In Views" -msgstr "" +msgstr "Em views" #. type: Plain text #: ../src/guide/views/asset.md msgid "You can also register assets directly in views:" -msgstr "" +msgstr "Você também pode registrar assets diretamente nas views:" #. type: Fenced code block (php) #: ../src/guide/views/asset.md @@ -337,17 +451,38 @@ msgid "" " \n" "\n" msgstr "" +"register(ProductAsset::class);\n" +"?>\n" +"\n" +"
\n" +"

\n" +" \n" +"
\n" #. type: Title ### #: ../src/guide/views/asset.md #, no-wrap msgid "With WebView Integration" -msgstr "" +msgstr "Com integração à WebView" #. type: Plain text #: ../src/guide/views/asset.md msgid "The recommended approach is to integrate with WebView for automatic asset rendering:" -msgstr "" +msgstr "A abordagem recomendada é integrar com a WebView para que os assets sejam renderizados automaticamente:" #. type: Fenced code block (php) #: ../src/guide/views/asset.md @@ -379,23 +514,48 @@ msgid "" " \n" "\n" msgstr "" +"register(MainAsset::class);\n" +"\n" +"// Adiciona todos os assets registrados à view\n" +"$this->addCssFiles($assetManager->getCssFiles());\n" +"$this->addCssStrings($assetManager->getCssStrings());\n" +"$this->addJsFiles($assetManager->getJsFiles());\n" +"$this->addJsStrings($assetManager->getJsStrings());\n" +"$this->addJsVars($assetManager->getJsVars());\n" +"?>\n" +"\n" +"
\n" +" \n" +"
\n" #. type: Title ## #: ../src/guide/views/asset.md #, no-wrap msgid "Asset Publishing" -msgstr "" +msgstr "Publicação de assets" #. type: Title ### #: ../src/guide/views/asset.md #, no-wrap msgid "Source Path Publishing" -msgstr "" +msgstr "Publicação a partir do source path" #. type: Plain text #: ../src/guide/views/asset.md msgid "When assets are located in non-web-accessible directories (like vendor packages), they need to be published:" -msgstr "" +msgstr "Quando os assets ficam em diretórios não acessíveis pela web (como pacotes do vendor), eles precisam ser publicados:" #. type: Fenced code block (php) #: ../src/guide/views/asset.md @@ -427,17 +587,42 @@ msgid "" " ];\n" "}\n" msgstr "" +"getPublishedUrl('@vendor/company/package/assets');\n" msgstr "" +"/**\n" +" * @var \\Yiisoft\\Assets\\AssetManager $assetManager\n" +" */\n" +"\n" +"// Publica um diretório\n" +"$publishedPath = $assetManager->publish('@vendor/company/package/assets');\n" +"\n" +"// Obtém a URL publicada\n" +"$publishedUrl = $assetManager->getPublishedUrl('@vendor/company/package/assets');\n" #. type: Title ## #: ../src/guide/views/asset.md #, no-wrap msgid "Third-party Library Assets" -msgstr "" +msgstr "Assets de bibliotecas de terceiros" #. type: Title ### #: ../src/guide/views/asset.md #, no-wrap msgid "jQuery Asset Bundle" -msgstr "" +msgstr "Asset bundle do jQuery" #. type: Fenced code block (php) #: ../src/guide/views/asset.md @@ -488,12 +682,29 @@ msgid "" " ];\n" "}\n" msgstr "" +" 'sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3',\n" +" 'crossorigin' => 'anonymous',\n" +" ];\n" +"\n" +" public array $js = [\n" +" 'https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js',\n" +" ];\n" +"\n" +" public array $jsOptions = [\n" +" 'integrity' => 'sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p',\n" +" 'crossorigin' => 'anonymous',\n" +" ];\n" +"}\n" #. type: Title ## #: ../src/guide/views/asset.md #, no-wrap msgid "Asset Configuration" -msgstr "" +msgstr "Configuração de assets" #. type: Title ### #: ../src/guide/views/asset.md #, no-wrap msgid "Application Configuration" -msgstr "" +msgstr "Configuração da aplicação" #. type: Plain text #: ../src/guide/views/asset.md msgid "Configure asset management in your application configuration:" -msgstr "" +msgstr "Configure o gerenciamento de assets na configuração da sua aplicação:" #. type: Plain text #: ../src/guide/views/asset.md #, no-wrap msgid "**config/web/params.php**\n" -msgstr "" +msgstr "**config/web/params.php**\n" #. type: Fenced code block (php) #: ../src/guide/views/asset.md @@ -623,17 +889,34 @@ msgid "" " ],\n" "];\n" msgstr "" +"return [\n" +" 'yiisoft/assets' => [\n" +" // Caminho base dos assets publicados\n" +" 'basePath' => '@webroot/assets',\n" +" \n" +" // URL base dos assets\n" +" 'baseUrl' => '@web/assets',\n" +" \n" +" // Configuração do conversor de assets\n" +" 'converter' => [\n" +" 'commands' => [\n" +" 'scss' => ['sass', '{from}', '{to}', '--style=compressed'],\n" +" 'ts' => ['tsc', '{from}', '--outFile', '{to}'],\n" +" ],\n" +" ],\n" +" ],\n" +"];\n" #. type: Title ### #: ../src/guide/views/asset.md #, no-wrap msgid "Environment-specific Assets" -msgstr "" +msgstr "Assets por ambiente" #. type: Plain text #: ../src/guide/views/asset.md msgid "Configure different assets for different environments:" -msgstr "" +msgstr "Configure assets diferentes para cada ambiente:" #. type: Fenced code block (php) #: ../src/guide/views/asset.md @@ -669,23 +952,52 @@ msgid "" " }\n" "}\n" msgstr "" +"css = ['css/main.css', 'css/debug.css'];\n" +" $this->js = ['js/main.js', 'js/debug.js'];\n" +" } else {\n" +" // Assets de produção (minificados)\n" +" $this->css = ['css/main.min.css'];\n" +" $this->js = ['js/main.min.js'];\n" +" }\n" +" }\n" +"}\n" #. type: Title ## #: ../src/guide/views/asset.md #, no-wrap msgid "Asset Optimization" -msgstr "" +msgstr "Otimização de assets" #. type: Title ### #: ../src/guide/views/asset.md #, no-wrap msgid "Asset Combination" -msgstr "" +msgstr "Combinação de assets" #. type: Plain text #: ../src/guide/views/asset.md msgid "Combine multiple CSS or JavaScript files into single files:" -msgstr "" +msgstr "Combine vários arquivos CSS ou JavaScript em arquivos únicos:" #. type: Fenced code block (php) #: ../src/guide/views/asset.md @@ -704,17 +1016,29 @@ msgid "" " 'js' => true, // Combine JavaScript files\n" "]);\n" msgstr "" +"/**\n" +" * @var \\Yiisoft\\Assets\\AssetManager $assetManager\n" +" */\n" +"\n" +"// Habilita a combinação de assets\n" +"$assetManager->setCombine(true);\n" +"\n" +"// Define as opções de combinação\n" +"$assetManager->setCombineOptions([\n" +" 'css' => true, // Combina os arquivos CSS\n" +" 'js' => true, // Combina os arquivos JavaScript\n" +"]);\n" #. type: Title ### #: ../src/guide/views/asset.md #, no-wrap msgid "Asset Compression" -msgstr "" +msgstr "Compressão de assets" #. type: Plain text #: ../src/guide/views/asset.md msgid "Configure asset compression for production:" -msgstr "" +msgstr "Configure a compressão de assets para produção:" #. type: Fenced code block (php) #: ../src/guide/views/asset.md @@ -728,18 +1052,25 @@ msgid "" " ],\n" "],\n" msgstr "" +"// Na configuração do seu asset manager\n" +"'converter' => [\n" +" 'commands' => [\n" +" 'css' => ['cleancss', '{from}', '-o', '{to}'],\n" +" 'js' => ['uglifyjs', '{from}', '-o', '{to}', '--compress', '--mangle'],\n" +" ],\n" +"],\n" #. type: Title ## #: ../src/guide/views/asset.md #, no-wrap msgid "Working with Asset Converter" -msgstr "" +msgstr "Trabalhando com o conversor de assets" #. type: Title ### #: ../src/guide/views/asset.md #, no-wrap msgid "SCSS/SASS Compilation" -msgstr "" +msgstr "Compilação de SCSS/SASS" #. type: Fenced code block (php) #: ../src/guide/views/asset.md @@ -765,12 +1096,31 @@ msgid "" " ];\n" "}\n" msgstr "" +" 'screen and (max-width: 768px)'],\n" +" ];\n" +" \n" +" public array $depends = [\n" +" AppAsset::class,\n" +" ];\n" +"}\n" #. type: Title ## -#: ../src/guide/views/asset.md ../src/guide/views/script-style-meta.md -#: ../src/guide/views/template-engines.md +#: ../src/guide/views/asset.md ../src/guide/views/script-style-meta.md ../src/guide/views/template-engines.md #, no-wrap msgid "Best Practices" -msgstr "" +msgstr "Boas práticas" #. type: Bullet: '1. ' #: ../src/guide/views/asset.md msgid "**Organize by functionality**: Group related assets into logical bundles" -msgstr "" +msgstr "**Organize por funcionalidade**: agrupe assets relacionados em bundles lógicos" #. type: Bullet: '2. ' #: ../src/guide/views/asset.md msgid "**Manage dependencies**: Properly declare dependencies between bundles" -msgstr "" +msgstr "**Gerencie as dependências**: declare corretamente as dependências entre bundles" #. type: Bullet: '3. ' #: ../src/guide/views/asset.md msgid "**Use meaningful names**: Name your asset bundles clearly" -msgstr "" +msgstr "**Use nomes significativos**: dê nomes claros aos seus asset bundles" #. type: Bullet: '4. ' #: ../src/guide/views/asset.md msgid "**Environment optimization**: Use minified assets in production" -msgstr "" +msgstr "**Otimize por ambiente**: use assets minificados em produção" #. type: Bullet: '5. ' #: ../src/guide/views/asset.md msgid "**CDN consideration**: Use CDN for popular libraries when appropriate" -msgstr "" +msgstr "**Considere uma CDN**: use CDN para bibliotecas populares quando fizer sentido" #. type: Bullet: '6. ' #: ../src/guide/views/asset.md msgid "**Version your assets**: Include version numbers in filenames for cache busting" -msgstr "" +msgstr "**Versione seus assets**: inclua números de versão nos nomes dos arquivos para invalidar o cache" #. type: Bullet: '7. ' #: ../src/guide/views/asset.md msgid "**Minimize HTTP requests**: Combine related assets when possible" -msgstr "" +msgstr "**Reduza as requisições HTTP**: combine assets relacionados quando possível" #. type: Bullet: '8. ' #: ../src/guide/views/asset.md msgid "**Optimize file sizes**: Compress and minify assets for production" -msgstr "" +msgstr "**Otimize o tamanho dos arquivos**: comprima e minifique os assets para produção" #. type: Title ### #: ../src/guide/views/asset.md #, no-wrap msgid "Common Issues" -msgstr "" +msgstr "Problemas comuns" #. type: Plain text #: ../src/guide/views/asset.md @@ -967,6 +1413,10 @@ msgid "" "- Verify `$basePath` and `$baseUrl` are configured correctly\n" "- Ensure assets are published if using `$sourcePath`\n" msgstr "" +"**Asset não encontrado:**\n" +"- Verifique se o arquivo de asset existe no caminho especificado\n" +"- Confira se `$basePath` e `$baseUrl` estão configurados corretamente\n" +"- Garanta que os assets foram publicados se você usa `$sourcePath`\n" #. type: Plain text #: ../src/guide/views/asset.md @@ -977,6 +1427,10 @@ msgid "" "- Check for circular dependencies\n" "- Ensure dependency bundles are correctly configured\n" msgstr "" +"**Dependências não carregam:**\n" +"- Confira se os bundles de dependência estão registrados corretamente\n" +"- Verifique se há dependências circulares\n" +"- Garanta que os bundles de dependência estão configurados corretamente\n" #. type: Plain text #: ../src/guide/views/asset.md @@ -986,6 +1440,9 @@ msgid "" "- Make sure you're calling `$this->addCssFiles()` and `$this->addJsFiles()` in your layout\n" "- Verify that `$this->head()`, `$this->beginBody()`, and `$this->endBody()` are called in the layout\n" msgstr "" +"**Assets não aparecem no HTML:**\n" +"- Verifique se você chama `$this->addCssFiles()` e `$this->addJsFiles()` no seu layout\n" +"- Confira se `$this->head()`, `$this->beginBody()` e `$this->endBody()` são chamados no layout\n" #. type: Plain text #: ../src/guide/views/asset.md @@ -995,3 +1452,6 @@ msgid "" "- Check that the web server has write permissions to the assets directory\n" "- Verify the published assets directory is web-accessible\n" msgstr "" +"**Problemas de permissão:**\n" +"- Verifique se o servidor web tem permissão de escrita no diretório de assets\n" +"- Confira se o diretório de assets publicados é acessível pela web\n" diff --git a/_translations/po/pt-BR/guide_views_script-style-meta.md.po b/_translations/po/pt-BR/guide_views_script-style-meta.md.po index f77827bf..665bdbab 100644 --- a/_translations/po/pt-BR/guide_views_script-style-meta.md.po +++ b/_translations/po/pt-BR/guide_views_script-style-meta.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2025-12-24 13:00+0000\n" "PO-Revision-Date: 2025-12-24 13:00+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,78 +19,77 @@ msgstr "" #: ../src/guide/structure/overview.md ../src/guide/views/script-style-meta.md #, no-wrap msgid "Overview" -msgstr "" +msgstr "Visão geral" #. type: Title ## #: ../src/guide/views/asset.md ../src/guide/views/script-style-meta.md #, no-wrap msgid "Practical Examples" -msgstr "" +msgstr "Exemplos práticos" #. type: Title ## -#: ../src/guide/views/asset.md ../src/guide/views/script-style-meta.md -#: ../src/guide/views/template-engines.md +#: ../src/guide/views/asset.md ../src/guide/views/script-style-meta.md ../src/guide/views/template-engines.md #, no-wrap msgid "Best Practices" -msgstr "" +msgstr "Boas práticas" #. type: Title # #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Scripts, styles and meta tags" -msgstr "" +msgstr "Scripts, estilos e meta tags" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "Modern web applications require careful management of CSS styles, JavaScript code, and HTML meta tags. Yii3 provides a comprehensive system for registering and organizing these resources through the `WebView` class, which is part of the `yiisoft/view` package." -msgstr "" +msgstr "Aplicações web modernas exigem um gerenciamento cuidadoso de estilos CSS, código JavaScript e meta tags HTML. O Yii3 oferece um sistema completo para registrar e organizar esses recursos por meio da classe `WebView`, que faz parte do pacote `yiisoft/view`." #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "The `WebView` class extends the basic `View` class with web-specific functionality, allowing you to:" -msgstr "" +msgstr "A classe `WebView` estende a classe básica `View` com funcionalidades específicas para a web, permitindo que você:" #. type: Bullet: '- ' #: ../src/guide/views/script-style-meta.md msgid "Register CSS files and inline styles" -msgstr "" +msgstr "Registre arquivos CSS e estilos inline" #. type: Bullet: '- ' #: ../src/guide/views/script-style-meta.md msgid "Register JavaScript files and inline scripts" -msgstr "" +msgstr "Registre arquivos JavaScript e scripts inline" #. type: Bullet: '- ' #: ../src/guide/views/script-style-meta.md msgid "Manage HTML meta tags and link tags" -msgstr "" +msgstr "Gerencie meta tags e link tags HTML" #. type: Bullet: '- ' #: ../src/guide/views/script-style-meta.md msgid "Control the position where resources are rendered" -msgstr "" +msgstr "Controle a posição em que os recursos são renderizados" #. type: Bullet: '- ' #: ../src/guide/views/script-style-meta.md msgid "Handle dependencies between resources" -msgstr "" +msgstr "Lide com dependências entre recursos" #. type: Title ## #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "CSS management" -msgstr "" +msgstr "Gerenciamento de CSS" #. type: Title ### #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Registering CSS Files" -msgstr "" +msgstr "Registrando arquivos CSS" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "You can register CSS files to be included in your HTML pages:" -msgstr "" +msgstr "Você pode registrar arquivos CSS para incluí-los nas suas páginas HTML:" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md @@ -117,17 +116,37 @@ msgid "" "// Register CSS file with custom key to avoid duplicates\n" "$this->registerCssFile('/css/theme.css', WebView::POSITION_HEAD, [], 'theme-css');\n" msgstr "" +"registerCssFile('/css/styles.css');\n" +"\n" +"// Registra um arquivo CSS com atributos\n" +"$this->registerCssFile('/css/print.css', WebView::POSITION_HEAD, [\n" +" 'media' => 'print',\n" +"]);\n" +"\n" +"// Registra um arquivo CSS com uma chave personalizada para evitar duplicatas\n" +"$this->registerCssFile('/css/theme.css', WebView::POSITION_HEAD, [], 'theme-css');\n" #. type: Title ### #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Registering Inline CSS" -msgstr "" +msgstr "Registrando CSS inline" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "For inline CSS styles, use the `registerCss()` method:" -msgstr "" +msgstr "Para estilos CSS inline, use o método `registerCss()`:" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md @@ -152,17 +171,35 @@ msgid "" " }\n" "', WebView::POSITION_HEAD, ['id' => 'print-styles']);\n" msgstr "" +"// Registra CSS inline\n" +"$this->registerCss('\n" +" .highlight {\n" +" background-color: yellow;\n" +" font-weight: bold;\n" +" }\n" +" .error {\n" +" color: red;\n" +" border: 1px solid red;\n" +" }\n" +"', WebView::POSITION_HEAD);\n" +"\n" +"// Com atributos personalizados\n" +"$this->registerCss('\n" +" @media print {\n" +" .no-print { display: none; }\n" +" }\n" +"', WebView::POSITION_HEAD, ['id' => 'print-styles']);\n" #. type: Title ### #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "CSS from Files" -msgstr "" +msgstr "CSS a partir de arquivos" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "You can also register CSS content from external files:" -msgstr "" +msgstr "Você também pode registrar o conteúdo CSS de arquivos externos:" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md @@ -173,17 +210,21 @@ msgid "" " 'id' => 'dynamic-styles',\n" "]);\n" msgstr "" +"// Lê o CSS de um arquivo e o registra como CSS inline\n" +"$this->registerCssFromFile('/path/to/dynamic-styles.css', WebView::POSITION_HEAD, [\n" +" 'id' => 'dynamic-styles',\n" +"]);\n" #. type: Title ### #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Using Style Tags" -msgstr "" +msgstr "Usando tags style" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "For more control, you can use HTML style tags directly:" -msgstr "" +msgstr "Para ter mais controle, você pode usar tags style do HTML diretamente:" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md @@ -202,23 +243,35 @@ msgid "" "\n" "$this->registerStyleTag($styleTag, WebView::POSITION_HEAD);\n" msgstr "" +"use Yiisoft\\Html\\Html;\n" +"\n" +"$styleTag = Html::style('\n" +" .custom-button {\n" +" background: linear-gradient(45deg, #blue, #purple);\n" +" border: none;\n" +" color: white;\n" +" padding: 10px 20px;\n" +" }\n" +"', ['id' => 'custom-button-styles']);\n" +"\n" +"$this->registerStyleTag($styleTag, WebView::POSITION_HEAD);\n" #. type: Title ## #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "JavaScript management" -msgstr "" +msgstr "Gerenciamento de JavaScript" #. type: Title ### #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Registering JavaScript Files" -msgstr "" +msgstr "Registrando arquivos JavaScript" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "Include external JavaScript files using `registerJsFile()`:" -msgstr "" +msgstr "Inclua arquivos JavaScript externos com `registerJsFile()`:" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md @@ -241,17 +294,33 @@ msgid "" "$this->registerJsFile('https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js', \n" " WebView::POSITION_END, [], 'jquery');\n" msgstr "" +"// Registra um arquivo JavaScript\n" +"$this->registerJsFile('/js/main.js');\n" +"\n" +"// Registra com atributos (carregamento assíncrono)\n" +"$this->registerJsFile('/js/analytics.js', WebView::POSITION_END, [\n" +" 'async' => true,\n" +"]);\n" +"\n" +"// Registra com o atributo defer\n" +"$this->registerJsFile('/js/interactive.js', WebView::POSITION_END, [\n" +" 'defer' => true,\n" +"]);\n" +"\n" +"// Registra a partir de uma CDN\n" +"$this->registerJsFile('https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js', \n" +" WebView::POSITION_END, [], 'jquery');\n" #. type: Title ### #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Registering Inline JavaScript" -msgstr "" +msgstr "Registrando JavaScript inline" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "Add inline JavaScript code with `registerJs()`:" -msgstr "" +msgstr "Adicione código JavaScript inline com `registerJs()`:" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md @@ -272,17 +341,31 @@ msgid "" " }\n" "', WebView::POSITION_READY);\n" msgstr "" +"// Registra JavaScript inline\n" +"$this->registerJs('\n" +" document.addEventListener(\"DOMContentLoaded\", function() {\n" +" console.log(\"Page loaded!\");\n" +" initializeComponents();\n" +" });\n" +"', WebView::POSITION_END);\n" +"\n" +"// Registra JavaScript que deve rodar quando o DOM estiver pronto\n" +"$this->registerJs('\n" +" function showAlert(message) {\n" +" alert(message);\n" +" }\n" +"', WebView::POSITION_READY);\n" #. type: Title ### #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "JavaScript Variables" -msgstr "" +msgstr "Variáveis JavaScript" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "Pass PHP data to JavaScript using `registerJsVar()`:" -msgstr "" +msgstr "Passe dados do PHP para o JavaScript com `registerJsVar()`:" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md @@ -300,11 +383,22 @@ msgid "" " 'locale' => $this->getLocale(),\n" "]);\n" msgstr "" +"// Registra variáveis JavaScript\n" +"$this->registerJsVar('apiUrl', 'https://api.example.com');\n" +"$this->registerJsVar('currentUser', [\n" +" 'id' => $user->getId(),\n" +" 'name' => $user->getName(),\n" +" 'isAdmin' => $user->isAdmin(),\n" +"]);\n" +"$this->registerJsVar('config', [\n" +" 'debug' => $this->isDebugMode(),\n" +" 'locale' => $this->getLocale(),\n" +"]);\n" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "This generates JavaScript code like:" -msgstr "" +msgstr "Isso gera um código JavaScript como este:" #. type: Fenced code block (html) #: ../src/guide/views/script-style-meta.md @@ -316,17 +410,22 @@ msgid "" "var config = {\"debug\":true,\"locale\":\"en-US\"};\n" "\n" msgstr "" +"\n" #. type: Title ### #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Using Script Tags" -msgstr "" +msgstr "Usando tags script" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "For more control over script tags:" -msgstr "" +msgstr "Para ter mais controle sobre as tags script:" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md @@ -344,17 +443,28 @@ msgid "" "\n" "$this->registerScriptTag($scriptTag, WebView::POSITION_END);\n" msgstr "" +"use Yiisoft\\Html\\Html;\n" +"\n" +"$scriptTag = Html::script('\n" +" window.myApp = {\n" +" init: function() {\n" +" console.log(\"App initialized\");\n" +" }\n" +" };\n" +"', ['type' => 'module']);\n" +"\n" +"$this->registerScriptTag($scriptTag, WebView::POSITION_END);\n" #. type: Title ## #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Position Constants" -msgstr "" +msgstr "Constantes de posição" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "Resources can be positioned at different locations in the HTML document:" -msgstr "" +msgstr "Os recursos podem ser posicionados em diferentes pontos do documento HTML:" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md @@ -377,11 +487,27 @@ msgid "" "// When page is fully loaded (window.onload equivalent)\n" "WebView::POSITION_LOAD\n" msgstr "" +"use Yiisoft\\View\\WebView;\n" +"\n" +"// Na seção \n" +"WebView::POSITION_HEAD\n" +"\n" +"// No início do \n" +"WebView::POSITION_BEGIN \n" +"\n" +"// No fim do (antes de )\n" +"WebView::POSITION_END\n" +"\n" +"// Quando o DOM estiver pronto (equivalente ao document.ready do jQuery)\n" +"WebView::POSITION_READY\n" +"\n" +"// Quando a página terminar de carregar (equivalente ao window.onload)\n" +"WebView::POSITION_LOAD\n" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "Example layout showing where each position is rendered:" -msgstr "" +msgstr "Exemplo de layout mostrando onde cada posição é renderizada:" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md @@ -416,23 +542,51 @@ msgid "" "\n" "endPage() ?>\n" msgstr "" +"\n" +"beginPage() ?>\n" +"\n" +"\n" +"\n" +" \n" +" head() ?>\n" +"\n" +"\n" +" \n" +" beginBody() ?>\n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" endBody() ?>\n" +"\n" +"\n" +"endPage() ?>\n" #. type: Title ## #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Meta tags" -msgstr "" +msgstr "Meta tags" #. type: Title ### #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Basic Meta Tags" -msgstr "" +msgstr "Meta tags básicas" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "Register meta tags for SEO and page information:" -msgstr "" +msgstr "Registre meta tags para SEO e informações da página:" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md @@ -452,17 +606,30 @@ msgid "" "$this->registerMeta(['property' => 'og:description', 'content' => 'Page description']);\n" "$this->registerMeta(['property' => 'og:image', 'content' => 'https://example.com/image.jpg']);\n" msgstr "" +"// Registra meta tags usando a sintaxe de array\n" +"$this->registerMeta(['name' => 'description', 'content' => 'Page description']);\n" +"$this->registerMeta(['name' => 'keywords', 'content' => 'yii, php, framework']);\n" +"$this->registerMeta(['name' => 'author', 'content' => 'John Doe']);\n" +"$this->registerMeta(['name' => 'robots', 'content' => 'index, follow']);\n" +"\n" +"// Viewport para design responsivo\n" +"$this->registerMeta(['name' => 'viewport', 'content' => 'width=device-width, initial-scale=1']);\n" +"\n" +"// Tags Open Graph para redes sociais\n" +"$this->registerMeta(['property' => 'og:title', 'content' => 'Page Title']);\n" +"$this->registerMeta(['property' => 'og:description', 'content' => 'Page description']);\n" +"$this->registerMeta(['property' => 'og:image', 'content' => 'https://example.com/image.jpg']);\n" #. type: Title ### #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Using Meta Tag Objects" -msgstr "" +msgstr "Usando objetos de meta tag" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "For more control, use the `Html::meta()` helper:" -msgstr "" +msgstr "Para ter mais controle, use o helper `Html::meta()`:" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md @@ -483,17 +650,31 @@ msgid "" " ->content('300') // Refresh every 5 minutes\n" ");\n" msgstr "" +"use Yiisoft\\Html\\Html;\n" +"\n" +"// Cria meta tags com o helper Html\n" +"$this->registerMetaTag(\n" +" Html::meta()\n" +" ->name('description')\n" +" ->content('This is a comprehensive guide to Yii3 views')\n" +");\n" +"\n" +"$this->registerMetaTag(\n" +" Html::meta()\n" +" ->httpEquiv('refresh')\n" +" ->content('300') // Atualiza a cada 5 minutos\n" +");\n" #. type: Title ### #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Preventing Duplicate Meta Tags" -msgstr "" +msgstr "Evitando meta tags duplicadas" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "Use keys to prevent duplicate meta tags:" -msgstr "" +msgstr "Use chaves para evitar meta tags duplicadas:" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md @@ -511,23 +692,34 @@ msgid "" " 'content' => 'Updated description'\n" "], 'description');\n" msgstr "" +"// Primeiro registro\n" +"$this->registerMeta([\n" +" 'name' => 'description',\n" +" 'content' => 'Original description'\n" +"], 'description');\n" +"\n" +"// Este sobrescreve o anterior\n" +"$this->registerMeta([\n" +" 'name' => 'description', \n" +" 'content' => 'Updated description'\n" +"], 'description');\n" #. type: Title ## #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Link tags" -msgstr "" +msgstr "Link tags" #. type: Title ### #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Basic Link Tags" -msgstr "" +msgstr "Link tags básicas" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "Register various types of link tags:" -msgstr "" +msgstr "Registre vários tipos de link tags:" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md @@ -563,12 +755,41 @@ msgid "" " 'crossorigin' => 'anonymous',\n" "]);\n" msgstr "" +"// Favicon\n" +"$this->registerLink([\n" +" 'rel' => 'icon',\n" +" 'type' => 'image/png',\n" +" 'href' => '/favicon.png',\n" +"]);\n" +"\n" +"// Feed RSS\n" +"$this->registerLink([\n" +" 'rel' => 'alternate',\n" +" 'type' => 'application/rss+xml',\n" +" 'title' => 'RSS Feed',\n" +" 'href' => '/feed.rss',\n" +"]);\n" +"\n" +"// URL canônica\n" +"$this->registerLink([\n" +" 'rel' => 'canonical',\n" +" 'href' => 'https://example.com/canonical-url',\n" +"]);\n" +"\n" +"// Pré-carregamento de recursos\n" +"$this->registerLink([\n" +" 'rel' => 'preload',\n" +" 'href' => '/fonts/main.woff2',\n" +" 'as' => 'font',\n" +" 'type' => 'font/woff2',\n" +" 'crossorigin' => 'anonymous',\n" +"]);\n" #. type: Title ### #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Using Link Tag Objects" -msgstr "" +msgstr "Usando objetos de link tag" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md @@ -590,17 +811,32 @@ msgid "" " ])\n" ");\n" msgstr "" +"use Yiisoft\\Html\\Html;\n" +"\n" +"// Folha de estilo CSS\n" +"$this->registerLinkTag(\n" +" Html::link('/css/main.css', [\n" +" 'rel' => 'stylesheet',\n" +" ])\n" +");\n" +"\n" +"// Prefetch de DNS\n" +"$this->registerLinkTag(\n" +" Html::link('https://fonts.googleapis.com', [\n" +" 'rel' => 'dns-prefetch',\n" +" ])\n" +");\n" #. type: Title ### #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Complete Page Setup" -msgstr "" +msgstr "Configuração completa de uma página" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "Here's how you might set up a complete page with all types of resources:" -msgstr "" +msgstr "Veja como montar uma página completa com todos os tipos de recursos:" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md @@ -668,17 +904,78 @@ msgid "" " \n" "\n" msgstr "" +"setTitle($title);\n" +"\n" +"// Meta tags\n" +"$this->registerMeta(['name' => 'description', 'content' => $description]);\n" +"$this->registerMeta(['name' => 'keywords', 'content' => 'ecommerce, products, online shop']);\n" +"\n" +"// Tags Open Graph\n" +"$this->registerMeta(['property' => 'og:title', 'content' => $title]);\n" +"$this->registerMeta(['property' => 'og:description', 'content' => $description]);\n" +"$this->registerMeta(['property' => 'og:image', 'content' => $product['image']]);\n" +"\n" +"// Arquivos CSS\n" +"$this->registerCssFile('/css/product.css');\n" +"$this->registerCssFile('/css/responsive.css', WebView::POSITION_HEAD, [\n" +" 'media' => 'screen and (max-width: 768px)',\n" +"]);\n" +"\n" +"// Arquivos JavaScript\n" +"$this->registerJsFile('/js/product-gallery.js', WebView::POSITION_END);\n" +"$this->registerJsFile('/js/shopping-cart.js', WebView::POSITION_END);\n" +"\n" +"// Variáveis JavaScript\n" +"$this->registerJsVar('productData', $product);\n" +"$this->registerJsVar('cartApiUrl', '/api/cart');\n" +"\n" +"// JavaScript inline\n" +"$this->registerJs('\n" +" document.addEventListener(\"DOMContentLoaded\", function() {\n" +" initProductGallery();\n" +" initShoppingCart();\n" +" });\n" +"', WebView::POSITION_END);\n" +"\n" +"// Estilos específicos da página\n" +"$this->registerCss('\n" +" .product-special {\n" +" background: linear-gradient(45deg, #ff6b6b, #4ecdc4);\n" +" padding: 20px;\n" +" border-radius: 10px;\n" +" }\n" +"', WebView::POSITION_HEAD);\n" +"?>\n" +"\n" +"
\n" +" \n" +"
\n" #. type: Title ### #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Conditional Resource Loading" -msgstr "" +msgstr "Carregamento condicional de recursos" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "Load resources based on conditions:" -msgstr "" +msgstr "Carregue recursos de acordo com condições:" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md @@ -716,57 +1013,88 @@ msgid "" "]);\n" "?>\n" msgstr "" +"registerCssFile('/css/dark-theme.css');\n" +"} else {\n" +" $this->registerCssFile('/css/light-theme.css');\n" +"}\n" +"\n" +"// Recursos específicos da área admin\n" +"if ($isAdmin) {\n" +" $this->registerCssFile('/css/admin-toolbar.css');\n" +" $this->registerJsFile('/js/admin-functions.js');\n" +"}\n" +"\n" +"// Configuração JavaScript baseada no papel do usuário\n" +"$this->registerJsVar('userPermissions', [\n" +" 'canEdit' => in_array($userRole, ['admin', 'editor']),\n" +" 'canDelete' => $userRole === 'admin',\n" +" 'canPublish' => in_array($userRole, ['admin', 'publisher']),\n" +"]);\n" +"?>\n" #. type: Bullet: '1. ' #: ../src/guide/views/script-style-meta.md msgid "**Use appropriate positions**: Place CSS in `POSITION_HEAD`, JavaScript at `POSITION_END`" -msgstr "" +msgstr "**Use as posições adequadas**: coloque o CSS em `POSITION_HEAD` e o JavaScript em `POSITION_END`" #. type: Bullet: '2. ' #: ../src/guide/views/script-style-meta.md msgid "**Minimize inline resources**: Prefer external files for better caching" -msgstr "" +msgstr "**Reduza os recursos inline**: prefira arquivos externos, que aproveitam melhor o cache" #. type: Bullet: '3. ' #: ../src/guide/views/script-style-meta.md msgid "**Use keys for duplicates**: Prevent duplicate resources with meaningful keys" -msgstr "" +msgstr "**Use chaves contra duplicatas**: evite recursos duplicados com chaves significativas" #. type: Bullet: '4. ' #: ../src/guide/views/script-style-meta.md msgid "**Optimize loading**: Use `async` and `defer` attributes for non-critical JavaScript" -msgstr "" +msgstr "**Otimize o carregamento**: use os atributos `async` e `defer` para JavaScript não crítico" #. type: Bullet: '5. ' #: ../src/guide/views/script-style-meta.md msgid "**Group related resources**: Keep related CSS and JS files together" -msgstr "" +msgstr "**Agrupe recursos relacionados**: mantenha juntos os arquivos CSS e JS relacionados" #. type: Bullet: '6. ' #: ../src/guide/views/script-style-meta.md msgid "**Use CDNs wisely**: Balance performance with reliability" -msgstr "" +msgstr "**Use CDNs com critério**: equilibre desempenho e confiabilidade" #. type: Bullet: '7. ' #: ../src/guide/views/script-style-meta.md msgid "**Validate meta tags**: Ensure proper SEO meta tags are set" -msgstr "" +msgstr "**Valide as meta tags**: garanta que as meta tags de SEO estejam definidas corretamente" #. type: Bullet: '8. ' #: ../src/guide/views/script-style-meta.md msgid "**Consider security**: Be careful with inline scripts and CSP policies" -msgstr "" +msgstr "**Pense na segurança**: tenha cuidado com scripts inline e políticas de CSP" #. type: Title ## #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Working with Asset Bundles" -msgstr "" +msgstr "Trabalhando com asset bundles" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "For more complex asset management, consider using asset bundles:" -msgstr "" +msgstr "Para um gerenciamento de assets mais complexo, considere usar asset bundles:" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md @@ -781,3 +1109,11 @@ msgid "" "// Add all JavaScript files from the bundle \n" "$this->addJsFiles($this->assetManager->getJsFiles());\n" msgstr "" +"// Registra um asset bundle (explicado em detalhes no guia de Assets)\n" +"$assetBundle = $this->assetManager->register(MainAsset::class);\n" +"\n" +"// Adiciona todos os arquivos CSS do bundle\n" +"$this->addCssFiles($this->assetManager->getCssFiles());\n" +"\n" +"// Adiciona todos os arquivos JavaScript do bundle \n" +"$this->addJsFiles($this->assetManager->getJsFiles());\n" diff --git a/_translations/po/pt-BR/guide_views_template-engines.md.po b/_translations/po/pt-BR/guide_views_template-engines.md.po index 9df94dc9..cd505f78 100644 --- a/_translations/po/pt-BR/guide_views_template-engines.md.po +++ b/_translations/po/pt-BR/guide_views_template-engines.md.po @@ -8,57 +8,56 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-01-26 18:48+0000\n" "PO-Revision-Date: 2026-01-26 18:48+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/guide/views/asset.md ../src/guide/views/script-style-meta.md -#: ../src/guide/views/template-engines.md +#: ../src/guide/views/asset.md ../src/guide/views/script-style-meta.md ../src/guide/views/template-engines.md #, no-wrap msgid "Best Practices" -msgstr "" +msgstr "Boas práticas" #. type: Title # #: ../src/guide/views/template-engines.md #, no-wrap msgid "Template engines" -msgstr "" +msgstr "Template engines" #. type: Plain text #: ../src/guide/views/template-engines.md msgid "Yii3 supports multiple template engines through a flexible renderer system. By default, PHP is used as the template engine, but you can easily add support for other engines like Twig and [Blade](https://github.com/lee-to/yii-blade), or create your own custom renderers." -msgstr "" +msgstr "O Yii3 suporta várias template engines por meio de um sistema flexível de renderers. Por padrão, o PHP é usado como template engine, mas você pode adicionar suporte a outras engines como Twig e [Blade](https://github.com/lee-to/yii-blade), ou criar seus próprios renderers." #. type: Plain text #: ../src/guide/views/template-engines.md msgid "PHP templates were described in the \"[View](view.md)\" guide section." -msgstr "" +msgstr "Os templates PHP foram descritos na seção \"[View](view.md)\" do guia." #. type: Title ## #: ../src/guide/views/template-engines.md #, no-wrap msgid "Twig Template Engine" -msgstr "" +msgstr "Template engine Twig" #. type: Plain text #: ../src/guide/views/template-engines.md msgid "Twig is a modern template engine that provides a more designer-friendly syntax. To use Twig in your Yii3 application, you need to install the Twig extension." -msgstr "" +msgstr "O Twig é uma template engine moderna, com uma sintaxe mais amigável para designers. Para usar o Twig na sua aplicação Yii3, instale a extensão do Twig." #. type: Fenced code block (bash) #: ../src/guide/views/template-engines.md #, no-wrap msgid "composer require yiisoft/view-twig\n" -msgstr "" +msgstr "composer require yiisoft/view-twig\n" #. type: Plain text #: ../src/guide/views/template-engines.md msgid "Now you can use `.twig` templates. For example, `views/site/about.twig`:" -msgstr "" +msgstr "Agora você pode usar templates `.twig`. Por exemplo, `views/site/about.twig`:" #. type: Fenced code block (twig) #: ../src/guide/views/template-engines.md @@ -88,18 +87,41 @@ msgid "" " {% endif %}\n" "\n" msgstr "" +"{# Dicas de tipo das variáveis para suporte na IDE #}\n" +"{# @var user \\App\\Entity\\User #}\n" +"{# @var posts \\App\\Entity\\Post[] #}\n" +"\n" +"
\n" +"

{{ user.name }}

\n" +"

Email: {{ user.email }}

\n" +" \n" +" {% if posts is not empty %}\n" +"

Recent Posts

\n" +"
    \n" +" {% for post in posts %}\n" +"
  • \n" +"

    {{ post.title }}

    \n" +"

    {{ post.excerpt }}

    \n" +" \n" +"
  • \n" +" {% endfor %}\n" +"
\n" +" {% else %}\n" +"

No posts available.

\n" +" {% endif %}\n" +"
\n" #. type: Title ### #: ../src/guide/views/template-engines.md #, no-wrap msgid "Twig Features" -msgstr "" +msgstr "Recursos do Twig" #. type: Plain text #: ../src/guide/views/template-engines.md #, no-wrap msgid "**Automatic Escaping**: Twig automatically escapes variables for HTML context:\n" -msgstr "" +msgstr "**Escape automático**: o Twig escapa as variáveis automaticamente para o contexto HTML:\n" #. type: Fenced code block (twig) #: ../src/guide/views/template-engines.md @@ -111,12 +133,17 @@ msgid "" "{# Raw output (use carefully) #}\n" "
{{ content|raw }}
\n" msgstr "" +"{# Escapado automaticamente #}\n" +"

{{ title }}

\n" +"\n" +"{# Saída bruta (use com cuidado) #}\n" +"
{{ content|raw }}
\n" #. type: Plain text #: ../src/guide/views/template-engines.md #, no-wrap msgid "**Filters and Functions**: Twig provides many built-in filters and functions:\n" -msgstr "" +msgstr "**Filtros e funções**: o Twig oferece muitos filtros e funções nativos:\n" #. type: Fenced code block (twig) #: ../src/guide/views/template-engines.md @@ -131,18 +158,26 @@ msgid "" "{# URL generation #}\n" "Profile\n" msgstr "" +"{# Formatação de data #}\n" +"\n" +"\n" +"{# Manipulação de strings #}\n" +"

{{ description|truncate(100) }}

\n" +"\n" +"{# Geração de URLs #}\n" +"Profile\n" #. type: Plain text #: ../src/guide/views/template-engines.md #, no-wrap msgid "**Template Inheritance**: Twig supports template inheritance:\n" -msgstr "" +msgstr "**Herança de templates**: o Twig suporta herança de templates:\n" #. type: Plain text #: ../src/guide/views/template-engines.md #, no-wrap msgid "**views/layout/main.twig**\n" -msgstr "" +msgstr "**views/layout/main.twig**\n" #. type: Fenced code block (twig) #: ../src/guide/views/template-engines.md @@ -160,12 +195,23 @@ msgid "" "\n" "\n" msgstr "" +"\n" +"\n" +"\n" +" {% block title %}Default Title{% endblock %}\n" +"\n" +"\n" +"
\n" +" {% block content %}{% endblock %}\n" +"
\n" +"\n" +"\n" #. type: Plain text #: ../src/guide/views/template-engines.md #, no-wrap msgid "**views/site/about.twig**\n" -msgstr "" +msgstr "**views/site/about.twig**\n" #. type: Fenced code block (twig) #: ../src/guide/views/template-engines.md @@ -180,17 +226,25 @@ msgid "" "

Welcome to our website!

\n" "{% endblock %}\n" msgstr "" +"{% extends \"layout/main.twig\" %}\n" +"\n" +"{% block title %}About Us{% endblock %}\n" +"\n" +"{% block content %}\n" +"

About Our Company

\n" +"

Welcome to our website!

\n" +"{% endblock %}\n" #. type: Title ### #: ../src/guide/views/template-engines.md #, no-wrap msgid "Rendering Twig Templates" -msgstr "" +msgstr "Renderizando templates Twig" #. type: Plain text #: ../src/guide/views/template-engines.md msgid "Use Twig templates the same way as PHP templates:" -msgstr "" +msgstr "Use templates Twig da mesma forma que templates PHP:" #. type: Fenced code block (php) #: ../src/guide/views/template-engines.md @@ -205,17 +259,25 @@ msgid "" " ]);\n" "}\n" msgstr "" +"// No seu controller\n" +"public function about(): ResponseInterface\n" +"{\n" +" return $this->viewRenderer->render('about.twig', [\n" +" 'user' => $this->getCurrentUser(),\n" +" 'posts' => $this->getRecentPosts(),\n" +" ]);\n" +"}\n" #. type: Title ## #: ../src/guide/views/template-engines.md #, no-wrap msgid "Custom Template Engines" -msgstr "" +msgstr "Template engines personalizadas" #. type: Plain text #: ../src/guide/views/template-engines.md msgid "You can create custom template engines by implementing the `TemplateRendererInterface`:" -msgstr "" +msgstr "Você pode criar template engines personalizadas implementando a `TemplateRendererInterface`:" #. type: Fenced code block (php) #: ../src/guide/views/template-engines.md @@ -248,11 +310,37 @@ msgid "" " }\n" "}\n" msgstr "" +" $value) {\n" +" $content = str_replace(\"{{$key}}\", (string) $value, $content);\n" +" }\n" +" \n" +" return $this->parser->parse($content);\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/views/template-engines.md msgid "Register your custom renderer:" -msgstr "" +msgstr "Registre o seu renderer personalizado:" #. type: Fenced code block (php) #: ../src/guide/views/template-engines.md @@ -267,17 +355,25 @@ msgid "" " ],\n" "],\n" msgstr "" +"use Yiisoft\\Container\\Reference;\n" +"\n" +"// Na configuração\n" +"'yiisoft/view' => [\n" +" 'renderers' => [\n" +" 'md' => Reference::to(App\\View\\MarkdownRenderer::class),\n" +" ],\n" +"],\n" #. type: Plain text #: ../src/guide/views/template-engines.md msgid "Now you can use `.md` template files:" -msgstr "" +msgstr "Agora você pode usar arquivos de template `.md`:" #. type: Plain text #: ../src/guide/views/template-engines.md #, no-wrap msgid "**views/content/help.md**\n" -msgstr "" +msgstr "**views/content/help.md**\n" #. type: Fenced code block (markdown) #: ../src/guide/views/template-engines.md @@ -293,12 +389,21 @@ msgid "" "- Feature 2\n" "- Feature 3\n" msgstr "" +"# Help: {{title}}\n" +"\n" +"Welcome, {{username}}!\n" +"\n" +"This is a Markdown template with **bold** and *italic* text.\n" +"\n" +"- Feature 1\n" +"- Feature 2\n" +"- Feature 3\n" #. type: Title ## #: ../src/guide/views/template-engines.md #, no-wrap msgid "Choosing the Right Template Engine" -msgstr "" +msgstr "Escolhendo a template engine certa" #. type: Plain text #: ../src/guide/views/template-engines.md @@ -310,6 +415,11 @@ msgid "" "- You want to leverage existing PHP knowledge\n" "- You need complex logic in templates (though this should be minimized)\n" msgstr "" +"**Use templates PHP quando:**\n" +"- Você precisa do máximo de flexibilidade e desempenho\n" +"- Seu time está à vontade com PHP\n" +"- Você quer aproveitar o conhecimento de PHP que já tem\n" +"- Você precisa de lógica complexa nos templates (embora isso deva ser minimizado)\n" #. type: Plain text #: ../src/guide/views/template-engines.md @@ -321,6 +431,11 @@ msgid "" "- You need automatic escaping and security features\n" "- You want template inheritance and advanced features\n" msgstr "" +"**Use templates Twig quando:**\n" +"- Você quer uma separação mais rígida entre lógica e apresentação\n" +"- Você trabalha com designers que preferem uma sintaxe mais limpa\n" +"- Você precisa de escape automático e recursos de segurança\n" +"- Você quer herança de templates e recursos avançados\n" #. type: Plain text #: ../src/guide/views/template-engines.md @@ -331,33 +446,37 @@ msgid "" "- You're working with specialized content formats\n" "- You need integration with external template systems\n" msgstr "" +"**Use templates personalizados quando:**\n" +"- Você tem requisitos específicos que o PHP ou o Twig não atendem\n" +"- Você trabalha com formatos de conteúdo especializados\n" +"- Você precisa integrar com sistemas de template externos\n" #. type: Bullet: '1. ' #: ../src/guide/views/template-engines.md msgid "**Keep templates simple**: Move complex logic to controllers or services" -msgstr "" +msgstr "**Mantenha os templates simples**: leve a lógica complexa para controllers ou serviços" #. type: Bullet: '2. ' #: ../src/guide/views/template-engines.md msgid "**Always escape output**: Prevent XSS attacks by properly escaping variables" -msgstr "" +msgstr "**Sempre escape a saída**: evite ataques XSS escapando as variáveis corretamente" #. type: Bullet: '3. ' #: ../src/guide/views/template-engines.md msgid "**Use meaningful names**: Name your templates and variables clearly" -msgstr "" +msgstr "**Use nomes significativos**: dê nomes claros aos seus templates e variáveis" #. type: Bullet: '4. ' #: ../src/guide/views/template-engines.md msgid "**Organize templates**: Group related templates in subdirectories" -msgstr "" +msgstr "**Organize os templates**: agrupe templates relacionados em subdiretórios" #. type: Bullet: '5. ' #: ../src/guide/views/template-engines.md msgid "**Document variables**: Always add type hints for better IDE support" -msgstr "" +msgstr "**Documente as variáveis**: sempre adicione dicas de tipo para um suporte melhor da IDE" #. type: Bullet: '6. ' #: ../src/guide/views/template-engines.md msgid "**Avoid business logic**: Keep business logic in models and services" -msgstr "" +msgstr "**Evite lógica de negócio**: mantenha a lógica de negócio em models e serviços" diff --git a/_translations/po/pt-BR/guide_views_view-injections.md.po b/_translations/po/pt-BR/guide_views_view-injections.md.po index 0f074a2f..637cb09f 100644 --- a/_translations/po/pt-BR/guide_views_view-injections.md.po +++ b/_translations/po/pt-BR/guide_views_view-injections.md.po @@ -8,47 +8,45 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2025-12-24 13:00+0000\n" "PO-Revision-Date: 2025-12-24 13:00+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/cookbook/sentry-integration.md ../src/guide/concept/configuration.md -#: ../src/guide/tutorial/using-yii-with-roadrunner.md -#: ../src/guide/views/view-injections.md +#: ../src/cookbook/sentry-integration.md ../src/guide/concept/configuration.md ../src/guide/tutorial/using-yii-with-roadrunner.md ../src/guide/views/view-injections.md #, no-wrap msgid "Configuration" -msgstr "" +msgstr "Configuração" #. type: Title # #: ../src/guide/views/view-injections.md #, no-wrap msgid "View injections" -msgstr "" +msgstr "Injeções de view" #. type: Plain text #: ../src/guide/views/view-injections.md msgid "The view injections are designed to provide a standardized way to pass parameters to the common layer of views in an application. It allows developers to manage the data that will be available across various views, ensuring flexibility and reusability of code." -msgstr "" +msgstr "As injeções de view oferecem uma forma padronizada de passar parâmetros para a camada comum das views de uma aplicação. Com elas, você gerencia os dados que ficarão disponíveis em várias views, o que garante flexibilidade e reaproveitamento de código." #. type: Plain text #: ../src/guide/views/view-injections.md msgid "The view injections could be used if you require `yiisoft/yii-view-renderer` package:" -msgstr "" +msgstr "Você pode usar as injeções de view se a sua aplicação exige o pacote `yiisoft/yii-view-renderer`:" #. type: Fenced code block (sh) #: ../src/guide/views/view-injections.md ../src/guide/views/view.md #, no-wrap msgid "composer require yiisoft/yii-view-renderer\n" -msgstr "" +msgstr "composer require yiisoft/yii-view-renderer\n" #. type: Plain text #: ../src/guide/views/view-injections.md msgid "In config `params.php`:" -msgstr "" +msgstr "Na configuração `params.php`:" #. type: Fenced code block (php) #: ../src/guide/views/view-injections.md @@ -63,17 +61,25 @@ msgid "" " ],\n" " ],\n" msgstr "" +"...\n" +"'yiisoft/yii-view' => [\n" +" 'injections' => [\n" +" Reference::to(ContentViewInjection::class),\n" +" Reference::to(CsrfViewInjection::class),\n" +" Reference::to(LayoutViewInjection::class),\n" +" ],\n" +" ],\n" #. type: Title ## #: ../src/guide/views/view-injections.md #, no-wrap msgid "New injections" -msgstr "" +msgstr "Novas injeções" #. type: Plain text #: ../src/guide/views/view-injections.md msgid "Start by defining a class that will implement the `Yiisoft\\Yii\\View\\Renderer\\CommonParametersInjectionInterface`. This class will be responsible for providing the parameters you want to inject into your view templates and layouts." -msgstr "" +msgstr "Comece definindo uma classe que implemente `Yiisoft\\Yii\\View\\Renderer\\CommonParametersInjectionInterface`. Essa classe fornece os parâmetros que você quer injetar nos templates de view e nos layouts." #. type: Fenced code block (php) #: ../src/guide/views/view-injections.md @@ -98,11 +104,29 @@ msgid "" " }\n" "}\n" msgstr "" +"class MyCustomParametersInjection implements Yiisoft\\Yii\\View\\Renderer\\CommonParametersInjectionInterface\n" +"{\n" +" // As propriedades e os métodos da classe ficam aqui\n" +"\n" +" public function __construct(UserService $userService)\n" +" {\n" +" $this->userService = $userService;\n" +" }\n" +"\n" +" public function getCommonParameters(): array\n" +" {\n" +" return [\n" +" 'siteName' => 'My Awesome Site',\n" +" 'currentYear' => date('Y'),\n" +" 'user' => $this->userService->getCurrentUser(),\n" +" ];\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/views/view-injections.md msgid "Add your new Injection to `params.php`:" -msgstr "" +msgstr "Adicione a nova injeção ao `params.php`:" #. type: Fenced code block (php) #: ../src/guide/views/view-injections.md @@ -115,22 +139,28 @@ msgid "" " ],\n" " ],\n" msgstr "" +"'yiisoft/yii-view' => [\n" +" 'injections' => [\n" +" ...,\n" +" Reference::to(MyCustomParametersInjection::class),\n" +" ],\n" +" ],\n" #. type: Title ## #: ../src/guide/views/view-injections.md #, no-wrap msgid "Using Separate Injections for Different Layouts" -msgstr "" +msgstr "Usando injeções separadas para layouts diferentes" #. type: Plain text #: ../src/guide/views/view-injections.md msgid "If your application has multiple layouts, you can create separate parameter injections for each layout. This approach allows you to tailor the parameters injected into each layout according to its specific needs, enhancing the flexibility and maintainability of your application." -msgstr "" +msgstr "Se a sua aplicação tem vários layouts, você pode criar injeções de parâmetros separadas para cada um. Assim, os parâmetros injetados em cada layout atendem às necessidades específicas dele, o que deixa a aplicação mais flexível e fácil de manter." #. type: Plain text #: ../src/guide/views/view-injections.md msgid "Create your custom ViewInjection for a specific layout:" -msgstr "" +msgstr "Crie a sua ViewInjection personalizada para um layout específico:" #. type: Fenced code block (php) #: ../src/guide/views/view-injections.md @@ -150,11 +180,24 @@ msgid "" " }\n" "}\n" msgstr "" +"readonly final class CartViewInjection implements CommonParametersInjectionInterface\n" +"{\n" +" public function __construct(private Cart $cart)\n" +" {\n" +" }\n" +"\n" +" public function getCommonParameters(): array\n" +" {\n" +" return [\n" +" 'cart' => $this->cart,\n" +" ];\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/views/view-injections.md msgid "Add your new injection to `params.php` under specific layout name. In the following example, it's `@layout/cart`:" -msgstr "" +msgstr "Adicione a nova injeção ao `params.php` sob o nome de um layout específico. No exemplo a seguir, é `@layout/cart`:" #. type: Fenced code block (php) #: ../src/guide/views/view-injections.md @@ -177,3 +220,19 @@ msgid "" " ],\n" " ],\n" msgstr "" +"'yiisoft/yii-view' => [\n" +" 'injections' => [\n" +" ...,\n" +" Reference::to(MyCustomParametersInjection::class),\n" +" DynamicReference::to(static function (ContainerInterface $container) {\n" +" $cart = $container\n" +" ->get(Cart::class);\n" +"\n" +" return new LayoutSpecificInjections(\n" +" '@layout/cart', // nome do layout para a injeção\n" +"\n" +" new CartViewInjection($cart)\n" +" );\n" +" }),\n" +" ],\n" +" ],\n" diff --git a/_translations/po/pt-BR/guide_views_view.md.po b/_translations/po/pt-BR/guide_views_view.md.po index 5c3eba68..921406e7 100644 --- a/_translations/po/pt-BR/guide_views_view.md.po +++ b/_translations/po/pt-BR/guide_views_view.md.po @@ -8,22 +8,18 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-02-25 03:25+0000\n" "PO-Revision-Date: 2026-02-25 03:25+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/cookbook/making-http-requests.md -#: ../src/cookbook/sentry-integration.md -#: ../src/guide/tutorial/using-yii-with-roadrunner.md -#: ../src/guide/tutorial/using-yii-with-swoole.md ../src/guide/views/asset.md -#: ../src/guide/views/view.md ../src/guide/views/widget.md +#: ../src/cookbook/making-http-requests.md ../src/cookbook/sentry-integration.md ../src/guide/tutorial/using-yii-with-roadrunner.md ../src/guide/tutorial/using-yii-with-swoole.md ../src/guide/views/asset.md ../src/guide/views/view.md ../src/guide/views/widget.md #, no-wrap msgid "Installation" -msgstr "" +msgstr "Instalação" #. type: Title # #: ../src/guide/index.md ../src/guide/views/view.md @@ -108,22 +104,21 @@ msgstr "" "}\n" #. type: Title ## -#: ../src/guide/views/asset.md ../src/guide/views/view.md -#: ../src/guide/views/widget.md +#: ../src/guide/views/asset.md ../src/guide/views/view.md ../src/guide/views/widget.md #, no-wrap msgid "Basic Concepts" -msgstr "" +msgstr "Conceitos básicos" #. type: Fenced code block (sh) #: ../src/guide/views/view-injections.md ../src/guide/views/view.md #, no-wrap msgid "composer require yiisoft/yii-view-renderer\n" -msgstr "" +msgstr "composer require yiisoft/yii-view-renderer\n" #. type: Plain text #: ../src/guide/views/view.md msgid "View is responsible for presenting data to end users. You give it a template with some placeholders and presentation logic and some data. The view is passing data to the template executing template logic. The end result is ready to be passed to end user, be it a browser, a file to download, an email to send or something else." -msgstr "" +msgstr "A view é responsável por apresentar os dados ao usuário final. Você entrega a ela um template com alguns placeholders e lógica de apresentação, além de alguns dados. A view passa os dados para o template e executa a lógica do template. O resultado final está pronto para ser entregue ao usuário final, seja um navegador, um arquivo para download, um e-mail a ser enviado ou outra coisa." #. type: Fenced code block (mermaid) #: ../src/guide/views/view.md @@ -135,58 +130,63 @@ msgid "" " V --> C[HTML]\n" " C --> D[Browser]\n" msgstr "" +"flowchart LR\n" +" A[Dados] --> V[View]\n" +" B[Template] --> V\n" +" V --> C[HTML]\n" +" C --> D[Navegador]\n" #. type: Plain text #: ../src/guide/views/view.md msgid "In Yii3 views are typically PHP files that contain presentation logic and HTML markup. The view system provides a flexible way to organize your presentation layer and supports features like layouts and partial views. Instead of using plain PHP templates, you can leverage one of the template engines such as [Twig](template-engines.md) or [Blade](https://github.com/lee-to/yii-blade)." -msgstr "" +msgstr "No Yii3, as views normalmente são arquivos PHP com lógica de apresentação e marcação HTML. O sistema de views oferece uma forma flexível de organizar a camada de apresentação e suporta recursos como layouts e views parciais. Em vez de templates PHP puros, você pode usar uma das template engines, como [Twig](template-engines.md) ou [Blade](https://github.com/lee-to/yii-blade)." #. type: Plain text #: ../src/guide/views/view.md msgid "For basic view functionality, you need the `yiisoft/view` package:" -msgstr "" +msgstr "Para a funcionalidade básica de views, você precisa do pacote `yiisoft/view`:" #. type: Fenced code block (sh) #: ../src/guide/views/view.md #, no-wrap msgid "composer require yiisoft/view\n" -msgstr "" +msgstr "composer require yiisoft/view\n" #. type: Plain text #: ../src/guide/views/view.md msgid "For web applications, you should also install the `yiisoft/yii-view-renderer` package which provides [PSR-7](https://www.php-fig.org/psr/psr-7/) compatibility and web-specific features:" -msgstr "" +msgstr "Em aplicações web, instale também o pacote `yiisoft/yii-view-renderer`, que oferece compatibilidade com [PSR-7](https://www.php-fig.org/psr/psr-7/) e recursos específicos para a web:" #. type: Plain text #: ../src/guide/views/view.md ../src/guide/views/widget.md msgid "These packages are included by default in the `yiisoft/app` application template." -msgstr "" +msgstr "Esses pacotes já vêm incluídos por padrão no template de aplicação `yiisoft/app`." #. type: Plain text #: ../src/guide/views/view.md msgid "A view template file contains presentation logic. In the `yiisoft/app` template, view files are typically stored alongside their controllers (e.g., `src/Web/Echo/Action.php`). Here's a simple view file example, `src/Web/Echo/template.php`:" -msgstr "" +msgstr "Um arquivo de template de view contém lógica de apresentação. No template `yiisoft/app`, os arquivos de view normalmente ficam junto dos seus controllers (por exemplo, `src/Web/Echo/Action.php`). Este é um exemplo simples de arquivo de view, `src/Web/Echo/template.php`:" #. type: Plain text #: ../src/guide/views/view.md msgid "Here `$message` is a view data that is passed when you render a template with the help of `WebViewRenderer`. For example, `src/Web/Echo/Action.php`:" -msgstr "" +msgstr "Aqui, `$message` é um dado da view passado quando você renderiza um template com o `WebViewRenderer`. Por exemplo, `src/Web/Echo/Action.php`:" #. type: Plain text #: ../src/guide/views/view.md msgid "First argument of the `render()` method is a path to the template file. In the `yiisoft/app`, template files are typically stored alongside their actions. The result is ready to be rendered to the browser so we return it immediately." -msgstr "" +msgstr "O primeiro argumento do método `render()` é o caminho do arquivo de template. No `yiisoft/app`, os arquivos de template normalmente ficam junto das suas actions. O resultado já está pronto para ser enviado ao navegador, então o devolvemos imediatamente." #. type: Title ## #: ../src/guide/views/view.md #, no-wrap msgid "Working with layouts" -msgstr "" +msgstr "Trabalhando com layouts" #. type: Plain text #: ../src/guide/views/view.md msgid "Most web applications use a common layout for all pages. In the `yiisoft/app` template, layouts are stored in `src/Web/Shared/Layout/Main/` directory. You can set a default layout in `config/common/params.php`:" -msgstr "" +msgstr "A maioria das aplicações web usa um layout comum para todas as páginas. No template `yiisoft/app`, os layouts ficam no diretório `src/Web/Shared/Layout/Main/`. Você pode definir um layout padrão em `config/common/params.php`:" #. type: Fenced code block (php) #: ../src/guide/views/view.md @@ -199,11 +199,17 @@ msgid "" " ],\n" "];\n" msgstr "" +"return [\n" +" 'yiisoft/yii-view-renderer' => [\n" +" 'viewPath' => null,\n" +" 'layout' => '@src/Web/Shared/Layout/Main/layout.php',\n" +" ],\n" +"];\n" #. type: Plain text #: ../src/guide/views/view.md msgid "A typical layout file such as `src/Web/Shared/Layout/Main/layout.php` looks like this:" -msgstr "" +msgstr "Um arquivo de layout típico, como `src/Web/Shared/Layout/Main/layout.php`, tem esta cara:" #. type: Fenced code block (php) #: ../src/guide/views/view.md @@ -268,21 +274,79 @@ msgid "" "\n" "endPage() ?>\n" msgstr "" +"register(MainAsset::class);\n" +"\n" +"$this->addCssFiles($assetManager->getCssFiles());\n" +"$this->addCssStrings($assetManager->getCssStrings());\n" +"$this->addJsFiles($assetManager->getJsFiles());\n" +"$this->addJsStrings($assetManager->getJsStrings());\n" +"$this->addJsVars($assetManager->getJsVars());\n" +"\n" +"$this->beginPage()\n" +"?>\n" +"\n" +"locale) ?>\">\n" +"\n" +" charset) ?>\">\n" +" \n" +" get('@baseUrl/favicon.svg') ?>\" type=\"image/svg+xml\">\n" +" <?= Html::encode($this->getTitle()) ?>\n" +" head() ?>\n" +"\n" +"\n" +"beginBody() ?>\n" +"\n" +"\n" +"\n" +"
\n" +" \n" +"
\n" +"\n" +"
\n" +" © name) ?> \n" +"
\n" +"\n" +"endBody() ?>\n" +"\n" +"\n" +"endPage() ?>\n" #. type: Plain text #: ../src/guide/views/view.md msgid "In the template above `$applicationParams` is an array of parameters from `config/common/application.php`." -msgstr "" +msgstr "No template acima, `$applicationParams` é um array de parâmetros de `config/common/application.php`." #. type: Plain text #: ../src/guide/views/view.md msgid "`$aliases` refers to [aliases component](../concept/aliases.md) that is used to get the base URL of the application at the server for URLs." -msgstr "" +msgstr "`$aliases` se refere ao [componente de aliases](../concept/aliases.md), usado para obter a URL base da aplicação no servidor para montar URLs." #. type: Plain text #: ../src/guide/views/view.md msgid "`$this` is an instance of the view that we use to get page title and output assets. Both standard and custom." -msgstr "" +msgstr "`$this` é uma instância da view que usamos para obter o título da página e gerar a saída dos assets, tanto os padrão quanto os personalizados." #. type: Plain text #: ../src/guide/views/view.md @@ -292,6 +356,9 @@ msgid "" "automatically copied to `public/assets` on first use. It is not very useful for a single CSS file but becomes handy as\n" "the number of assets grows.\n" msgstr "" +"Com `$assetManager->register(MainAsset::class);` registramos um asset que define o `css` a ser incluído na página. Ele é\n" +"copiado automaticamente para `public/assets` no primeiro uso. Isso não ajuda muito com um único arquivo CSS, mas se torna útil\n" +"conforme o número de assets cresce.\n" #. type: Plain text #: ../src/guide/views/view.md @@ -301,22 +368,25 @@ msgid "" "> No output in plain PHP templates is encoded you should not forget to use `Html::encode()` to prevent\n" "XSS security vulnerabilities.\n" msgstr "" +"> [!IMPORTANT]\n" +"> Nenhuma saída em templates PHP puros é codificada, então não se esqueça de usar `Html::encode()` para evitar\n" +"vulnerabilidades de segurança do tipo XSS.\n" #. type: Plain text #: ../src/guide/views/view.md msgid "More about what's available in layout could be read in [yiisoft/view](https://github.com/yiisoft/view) documentation." -msgstr "" +msgstr "Você encontra mais detalhes sobre o que está disponível no layout na documentação do [yiisoft/view](https://github.com/yiisoft/view)." #. type: Title ### #: ../src/guide/views/view.md #, no-wrap msgid "Rendering without layout" -msgstr "" +msgstr "Renderizando sem layout" #. type: Plain text #: ../src/guide/views/view.md msgid "Sometimes you need to render a view without a layout (for example, for AJAX responses):" -msgstr "" +msgstr "Às vezes você precisa renderizar uma view sem layout (por exemplo, para respostas AJAX):" #. type: Fenced code block (php) #: ../src/guide/views/view.md @@ -335,24 +405,36 @@ msgid "" " return $this->viewRenderer->renderPartial('ajax-content', ['data' => $data]);\n" "}\n" msgstr "" +"public function ajaxContent(): ResponseInterface\n" +"{\n" +" return $this->viewRenderer\n" +" ->withLayout(null)\n" +" ->render('ajax-content', ['data' => $data]);\n" +"}\n" +"\n" +"// Ou use o método renderPartial\n" +"public function ajaxContent(): ResponseInterface\n" +"{\n" +" return $this->viewRenderer->renderPartial('ajax-content', ['data' => $data]);\n" +"}\n" #. type: Title ## #: ../src/guide/views/view.md #, no-wrap msgid "Nested Views and Partials" -msgstr "" +msgstr "Views aninhadas e parciais" #. type: Title ### #: ../src/guide/views/view.md #, no-wrap msgid "Rendering Sub-views" -msgstr "" +msgstr "Renderizando sub-views" #. type: Plain text #: ../src/guide/views/view.md #, no-wrap msgid "You can render other views from within a view using the `$this->render()` method:\n" -msgstr "" +msgstr "Você pode renderizar outras views de dentro de uma view com o método `$this->render()`:\n" #. type: Fenced code block (php) #: ../src/guide/views/view.md @@ -373,12 +455,26 @@ msgid "" " \n" "\n" msgstr "" +"\n" +"
\n" +" \n" +" render('_post_item', ['post' => $post]) ?>\n" +" \n" +"
\n" #. type: Plain text #: ../src/guide/views/view.md #, no-wrap msgid "**src/Web/Post/_item.php**\n" -msgstr "" +msgstr "**src/Web/Post/_item.php**\n" #. type: Fenced code block (php) #: ../src/guide/views/view.md @@ -401,17 +497,33 @@ msgid "" " \n" "\n" msgstr "" +"\n" +"
\n" +"

getTitle()) ?>

\n" +"

getExcerpt()) ?>

\n" +" \n" +"
\n" #. type: Title ### #: ../src/guide/views/view.md #, no-wrap msgid "Using Blocks" -msgstr "" +msgstr "Usando blocos" #. type: Plain text #: ../src/guide/views/view.md msgid "Blocks allow you to define content in one view and display it in another, typically in layouts:" -msgstr "" +msgstr "Os blocos permitem definir conteúdo em uma view e exibi-lo em outra, normalmente nos layouts:" #. type: Fenced code block (php) #: ../src/guide/views/view.md @@ -425,17 +537,24 @@ msgid "" " \n" "\n" msgstr "" +"// Em um arquivo de view\n" +"setBlock('sidebar', $this->render('_sidebar', ['items' => $sidebarItems])) ?>\n" +"\n" +"// No arquivo de layout\n" +"hasBlock('sidebar')): ?>\n" +" \n" +"\n" #. type: Title ## #: ../src/guide/views/view.md #, no-wrap msgid "Rendering as String" -msgstr "" +msgstr "Renderizando como string" #. type: Plain text #: ../src/guide/views/view.md msgid "If you need the rendered content as a string instead of a PSR-7 response:" -msgstr "" +msgstr "Se você precisa do conteúdo renderizado como string em vez de uma resposta PSR-7:" #. type: Fenced code block (php) #: ../src/guide/views/view.md @@ -448,17 +567,23 @@ msgid "" " ]);\n" "}\n" msgstr "" +"public function getEmailContent(): string\n" +"{\n" +" return $this->viewRenderer->renderAsString('email/welcome', [\n" +" 'user' => $user,\n" +" ]);\n" +"}\n" #. type: Title ## #: ../src/guide/views/view.md #, no-wrap msgid "View Events" -msgstr "" +msgstr "Eventos de view" #. type: Plain text #: ../src/guide/views/view.md msgid "The view system triggers events during the rendering process that you can listen to:" -msgstr "" +msgstr "O sistema de views dispara eventos durante a renderização, e você pode escutá-los:" #. type: Fenced code block (php) #: ../src/guide/views/view.md @@ -488,3 +613,26 @@ msgid "" " }\n" "}\n" msgstr "" +"use Yiisoft\\View\\Event\\WebView\\BeforeRender;\n" +"use Yiisoft\\View\\Event\\WebView\\AfterRender;\n" +"\n" +"// Exemplo de listener de eventos\n" +"final class ViewEventListener\n" +"{\n" +" public function onBeforeRender(BeforeRender $event): void\n" +" {\n" +" // Adiciona uma classe CSS global com base no nome da view\n" +" if (str_contains($event->getFile(), 'admin/')) {\n" +" $event->getView()->registerCssClass('admin-view');\n" +" }\n" +" }\n" +"\n" +" public function onAfterRender(AfterRender $event): void\n" +" {\n" +" // Registra no log o tempo de renderização\n" +" $this->logger->info('View rendered', [\n" +" 'view' => $event->getFile(),\n" +" 'time' => $event->getRenderTime(),\n" +" ]);\n" +" }\n" +"}\n" diff --git a/_translations/po/pt-BR/guide_views_widget.md.po b/_translations/po/pt-BR/guide_views_widget.md.po index 5835a096..e18187ff 100644 --- a/_translations/po/pt-BR/guide_views_widget.md.po +++ b/_translations/po/pt-BR/guide_views_widget.md.po @@ -8,117 +8,112 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2025-12-24 13:00+0000\n" "PO-Revision-Date: 2025-12-24 13:00+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/cookbook/making-http-requests.md -#: ../src/cookbook/sentry-integration.md -#: ../src/guide/tutorial/using-yii-with-roadrunner.md -#: ../src/guide/tutorial/using-yii-with-swoole.md ../src/guide/views/asset.md -#: ../src/guide/views/view.md ../src/guide/views/widget.md +#: ../src/cookbook/making-http-requests.md ../src/cookbook/sentry-integration.md ../src/guide/tutorial/using-yii-with-roadrunner.md ../src/guide/tutorial/using-yii-with-swoole.md ../src/guide/views/asset.md ../src/guide/views/view.md ../src/guide/views/widget.md #, no-wrap msgid "Installation" -msgstr "" +msgstr "Instalação" #. type: Title ## -#: ../src/guide/views/asset.md ../src/guide/views/view.md -#: ../src/guide/views/widget.md +#: ../src/guide/views/asset.md ../src/guide/views/view.md ../src/guide/views/widget.md #, no-wrap msgid "Basic Concepts" -msgstr "" +msgstr "Conceitos básicos" #. type: Plain text #: ../src/guide/views/view.md ../src/guide/views/widget.md msgid "These packages are included by default in the `yiisoft/app` application template." -msgstr "" +msgstr "Esses pacotes já vêm incluídos por padrão no template de aplicação `yiisoft/app`." #. type: Title # #: ../src/guide/views/widget.md #, no-wrap msgid "Widgets" -msgstr "" +msgstr "Widgets" #. type: Plain text #: ../src/guide/views/widget.md msgid "Widgets are reusable, self-contained components that encapsulate complex HTML generation logic. They provide a clean way to create configurable UI elements that can be used across different views and applications. Yii3 provides a flexible widget system through the `yiisoft/widget` package." -msgstr "" +msgstr "Widgets são componentes reutilizáveis e autocontidos que encapsulam uma lógica complexa de geração de HTML. Eles oferecem uma forma limpa de criar elementos de interface configuráveis, que podem ser usados em diferentes views e aplicações. O Yii3 oferece um sistema de widgets flexível por meio do pacote `yiisoft/widget`." #. type: Plain text #: ../src/guide/views/widget.md msgid "The widget functionality is provided by the `yiisoft/widget` package:" -msgstr "" +msgstr "A funcionalidade de widgets vem do pacote `yiisoft/widget`:" #. type: Fenced code block (bash) #: ../src/guide/views/widget.md #, no-wrap msgid "composer require yiisoft/widget\n" -msgstr "" +msgstr "composer require yiisoft/widget\n" #. type: Plain text #: ../src/guide/views/widget.md msgid "For ready-made widgets (like forms, navigation, etc.), you can also install:" -msgstr "" +msgstr "Para widgets prontos (como formulários, navegação etc.), você também pode instalar:" #. type: Fenced code block (bash) #: ../src/guide/views/widget.md #, no-wrap msgid "composer require yiisoft/yii-widgets\n" -msgstr "" +msgstr "composer require yiisoft/yii-widgets\n" #. type: Title ### #: ../src/guide/views/widget.md #, no-wrap msgid "Widget Class" -msgstr "" +msgstr "Classe do widget" #. type: Plain text #: ../src/guide/views/widget.md msgid "A widget is a PHP class that extends the abstract `Widget` class and implements a `render()` method that returns HTML content as a string." -msgstr "" +msgstr "Um widget é uma classe PHP que estende a classe abstrata `Widget` e implementa um método `render()` que devolve o conteúdo HTML como string." #. type: Title ### #: ../src/guide/views/widget.md #, no-wrap msgid "Widget Factory" -msgstr "" +msgstr "Widget factory" #. type: Plain text #: ../src/guide/views/widget.md msgid "The `WidgetFactory` is responsible for creating widget instances and can inject dependencies through the DI container." -msgstr "" +msgstr "A `WidgetFactory` é responsável por criar as instâncias dos widgets e pode injetar dependências por meio do container de DI." #. type: Title ### #: ../src/guide/views/widget.md #, no-wrap msgid "Widget Configuration" -msgstr "" +msgstr "Configuração de widgets" #. type: Plain text #: ../src/guide/views/widget.md msgid "Widgets can be configured with properties and methods, making them highly customizable and reusable across different contexts." -msgstr "" +msgstr "Os widgets podem ser configurados com propriedades e métodos, o que os torna altamente personalizáveis e reutilizáveis em diferentes contextos." #. type: Title ## #: ../src/guide/views/widget.md #, no-wrap msgid "Creating Custom Widgets" -msgstr "" +msgstr "Criando widgets próprios" #. type: Title ### #: ../src/guide/views/widget.md #, no-wrap msgid "Simple Widget" -msgstr "" +msgstr "Widget simples" #. type: Plain text #: ../src/guide/views/widget.md msgid "Here's a basic widget that displays an alert message:" -msgstr "" +msgstr "Este é um widget básico que exibe uma mensagem de alerta:" #. type: Fenced code block (php) #: ../src/guide/views/widget.md @@ -186,12 +181,73 @@ msgid "" " }\n" "}\n" msgstr "" +"message = $message;\n" +" return $new;\n" +" }\n" +"\n" +" public function type(string $type): self\n" +" {\n" +" $new = clone $this;\n" +" $new->type = $type;\n" +" return $new;\n" +" }\n" +"\n" +" public function closeable(bool $closeable = true): self\n" +" {\n" +" $new = clone $this;\n" +" $new->closeable = $closeable;\n" +" return $new;\n" +" }\n" +"\n" +" protected function render(): string\n" +" {\n" +" if (empty($this->message)) {\n" +" return '';\n" +" }\n" +"\n" +" $classes = ['alert', 'alert-' . $this->type];\n" +" \n" +" if ($this->closeable) {\n" +" $classes[] = 'alert-dismissible';\n" +" }\n" +"\n" +" $content = Html::encode($this->message);\n" +" \n" +" if ($this->closeable) {\n" +" $content .= Html::button('×', [\n" +" 'type' => 'button',\n" +" 'class' => 'btn-close',\n" +" 'data-bs-dismiss' => 'alert',\n" +" ]);\n" +" }\n" +"\n" +" return Html::div($content, ['class' => implode(' ', $classes)]);\n" +" }\n" +"}\n" #. type: Title ### #: ../src/guide/views/widget.md #, no-wrap msgid "Using the Widget" -msgstr "" +msgstr "Usando o widget" #. type: Fenced code block (php) #: ../src/guide/views/widget.md @@ -219,17 +275,38 @@ msgid "" " ->type('danger') ?>\n" "\n" msgstr "" +"\n" +"\n" +"
\n" +" message('Operation completed successfully!')\n" +" ->type('success')\n" +" ->closeable() ?>\n" +" \n" +" message('Please review the form errors below.')\n" +" ->type('danger') ?>\n" +"
\n" #. type: Title ### #: ../src/guide/views/widget.md #, no-wrap msgid "Widget with Dependencies" -msgstr "" +msgstr "Widget com dependências" #. type: Plain text #: ../src/guide/views/widget.md msgid "Widgets can use dependency injection for services:" -msgstr "" +msgstr "Os widgets podem usar injeção de dependência para receber serviços:" #. type: Fenced code block (php) #: ../src/guide/views/widget.md @@ -301,29 +378,94 @@ msgid "" " }\n" "}\n" msgstr "" +"userService->getCurrentUser();\n" +" \n" +" if ($currentUser === null) {\n" +" return $this->renderLoginLink();\n" +" }\n" +"\n" +" return $this->renderUserMenu($currentUser);\n" +" }\n" +"\n" +" private function renderLoginLink(): string\n" +" {\n" +" return Html::a('Login', $this->urlGenerator->generate('login'), [\n" +" 'class' => 'btn btn-primary',\n" +" ]);\n" +" }\n" +"\n" +" private function renderUserMenu($user): string\n" +" {\n" +" $items = [\n" +" Html::a('Profile', $this->urlGenerator->generate('user.profile'), [\n" +" 'class' => 'dropdown-item',\n" +" ]),\n" +" Html::a('Settings', $this->urlGenerator->generate('user.settings'), [\n" +" 'class' => 'dropdown-item',\n" +" ]),\n" +" '
',\n" +" Html::a('Logout', $this->urlGenerator->generate('logout'), [\n" +" 'class' => 'dropdown-item',\n" +" ]),\n" +" ];\n" +"\n" +" return Html::div(\n" +" Html::button(\n" +" Html::encode($user->getName()) . ' ',\n" +" [\n" +" 'class' => 'btn btn-secondary dropdown-toggle',\n" +" 'type' => 'button',\n" +" 'data-bs-toggle' => 'dropdown',\n" +" ]\n" +" ) .\n" +" Html::div(implode('', $items), ['class' => 'dropdown-menu']),\n" +" ['class' => 'dropdown']\n" +" );\n" +" }\n" +"}\n" #. type: Title ## #: ../src/guide/views/widget.md #, no-wrap msgid "Widget Factory Setup" -msgstr "" +msgstr "Configuração da widget factory" #. type: Title ### #: ../src/guide/views/widget.md #, no-wrap msgid "Bootstrap Configuration" -msgstr "" +msgstr "Configuração de bootstrap" #. type: Plain text #: ../src/guide/views/widget.md msgid "Initialize the widget factory in your application bootstrap:" -msgstr "" +msgstr "Inicialize a widget factory no bootstrap da sua aplicação:" #. type: Plain text #: ../src/guide/views/widget.md #, no-wrap msgid "**config/bootstrap.php**\n" -msgstr "" +msgstr "**config/bootstrap.php**\n" #. type: Fenced code block (php) #: ../src/guide/views/widget.md @@ -352,18 +494,40 @@ msgid "" "\n" "WidgetFactory::initialize($container, $widgetDefaults);\n" msgstr "" +" [\n" +" 'type()' => ['info'],\n" +" 'closeable()' => [true],\n" +" ],\n" +" App\\Widget\\CardWidget::class => [\n" +" 'headerClass()' => ['card-header bg-primary text-white'],\n" +" ],\n" +"];\n" +"\n" +"WidgetFactory::initialize($container, $widgetDefaults);\n" #. type: Title ### #: ../src/guide/views/widget.md #, no-wrap msgid "DI Container Configuration" -msgstr "" +msgstr "Configuração do container de DI" #. type: Plain text #: ../src/guide/views/widget.md #, no-wrap msgid "**config/web/di.php**\n" -msgstr "" +msgstr "**config/web/di.php**\n" #. type: Fenced code block (php) #: ../src/guide/views/widget.md @@ -382,23 +546,35 @@ msgid "" " ) => new UserMenuWidget($userService, $urlGenerator),\n" "];\n" msgstr "" +"use App\\Widget\\AlertWidget;\n" +"use App\\Widget\\UserMenuWidget;\n" +"\n" +"return [\n" +" // Configurações de widgets podem ser definidas aqui, se necessário\n" +" AlertWidget::class => static fn() => new AlertWidget(),\n" +" \n" +" UserMenuWidget::class => static fn(\n" +" App\\Service\\UserService $userService,\n" +" Yiisoft\\Router\\UrlGeneratorInterface $urlGenerator\n" +" ) => new UserMenuWidget($userService, $urlGenerator),\n" +"];\n" #. type: Title ## #: ../src/guide/views/widget.md #, no-wrap msgid "Advanced Widget Examples" -msgstr "" +msgstr "Exemplos avançados de widgets" #. type: Title ### #: ../src/guide/views/widget.md #, no-wrap msgid "Data List Widget" -msgstr "" +msgstr "Widget de lista de dados" #. type: Plain text #: ../src/guide/views/widget.md msgid "A widget that displays a list of items with pagination:" -msgstr "" +msgstr "Um widget que exibe uma lista de itens com paginação:" #. type: Fenced code block (php) #: ../src/guide/views/widget.md @@ -482,11 +658,88 @@ msgid "" " }\n" "}\n" msgstr "" +"paginator = $paginator;\n" +" return $new;\n" +" }\n" +"\n" +" public function itemRenderer(callable $renderer): self\n" +" {\n" +" $new = clone $this;\n" +" $new->itemRenderer = $renderer;\n" +" return $new;\n" +" }\n" +"\n" +" public function containerClass(string $class): self\n" +" {\n" +" $new = clone $this;\n" +" $new->containerClass = $class;\n" +" return $new;\n" +" }\n" +"\n" +" public function itemClass(string $class): self\n" +" {\n" +" $new = clone $this;\n" +" $new->itemClass = $class;\n" +" return $new;\n" +" }\n" +"\n" +" public function emptyText(string $text): self\n" +" {\n" +" $new = clone $this;\n" +" $new->emptyText = $text;\n" +" return $new;\n" +" }\n" +"\n" +" protected function render(): string\n" +" {\n" +" if ($this->paginator === null) {\n" +" return '';\n" +" }\n" +"\n" +" $items = $this->paginator->read();\n" +" \n" +" if (empty($items)) {\n" +" return Html::div($this->emptyText, ['class' => 'empty-message']);\n" +" }\n" +"\n" +" $itemsHtml = '';\n" +" foreach ($items as $item) {\n" +" $content = $this->itemRenderer \n" +" ? ($this->itemRenderer)($item)\n" +" : Html::encode((string) $item);\n" +" \n" +" $itemsHtml .= Html::div($content, ['class' => $this->itemClass]);\n" +" }\n" +"\n" +" return Html::div($itemsHtml, ['class' => $this->containerClass]);\n" +" }\n" +"}\n" #. type: Plain text #: ../src/guide/views/widget.md msgid "Usage:" -msgstr "" +msgstr "Uso:" #. type: Fenced code block (php) #: ../src/guide/views/widget.md @@ -509,22 +762,135 @@ msgid "" " return $this->render('_post_card', ['post' => $post]);\n" " }) ?>\n" msgstr "" +"\n" +"\n" +"paginator($postPaginator)\n" +" ->containerClass('posts-list row')\n" +" ->itemClass('col-md-4 mb-3')\n" +" ->itemRenderer(function ($post) {\n" +" return $this->render('_post_card', ['post' => $post]);\n" +" }) ?>\n" #. type: Title ### #: ../src/guide/views/widget.md #, no-wrap msgid "Form Widget" -msgstr "" +msgstr "Widget de formulário" #. type: Plain text #: ../src/guide/views/widget.md msgid "A widget that simplifies form rendering:" +msgstr "Um widget que simplifica a renderização de formulários:" + +#. type: Fenced code block (php) +#: ../src/guide/views/widget.md +#, no-wrap +msgid "" +"model = $model;\n" +" return $new;\n" +" }\n" +"\n" +" public function action(string $action): self\n" +" {\n" +" $new = clone $this;\n" +" $new->action = $action;\n" +" return $new;\n" +" }\n" +"\n" +" public function method(string $method): self\n" +" {\n" +" $new = clone $this;\n" +" $new->method = $method;\n" +" return $new;\n" +" }\n" +"\n" +" public function options(array $options): self\n" +" {\n" +" $new = clone $this;\n" +" $new->options = $options;\n" +" return $new;\n" +" }\n" +"\n" +" public function field(string $attribute, array $options = []): self\n" +" {\n" +" $new = clone $this;\n" +" $new->fields[$attribute] = $options;\n" +" return $new;\n" +" }\n" +"\n" +" protected function render(): string\n" +" {\n" +" if ($this->model === null) {\n" +" return '';\n" +" }\n" +"\n" +" $formOptions = array_merge([\n" +" 'action' => $this->action,\n" +" 'method' => $this->method,\n" +" 'class' => 'form',\n" +" ], $this->options);\n" +"\n" +" $content = '';\n" +" foreach ($this->fields as $attribute => $options) {\n" +" $content .= $this->renderField($attribute, $options);\n" +" }\n" +"\n" +" return Html::form($content, $formOptions);\n" +" }\n" +"\n" +" private function renderField(string $attribute, array $options): string\n" +" {\n" +" $label = $options['label'] ?? ucfirst($attribute);\n" +" $type = $options['type'] ?? 'text';\n" +" $class = $options['class'] ?? 'form-control';\n" +"\n" +" $field = Html::div(\n" +" Html::label($label, null, ['class' => 'form-label']) .\n" +" Html::input($type, $attribute, $this->getModelValue($attribute), [\n" +" 'class' => $class,\n" +" 'id' => $attribute,\n" +" ]),\n" +" ['class' => 'mb-3']\n" +" );\n" +"\n" +" return $field;\n" +" }\n" +"\n" +" private function getModelValue(string $attribute): mixed\n" +" {\n" +" return $this->model->getAttributeValue($attribute);\n" +" }\n" +"}\n" msgstr "" - -#. type: Fenced code block (php) -#: ../src/guide/views/widget.md -#, no-wrap -msgid "" "model->getAttributeValue($attribute);\n" " }\n" "}\n" -msgstr "" #. type: Title ### #: ../src/guide/views/widget.md #, no-wrap msgid "Breadcrumb Widget" -msgstr "" +msgstr "Widget de breadcrumb" #. type: Plain text #: ../src/guide/views/widget.md msgid "A widget for navigation breadcrumbs:" -msgstr "" +msgstr "Um widget para breadcrumbs de navegação:" #. type: Fenced code block (php) #: ../src/guide/views/widget.md @@ -716,23 +1081,100 @@ msgid "" " }\n" "}\n" msgstr "" +"items = $items;\n" +" return $new;\n" +" }\n" +"\n" +" public function separator(string $separator): self\n" +" {\n" +" $new = clone $this;\n" +" $new->separator = $separator;\n" +" return $new;\n" +" }\n" +"\n" +" public function options(array $options): self\n" +" {\n" +" $new = clone $this;\n" +" $new->options = $options;\n" +" return $new;\n" +" }\n" +"\n" +" protected function render(): string\n" +" {\n" +" if (empty($this->items)) {\n" +" return '';\n" +" }\n" +"\n" +" $links = [];\n" +" $itemCount = count($this->items);\n" +" \n" +" foreach ($this->items as $index => $item) {\n" +" if ($index === $itemCount - 1) {\n" +" // Último item (página atual) - sem link\n" +" $links[] = Html::span($item['label'], ['class' => 'breadcrumb-item active']);\n" +" } else {\n" +" // Item de breadcrumb comum, com link\n" +" $url = isset($item['url']) \n" +" ? (is_array($item['url']) \n" +" ? $this->urlGenerator->generate($item['url'][0], $item['url'][1] ?? [])\n" +" : $item['url'])\n" +" : '#';\n" +" \n" +" $links[] = Html::span(\n" +" Html::a($item['label'], $url),\n" +" ['class' => 'breadcrumb-item']\n" +" );\n" +" }\n" +" }\n" +"\n" +" $options = array_merge(['class' => 'breadcrumb'], $this->options);\n" +"\n" +" return Html::nav(\n" +" Html::ol(implode('', $links), ['class' => 'breadcrumb']),\n" +" $options\n" +" );\n" +" }\n" +"}\n" #. type: Title ## #: ../src/guide/views/widget.md #, no-wrap msgid "Widget Best Practices" -msgstr "" +msgstr "Boas práticas com widgets" #. type: Title ### #: ../src/guide/views/widget.md #, no-wrap msgid "Configuration Pattern" -msgstr "" +msgstr "Padrão de configuração" #. type: Plain text #: ../src/guide/views/widget.md msgid "Use immutable configuration methods:" -msgstr "" +msgstr "Use métodos de configuração imutáveis:" #. type: Fenced code block (php) #: ../src/guide/views/widget.md @@ -745,17 +1187,23 @@ msgid "" " return $new;\n" "}\n" msgstr "" +"public function someProperty($value): self\n" +"{\n" +" $new = clone $this;\n" +" $new->someProperty = $value;\n" +" return $new;\n" +"}\n" #. type: Title ### #: ../src/guide/views/widget.md #, no-wrap msgid "Validation" -msgstr "" +msgstr "Validação" #. type: Plain text #: ../src/guide/views/widget.md msgid "Validate widget configuration in the render method:" -msgstr "" +msgstr "Valide a configuração do widget no método render:" #. type: Fenced code block (php) #: ../src/guide/views/widget.md @@ -770,17 +1218,25 @@ msgid "" " // ... render logic\n" "}\n" msgstr "" +"protected function render(): string\n" +"{\n" +" if (empty($this->items)) {\n" +" throw new InvalidArgumentException('Items cannot be empty.');\n" +" }\n" +" \n" +" // ... lógica de renderização\n" +"}\n" #. type: Title ### #: ../src/guide/views/widget.md #, no-wrap msgid "HTML Encoding" -msgstr "" +msgstr "Codificação de HTML" #. type: Plain text #: ../src/guide/views/widget.md msgid "Always encode user data:" -msgstr "" +msgstr "Sempre codifique os dados vindos do usuário:" #. type: Fenced code block (php) #: ../src/guide/views/widget.md @@ -793,17 +1249,23 @@ msgid "" " ]);\n" "}\n" msgstr "" +"protected function render(): string\n" +"{\n" +" return Html::div(Html::encode($this->userContent), [\n" +" 'class' => 'user-content',\n" +" ]);\n" +"}\n" #. type: Title ### #: ../src/guide/views/widget.md #, no-wrap msgid "Asset Management" -msgstr "" +msgstr "Gerenciamento de assets" #. type: Plain text #: ../src/guide/views/widget.md msgid "Register widget-specific assets:" -msgstr "" +msgstr "Registre os assets específicos do widget:" #. type: Fenced code block (php) #: ../src/guide/views/widget.md @@ -835,23 +1297,48 @@ msgid "" " }\n" "}\n" msgstr "" +"assetManager->register(ChartWidgetAsset::class);\n" +" \n" +" // Renderiza o conteúdo do widget\n" +" return $this->renderChart();\n" +" }\n" +"}\n" #. type: Title ## #: ../src/guide/views/widget.md #, no-wrap msgid "Using Widgets in Layouts" -msgstr "" +msgstr "Usando widgets em layouts" #. type: Plain text #: ../src/guide/views/widget.md msgid "Widgets are particularly useful in layouts for common UI elements:" -msgstr "" +msgstr "Os widgets são especialmente úteis em layouts, para elementos de interface comuns:" #. type: Plain text #: ../src/guide/views/widget.md #, no-wrap msgid "**views/layout/main.php**\n" -msgstr "" +msgstr "**views/layout/main.php**\n" #. type: Fenced code block (php) #: ../src/guide/views/widget.md @@ -891,23 +1378,56 @@ msgid "" "\n" "\n" msgstr "" +"\n" +"\n" +"\n" +"\n" +" \n" +"\n" +"\n" +"
\n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +"
\n" +"\n" +"\n" #. type: Title ## #: ../src/guide/views/widget.md #, no-wrap msgid "Testing Widgets" -msgstr "" +msgstr "Testando widgets" #. type: Title ### #: ../src/guide/views/widget.md #, no-wrap msgid "Unit Testing" -msgstr "" +msgstr "Testes unitários" #. type: Plain text #: ../src/guide/views/widget.md msgid "Test widget rendering logic:" -msgstr "" +msgstr "Teste a lógica de renderização do widget:" #. type: Fenced code block (php) #: ../src/guide/views/widget.md @@ -945,18 +1465,49 @@ msgid "" " }\n" "}\n" msgstr "" +"message('Test message')\n" +" ->type('success');\n" +" \n" +" $output = $widget->render();\n" +" \n" +" $this->assertStringContainsString('Test message', $output);\n" +" $this->assertStringContainsString('alert-success', $output);\n" +" }\n" +" \n" +" public function testRenderEmpty(): void\n" +" {\n" +" $widget = AlertWidget::widget();\n" +" $output = $widget->render();\n" +" \n" +" $this->assertEmpty($output);\n" +" }\n" +"}\n" #. type: Title ## #: ../src/guide/views/widget.md #, no-wrap msgid "Common Widget Patterns" -msgstr "" +msgstr "Padrões comuns de widgets" #. type: Title ### #: ../src/guide/views/widget.md #, no-wrap msgid "Conditional Rendering" -msgstr "" +msgstr "Renderização condicional" #. type: Fenced code block (php) #: ../src/guide/views/widget.md @@ -976,12 +1527,25 @@ msgid "" " return !empty($this->items) && $this->isVisible;\n" "}\n" msgstr "" +"protected function render(): string\n" +"{\n" +" if (!$this->shouldRender()) {\n" +" return '';\n" +" }\n" +" \n" +" return $this->doRender();\n" +"}\n" +"\n" +"private function shouldRender(): bool\n" +"{\n" +" return !empty($this->items) && $this->isVisible;\n" +"}\n" #. type: Title ### #: ../src/guide/views/widget.md #, no-wrap msgid "Template-based Rendering" -msgstr "" +msgstr "Renderização baseada em template" #. type: Fenced code block (php) #: ../src/guide/views/widget.md @@ -1001,12 +1565,25 @@ msgid "" " return $this->viewRenderer->renderPartialAsString($template, $data);\n" "}\n" msgstr "" +"protected function render(): string\n" +"{\n" +" return $this->renderTemplate('widget-template', [\n" +" 'items' => $this->items,\n" +" 'options' => $this->options,\n" +" ]);\n" +"}\n" +"\n" +"private function renderTemplate(string $template, array $data): string\n" +"{\n" +" // Usa um view renderer para renderizar arquivos de template\n" +" return $this->viewRenderer->renderPartialAsString($template, $data);\n" +"}\n" #. type: Title ### #: ../src/guide/views/widget.md #, no-wrap msgid "Event Integration" -msgstr "" +msgstr "Integração com eventos" #. type: Fenced code block (php) #: ../src/guide/views/widget.md @@ -1025,8 +1602,20 @@ msgid "" " return $afterEvent->getContent();\n" "}\n" msgstr "" +"protected function render(): string\n" +"{\n" +" $event = new BeforeWidgetRender($this);\n" +" $this->eventDispatcher->dispatch($event);\n" +" \n" +" $content = $this->doRender();\n" +" \n" +" $afterEvent = new AfterWidgetRender($this, $content);\n" +" $this->eventDispatcher->dispatch($afterEvent);\n" +" \n" +" return $afterEvent->getContent();\n" +"}\n" #. type: Plain text #: ../src/guide/views/widget.md msgid "Widgets provide a powerful way to create reusable, configurable UI components in Yii3 applications. They help maintain clean separation of concerns and make your views more maintainable and testable." -msgstr "" +msgstr "Os widgets oferecem uma forma eficaz de criar componentes de interface reutilizáveis e configuráveis em aplicações Yii3. Eles ajudam a manter uma separação clara de responsabilidades e deixam suas views mais fáceis de manter e testar." diff --git a/src/pt-BR/guide/glossary.md b/src/pt-BR/guide/glossary.md index bbf357a0..21f0518e 100644 --- a/src/pt-BR/guide/glossary.md +++ b/src/pt-BR/guide/glossary.md @@ -2,253 +2,268 @@ ## action -Action is a callable, class, or class method that handles a matched route -and returns a response. Read more in ["Actions"](structure/action.md). +Action é um callable, uma classe ou um método de classe que trata uma rota +correspondida e retorna uma resposta. Leia mais em +["Actions"](structure/action.md). ## alias -Alias is a string used by Yii to refer to the class or directory such as -`@app/vendor`. Read more in ["Aliases"](concept/aliases.md). +Alias é uma string usada pelo Yii para se referir a uma classe ou a um +diretório, como `@app/vendor`. Leia mais em +["Aliases"](concept/aliases.md). -## application +## aplicação -Application is an object that starts up, handles a request through -configured middleware, and shuts down. Read more in -["Application"](structure/application.md). +A aplicação é um objeto que inicializa, trata uma requisição passando pelos +middlewares configurados e encerra. Leia mais em +["Aplicação"](structure/application.md). ## asset -Asset refers to a resource file. Typically, it contains JavaScript or CSS -code but can be any static content accessed via HTTP. Read more in +Asset é um arquivo de recurso. Normalmente contém código JavaScript ou CSS, +mas pode ser qualquer conteúdo estático acessado via HTTP. Leia mais em ["Assets"](views/asset.md). ## asset bundle -Asset bundle is a PHP class that declares a group of CSS, JavaScript, image, -or font files that should be published and registered together. Read more -in ["Asset Bundles"](views/asset.md#asset-bundles). +Asset bundle é uma classe PHP que declara um grupo de arquivos CSS, +JavaScript, imagens ou fontes que devem ser publicados e registrados +juntos. Leia mais em ["Asset bundles"](views/asset.md#asset-bundles). -## authentication +## autenticação -Authentication is the process of determining the identity of the current -user. Read more in ["Authentication"](security/authentication.md). +Autenticação é o processo de determinar a identidade do usuário atual. Leia +mais em ["Autenticação"](security/authentication.md). -## authorization +## autorização -Authorization is the process of checking whether an authenticated or -anonymous user is allowed to perform an action. Read more in -["Authorization"](security/authorization.md). +Autorização é o processo de verificar se um usuário autenticado ou anônimo +tem permissão para realizar uma ação. Leia mais em +["Autorização"](security/authorization.md). ## autoloading -Autoloading is the process of loading PHP classes automatically when they -are first used. Read more in ["Class autoloading"](concept/autoloading.md). +Autoloading é o processo de carregar classes PHP automaticamente quando elas +são usadas pela primeira vez. Leia mais em ["Autoloading de +classes"](concept/autoloading.md). # B ## bootstrap -Bootstrap is application startup code that prepares services, configuration, -and runtime state before request handling. Read more in -["Configuration"](concept/configuration.md). +Bootstrap é o código de inicialização da aplicação que prepara serviços, +configuração e estado de execução antes do tratamento da requisição. Leia +mais em ["Configuração"](concept/configuration.md). # C -## configuration +## configuração -Configuration may refer either to the process of setting properties of an -object or to a configuration file that stores settings for an object, or a -class of objects. Read more in ["Configuration"](concept/configuration.md). +Configuração pode se referir tanto ao processo de definir propriedades de um +objeto quanto a um arquivo de configuração que guarda definições para um +objeto ou uma classe de objetos. Leia mais em +["Configuração"](concept/configuration.md). ## container -Container is an object that creates services, resolves their dependencies, -and returns configured instances. Read more in ["DI -container"](concept/di-container.md#di-container). +Container é um objeto que cria serviços, resolve suas dependências e retorna +instâncias configuradas. Leia mais em ["Container de +DI"](concept/di-container.md#container-de-di). ## controller -Controller is a class that groups action methods for related routes. Read -more in ["Actions"](structure/action.md). +Controller é uma classe que agrupa métodos de action de rotas relacionadas. +Leia mais em ["Actions"](structure/action.md). ## cookie -Cookie is a small piece of data stored by a browser and sent with later -requests to the same site. Read more in ["Cookies"](runtime/cookies.md). +Cookie é um pequeno pedaço de dados guardado pelo navegador e enviado nas +requisições seguintes ao mesmo site. Leia mais em +["Cookies"](runtime/cookies.md). ## CSRF -CSRF means cross-site request forgery, an attack where another site tries to -make a user's browser submit an unwanted request to your application. Read -more in ["Avoiding CSRF"](security/best-practices.md#avoiding-csrf). +CSRF significa cross-site request forgery (falsificação de requisição entre +sites), um ataque em que outro site tenta fazer o navegador de um usuário +enviar uma requisição indesejada para sua aplicação. Leia mais em +["Evitando CSRF"](security/best-practices.md#evitando-csrf). # D ## DI -Dependency injection is a programming technique where an object receives its -dependencies from the outside. Read more in ["Dependency injection and +Injeção de dependência é uma técnica de programação em que um objeto recebe +suas dependências de fora. Leia mais em ["Injeção de dependência e container"](concept/di-container.md). # E -## entry script +## entry script (script de entrada) -Entry script is the first PHP script executed for a web or console -application. Read more in ["Entry scripts"](structure/entry-script.md). +O script de entrada é o primeiro script PHP executado em uma aplicação web +ou de console. Leia mais em ["Scripts de +entrada"](structure/entry-script.md). -## event +## evento -Event is an object that represents something that happened and can be passed -to listeners. Read more in ["Events"](concept/events.md). +Evento é um objeto que representa algo que aconteceu e que pode ser passado +para listeners. Leia mais em ["Eventos"](concept/events.md). # H ## handler -Handler is callable code selected by routing or middleware to process a -request and produce a response. Read more in ["Routing and URL -generation"](runtime/routing.md). +Handler é o código callable escolhido pelo roteamento ou por um middleware +para processar uma requisição e produzir uma resposta. Leia mais em +["Roteamento e geração de URLs"](runtime/routing.md). # I -## installation +## instalação -Installation is a process of preparing something to work either by following -a readme file or by executing a specially prepared script. In the case of -Yii, it's setting permissions and fulfilling software requirements. +Instalação é o processo de preparar algo para funcionar, seja seguindo um +arquivo readme, seja executando um script preparado especialmente para +isso. No caso do Yii, é definir permissões e atender aos requisitos de +software. # L ## layout -Layout is a view template that wraps page-specific content with shared page -structure. Read more in ["Working with -layouts"](views/view.md#working-with-layouts). +Layout é um template de view que envolve o conteúdo específico de uma página +com a estrutura compartilhada da página. Leia mais em ["Trabalhando com +layouts"](views/view.md#trabalhando-com-layouts). # M ## migration -Migration is a versioned PHP class that applies or reverts a database schema -or data change. Read more in ["Migrations"](databases/db-migrations.md). +Migration é uma classe PHP versionada que aplica ou reverte uma mudança no +schema ou nos dados do banco de dados. Leia mais em +["Migrations"](databases/db-migrations.md). ## middleware -Middleware is a processor in the request processing stack. Given a request, -it may either produce a response or do some action and pass processing to -the next middleware. Read more in ["Middleware"](structure/middleware.md). +Middleware é um processador na pilha de processamento da requisição. Dada +uma requisição, ele pode produzir uma resposta ou fazer alguma ação e passar +o processamento para o próximo middleware. Leia mais em +["Middleware"](structure/middleware.md). ## model -Model is an object that represents application data and usually contains -validation or business rules for that data. Read more in ["Working with -forms"](start/forms.md). +Model é um objeto que representa dados da aplicação e normalmente contém +regras de validação ou de negócio para esses dados. Leia mais em +["Trabalhando com formulários"](start/forms.md). -## module +## módulo -The module is a namespace that groups some code based on a use-case. It's -typically used within the main application and may contain any source code, -define additional URL handlers or console commands. +O módulo é um namespace que agrupa código com base em um caso de +uso. Normalmente é usado dentro da aplicação principal e pode conter +qualquer código-fonte, definir handlers de URL adicionais ou comandos de +console. # N ## namespace -Namespace refers to a [PHP language -feature](https://www.php.net/manual/en/language.namespaces.php) to group -multiple classes under a certain name. +Namespace é um [recurso da linguagem +PHP](https://www.php.net/manual/en/language.namespaces.php) para agrupar +várias classes sob um determinado nome. # P -## package +## pacote -A package usually refers to [Composer -package](https://getcomposer.org/doc/). It's code ready for reuse and -redistribution installable automatically via a package manager. +Um pacote normalmente é um [pacote do +Composer](https://getcomposer.org/doc/). É código pronto para reutilização e +redistribuição, que pode ser instalado automaticamente por um gerenciador de +pacotes. -## parameter +## parâmetro -Parameter is a configuration value that can be used by application or -package config files. Read more in -["Parameters"](concept/configuration.md#parameters). +Parâmetro é um valor de configuração que pode ser usado pelos arquivos de +configuração da aplicação ou de pacotes. Leia mais em +["Parâmetros"](concept/configuration.md#parametros). # Q -## queue +## queue (fila) -A queue is a data structure that processes items in first-in, first-out -order. Yii has a [yiisoft/queue](https://github.com/yiisoft/queue) package. +Uma fila é uma estrutura de dados que processa itens na ordem em que +chegaram (primeiro a entrar, primeiro a sair). O Yii tem o pacote +[yiisoft/queue](https://github.com/yiisoft/queue). # R -## request +## requisição -Request is a PSR-7 object that represents an incoming HTTP message, -including method, URI, headers, body, uploaded files, and attributes. Read -more in ["Request"](runtime/request.md). +Requisição é um objeto PSR-7 que representa uma mensagem HTTP recebida, +incluindo método, URI, headers, corpo, arquivos enviados e atributos. Leia +mais em ["Requisição"](runtime/request.md). -## response +## resposta -Response is a PSR-7 object that represents an outgoing HTTP message, -including status code, headers, and body. Read more in -["Response"](runtime/response.md). +Resposta é um objeto PSR-7 que representa uma mensagem HTTP enviada, +incluindo código de status, headers e corpo. Leia mais em +["Resposta"](runtime/response.md). -## route +## rota -Route describes which request method and URL pattern should be handled by -which action or middleware. Read more in ["Routing and URL -generation"](runtime/routing.md). +A rota descreve qual método de requisição e qual padrão de URL devem ser +tratados por qual action ou middleware. Leia mais em ["Roteamento e geração +de URLs"](runtime/routing.md). -## rule +## regra -The rule usually refers to a validation rule of the -[yiisoft/validator](https://github.com/yiisoft/validator) package. It holds -a set of parameters for checking if a data set is valid. "Rule handler" -does the actual processing. +A regra normalmente se refere a uma regra de validação do pacote +[yiisoft/validator](https://github.com/yiisoft/validator). Ela guarda um +conjunto de parâmetros para verificar se um conjunto de dados é válido. O +"rule handler" faz o processamento de fato. # S -## service +## serviço -Service is a focused object that performs application work or provides -infrastructure behavior and is usually stored in the DI container. Read -more in ["Service components"](structure/service.md). +Serviço é um objeto focado que realiza trabalho da aplicação ou fornece +comportamento de infraestrutura e normalmente fica registrado no container +de DI. Leia mais em ["Componentes de serviço"](structure/service.md). -## service provider +## service provider (provedor de serviços) -Service provider is a class that registers related service definitions for -the DI container. Read more in ["Service +Service provider é uma classe que registra definições de serviços +relacionados para o container de DI. Leia mais em ["Service providers"](concept/configuration.md#service-providers). -## session +## sessão -Session is server-side storage associated with a browser across multiple -requests. Read more in ["Sessions"](runtime/sessions.md). +Sessão é um armazenamento no servidor associado a um navegador ao longo de +várias requisições. Leia mais em ["Sessões"](runtime/sessions.md). # T ## template -Template is a file used by a view or template engine to produce presentation -output such as HTML. Read more in ["Views"](views/view.md). +Template é um arquivo usado por uma view ou por um template engine para +produzir a saída de apresentação, como HTML. Leia mais em +["Views"](views/view.md). # V ## vendor -A vendor is an organization or individual developer providing code in the -form of packages. It also may refer to [Composer's `vendor` -directory](https://getcomposer.org/doc/). +Vendor é uma organização ou um desenvolvedor individual que fornece código +na forma de pacotes. Também pode se referir ao [diretório `vendor` do +Composer](https://getcomposer.org/doc/). ## view -View is responsible for presenting data to end users, usually by executing a -template with provided data. Read more in ["Views"](views/view.md). +A view é responsável por apresentar dados aos usuários finais, normalmente +executando um template com os dados fornecidos. Leia mais em +["Views"](views/view.md). # W ## widget -Widget is a reusable view component that renders a piece of user interface. -Read more in ["Widgets"](views/widget.md). +Widget é um componente de view reutilizável que renderiza uma parte da +interface do usuário. Leia mais em ["Widgets"](views/widget.md). diff --git a/src/pt-BR/guide/testing/end-to-end.md b/src/pt-BR/guide/testing/end-to-end.md index 27b33973..4b35ac94 100644 --- a/src/pt-BR/guide/testing/end-to-end.md +++ b/src/pt-BR/guide/testing/end-to-end.md @@ -1,15 +1,15 @@ -# End-to-end tests +# Testes end-to-end -The Yii application template uses the `Web` Codeception suite for tests that -go through an HTTP server. These tests live in `tests/Web` and use +O template de aplicação Yii usa a suíte `Web` do Codeception para testes que +passam por um servidor HTTP. Esses testes ficam em `tests/Web` e usam `App\Tests\Support\WebTester`. -Use web tests for user-visible HTTP behavior: pages, links, forms, -redirects, cookies, and error pages. +Use testes web para o comportamento HTTP visível ao usuário: páginas, links, +formulários, redirecionamentos, cookies e páginas de erro. -## Web suite +## Suíte Web -The template configures `tests/Web.suite.yml` like this: +O template configura `tests/Web.suite.yml` assim: ```yaml actor: WebTester @@ -24,12 +24,12 @@ modules: url: http://127.0.0.1:8080 ``` -`RunProcess` starts the application with the Composer `serve` -script. `PhpBrowser` sends HTTP requests to the server. +`RunProcess` inicia a aplicação com o script `serve` do +Composer. `PhpBrowser` envia requisições HTTP ao servidor. -## Test a page +## Testar uma página -The template includes `tests/Web/HomePageCest.php`: +O template inclui `tests/Web/HomePageCest.php`: ```php /tmp/home.html grep -q "Hello!" /tmp/home.html ``` -## Reset state +## Redefinir o estado -Web tests use real infrastructure, so reset state before each scenario: +Testes web usam infraestrutura real, então redefina o estado antes de cada +cenário: -- Load only the records required by the scenario. -- Clear session and cookie storage. -- Clear generated files and outgoing messages. -- Stop background workers, or make their effects deterministic. +- Carregue apenas os registros exigidos pelo cenário. +- Limpe o armazenamento de sessão e de cookies. +- Limpe arquivos gerados e mensagens de saída. +- Pare os workers em segundo plano ou torne seus efeitos determinísticos. -If the scenario changes a database, reset it in the Cest `_before()` hook or -in a project-specific helper: +Se o cenário altera um banco de dados, redefina-o no hook `_before()` do +Cest ou em um helper específico do projeto: ```php public function _before(WebTester $I): void { - // Reset database tables, files, queues, and outgoing messages. + // Redefina tabelas do banco de dados, arquivos, filas e mensagens de saída. } ``` diff --git a/src/pt-BR/guide/testing/environment-setup.md b/src/pt-BR/guide/testing/environment-setup.md index d96e4e1e..b510a747 100644 --- a/src/pt-BR/guide/testing/environment-setup.md +++ b/src/pt-BR/guide/testing/environment-setup.md @@ -1,13 +1,12 @@ -# Testing environment setup +# Configuração do ambiente de testes -The Yii application template has the test environment configured. Use this -page when creating a new project from the template, restoring removed test -files, or adding a new suite. +O template de aplicação Yii já vem com o ambiente de testes configurado. Use +esta página ao criar um novo projeto a partir do template, restaurar +arquivos de teste removidos ou adicionar uma nova suíte. -## Composer configuration +## Configuração do Composer -The template requires Codeception, PHPUnit, and the modules used by the -suites: +O template exige o Codeception, o PHPUnit e os módulos usados pelas suítes: ```json { @@ -29,13 +28,13 @@ suites: } ``` -If these entries are already in your project, keep the installed versions -from `composer.lock`. +Se essas entradas já estiverem no seu projeto, mantenha as versões +instaladas do `composer.lock`. -## Main Codeception file +## Arquivo principal do Codeception -The root `codeception.yml` defines the test namespace, paths, bootstrap -file, and coverage source: +O `codeception.yml` na raiz define o namespace dos testes, os caminhos, o +arquivo de bootstrap e a origem da cobertura: ```yaml namespace: App\Tests @@ -66,7 +65,7 @@ extensions: - Codeception\Extension\RunFailed ``` -`tests/bootstrap.php` prepares the application environment for every suite: +`tests/bootstrap.php` prepara o ambiente da aplicação para todas as suítes: ```php getStatusCode()); assertSame('/contact/sent', $response->getHeaderLine('Location')); ``` -For JSON APIs, write the JSON body into a PSR-7 stream and set +Para APIs JSON, escreva o corpo JSON em um stream PSR-7 e defina `Content-Type: application/json`. -## Reset state +## Redefinir o estado -Functional tests often touch runtime files, sessions, cache, and a -database. Reset changed state in the Cest `_before()` hook or in a project -helper: +Testes funcionais costumam mexer em arquivos de runtime, sessões, cache e +banco de dados. Redefina o estado alterado no hook `_before()` do Cest ou em +um helper do projeto: ```php public function _before(FunctionalTester $tester): void { - // Reset database tables, cache pools, queues, and outgoing messages. + // Redefina tabelas do banco de dados, pools de cache, filas e mensagens de saída. } ``` -Keep pure domain rules in unit tests. Put request and response behavior in -functional tests. +Mantenha as regras de domínio puras nos testes unitários. Coloque o +comportamento de requisição e resposta nos testes funcionais. diff --git a/src/pt-BR/guide/testing/overview.md b/src/pt-BR/guide/testing/overview.md index 88990cff..d4f71f66 100644 --- a/src/pt-BR/guide/testing/overview.md +++ b/src/pt-BR/guide/testing/overview.md @@ -1,14 +1,14 @@ # Testes -The Yii application template includes a ready test setup. It uses -Codeception with PHPUnit assertions and has four suites: +O template de aplicação Yii inclui uma configuração de testes pronta. Ele +usa o Codeception com asserções do PHPUnit e tem quatro suítes: -- `Unit` for isolated PHP classes. -- `Functional` for application code called in the same PHP process. -- `Web` for requests sent through an HTTP server. -- `Console` for console commands. +- `Unit` para classes PHP isoladas. +- `Functional` para código da aplicação chamado no mesmo processo PHP. +- `Web` para requisições enviadas por um servidor HTTP. +- `Console` para comandos de console. -The main files are: +Os arquivos principais são: - `codeception.yml`. - `tests/bootstrap.php`. @@ -18,27 +18,28 @@ The main files are: - `tests/Console.suite.yml`. - `tests/Support/*Tester.php`. -## Run tests locally +## Executar testes localmente -Build actor classes after installing dependencies or changing a suite: +Gere as classes de actor depois de instalar as dependências ou alterar uma +suíte: ```shell vendor/bin/codecept build ``` -Run all tests: +Execute todos os testes: ```shell APP_ENV=test vendor/bin/codecept run ``` -The template also defines a Composer script: +O template também define um script do Composer: ```shell APP_ENV=test composer test ``` -Run one suite: +Execute uma suíte: ```shell APP_ENV=test vendor/bin/codecept run Unit @@ -47,31 +48,32 @@ APP_ENV=test vendor/bin/codecept run Web APP_ENV=test vendor/bin/codecept run Console ``` -Run one test class or method: +Execute uma classe ou um método de teste: ```shell APP_ENV=test vendor/bin/codecept run Functional HomePageCest APP_ENV=test vendor/bin/codecept run Functional HomePageCest:base ``` -`APP_ENV=test` is required for local commands because `tests/bootstrap.php` -prepares the application environment before tests run. +`APP_ENV=test` é obrigatório nos comandos locais porque +`tests/bootstrap.php` prepara o ambiente da aplicação antes da execução dos +testes. -## Run tests in Docker +## Executar testes no Docker -Build actor classes: +Gere as classes de actor: ```shell make codecept build ``` -Run all tests: +Execute todos os testes: ```shell make test ``` -Run one suite: +Execute uma suíte: ```shell make test Unit @@ -80,20 +82,24 @@ make test Web make test Console ``` -The Docker test environment reads `docker/test/.env`, where `APP_ENV=test` -is already set. +O ambiente de testes do Docker lê `docker/test/.env`, onde `APP_ENV=test` já +está definido. -## Choose a suite +## Escolher uma suíte -Start with unit tests for code that has no framework boundary: value -objects, validators, domain services, and transformers. +Comece com testes unitários para código que não tem fronteira com o +framework: value objects, validadores, serviços de domínio e +transformadores. -Use functional tests when code needs Yii configuration, dependency -injection, routing, middleware, request handling, or template rendering. +Use testes funcionais quando o código precisa da configuração do Yii, +injeção de dependência, roteamento, middlewares, tratamento de requisições +ou renderização de templates. -Use web tests for behavior that must go through an HTTP server: status -codes, links, redirects, cookies, and rendered pages as seen by a client. +Use testes web para comportamentos que precisam passar por um servidor HTTP: +códigos de status, links, redirecionamentos, cookies e páginas renderizadas +como o cliente as vê. -Use console tests for commands in `src/Console`. +Use testes de console para os comandos em `src/Console`. -Run static analysis in CI and before changing shared contracts. +Execute a análise estática no CI e antes de alterar contratos +compartilhados. diff --git a/src/pt-BR/guide/testing/quality-tools.md b/src/pt-BR/guide/testing/quality-tools.md index b6882172..f110a7a7 100644 --- a/src/pt-BR/guide/testing/quality-tools.md +++ b/src/pt-BR/guide/testing/quality-tools.md @@ -1,95 +1,98 @@ -# Static analysis and code quality +# Análise estática e qualidade de código -The Yii application template includes static analysis and code quality tools -alongside the test suite. +O template de aplicação Yii inclui ferramentas de análise estática e de +qualidade de código junto com a suíte de testes. ## Psalm -Run Psalm locally: +Execute o Psalm localmente: ```shell vendor/bin/psalm ``` -Run Psalm in Docker: +Execute o Psalm no Docker: ```shell make psalm ``` -The template stores Psalm configuration in `psalm.xml`. The GitHub Actions -workflow runs Psalm for supported PHP versions. +O template guarda a configuração do Psalm em `psalm.xml`. O workflow do +GitHub Actions executa o Psalm nas versões de PHP suportadas. -When Psalm reports an issue, fix the code or add a precise type -annotation. Keep suppressions narrow and local to the line or method that -needs them. +Quando o Psalm reportar um problema, corrija o código ou adicione uma +anotação de tipo precisa. Mantenha as supressões restritas e locais à linha +ou ao método que precisa delas. ## Composer Dependency Analyser -Composer Dependency Analyser checks that `composer.json` matches the classes -used by the application. +O Composer Dependency Analyser verifica se o `composer.json` corresponde às +classes usadas pela aplicação. -Run it locally: +Execute-o localmente: ```shell vendor/bin/composer-dependency-analyser --config=composer-dependency-analyser.php ``` -Run it in Docker: +Execute-o no Docker: ```shell make composer-dependency-analyser ``` -Use this check after adding or removing package usage in `src`, `config`, or -`tests`. +Use essa verificação depois de adicionar ou remover o uso de pacotes em +`src`, `config` ou `tests`. ## PHP CS Fixer -PHP CS Fixer applies the project coding style from `.php-cs-fixer.php`. +O PHP CS Fixer aplica o estilo de código do projeto definido em +`.php-cs-fixer.php`. -Run it locally: +Execute-o localmente: ```shell vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.php --diff ``` -Run it in Docker: +Execute-o no Docker: ```shell make cs-fix ``` -Commit formatting changes together with the code that needs them. +Faça o commit das mudanças de formatação junto com o código que as exige. ## Rector -Rector applies configured code upgrades and refactorings from `rector.php`. +O Rector aplica as atualizações e refatorações de código configuradas em +`rector.php`. -Preview changes locally: +Visualize as mudanças localmente: ```shell vendor/bin/rector --dry-run ``` -Apply changes locally: +Aplique as mudanças localmente: ```shell vendor/bin/rector ``` -Run it in Docker: +Execute-o no Docker: ```shell make rector ``` -Review Rector changes before committing them. Automated refactoring can -change behavior when custom rules or broad paths are configured. +Revise as mudanças do Rector antes de fazer o commit. A refatoração +automatizada pode alterar o comportamento quando regras personalizadas ou +caminhos amplos estão configurados. -## Pull request checks +## Verificações de pull request -A practical local check before opening a pull request is: +Uma verificação local prática antes de abrir um pull request é: ```shell APP_ENV=test vendor/bin/codecept build @@ -99,7 +102,7 @@ vendor/bin/composer-dependency-analyser --config=composer-dependency-analyser.ph vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.php --diff ``` -With Docker: +Com Docker: ```shell make codecept build diff --git a/src/pt-BR/guide/testing/unit.md b/src/pt-BR/guide/testing/unit.md index 7c0b2bcb..18c9705e 100644 --- a/src/pt-BR/guide/testing/unit.md +++ b/src/pt-BR/guide/testing/unit.md @@ -1,10 +1,10 @@ -# Unit tests +# Testes unitários -Unit tests check a small piece of PHP code directly. In the Yii application -template they live in `tests/Unit` and run through the `Unit` Codeception -suite. +Testes unitários verificam diretamente um pequeno trecho de código PHP. No +template de aplicação Yii eles ficam em `tests/Unit` e são executados pela +suíte `Unit` do Codeception. -The template includes `tests/Unit/EnvironmentTest.php`: +O template inclui `tests/Unit/EnvironmentTest.php`: ```php [!NOTE] -> `phpdotenv` is a development dependency and is not installed in production -> (`composer install --no-dev`), so the root `.env` file has no effect on production containers. +> `phpdotenv` é uma dependência de desenvolvimento e não é instalado em produção +> (`composer install --no-dev`), então o arquivo `.env` da raiz não tem efeito nos containers de produção. ### docker/.env -This file contains variables used by the Compose files themselves — they are -**not** passed into the running application container: +Este arquivo contém variáveis usadas pelos próprios arquivos Compose — elas +**não** são repassadas ao container da aplicação em execução: ```ini -# Variables for compose.yml files. Not available in the app. +# Variáveis para os arquivos compose.yml. Não disponíveis na aplicação. STACK_NAME=app -# Development +# Desenvolvimento DEV_PORT=80 -# Production +# Produção PROD_HOST=app.example.com PROD_SSH="ssh://docker-web" @@ -93,23 +95,23 @@ IMAGE=app IMAGE_TAG=latest ``` -| Variable | Purpose | +| Variável | Finalidade | |--------------|-------------------------------------------------------------------------| -| `STACK_NAME` | Docker Compose project name and Docker Swarm stack name. | -| `DEV_PORT` | Host port to expose the application on in development (`make up`). | -| `PROD_HOST` | Hostname used by Caddy labels for automatic HTTPS in production. | -| `PROD_SSH` | Remote Docker host for deploying to a Swarm node via SSH. | -| `IMAGE` | Docker image name used during build and push. | -| `IMAGE_TAG` | Docker image tag (`latest` by default; use a version string in CI/CD). | +| `STACK_NAME` | Nome do projeto Docker Compose e nome da stack do Docker Swarm. | +| `DEV_PORT` | Porta do host onde a aplicação é exposta em desenvolvimento (`make up`). | +| `PROD_HOST` | Hostname usado pelos labels do Caddy para HTTPS automático em produção. | +| `PROD_SSH` | Host Docker remoto para deploy em um nó Swarm via SSH. | +| `IMAGE` | Nome da imagem Docker usada no build e no push. | +| `IMAGE_TAG` | Tag da imagem Docker (`latest` por padrão; use uma versão no CI/CD). | ### docker/dev/.env -Contains application environment variables injected into the development -container at runtime: +Contém as variáveis de ambiente da aplicação injetadas no container de +desenvolvimento em tempo de execução: ```ini -# App dev environment. -# Note that variables are available in the app only, not in compose.yml. +# Ambiente dev da aplicação. +# Note que as variáveis ficam disponíveis apenas na aplicação, não no compose.yml. APP_ENV=dev APP_DEBUG=true @@ -118,21 +120,21 @@ XDEBUG_MODE=develop COMPOSER_CACHE_DIR=/app/runtime/cache/composer ``` -| Variable | Purpose | +| Variável | Finalidade | |-----------------------|--------------------------------------------------------------------------------------| -| `APP_ENV` | Application environment. `dev` enables developer-friendly behavior. | -| `APP_DEBUG` | Enables detailed error output and debug panels. | -| `SERVER_NAME` | Caddy server address — `:80` means listen on all interfaces on port 80. | -| `XDEBUG_MODE` | Xdebug mode. Use `develop` for helpers and `debug` to enable step debugging. | -| `COMPOSER_CACHE_DIR` | Moves Composer's cache into the mounted volume so it persists between runs. | +| `APP_ENV` | Ambiente da aplicação. `dev` ativa um comportamento amigável para o desenvolvedor. | +| `APP_DEBUG` | Ativa saída de erros detalhada e painéis de debug. | +| `SERVER_NAME` | Endereço do servidor Caddy — `:80` significa escutar em todas as interfaces na porta 80. | +| `XDEBUG_MODE` | Modo do Xdebug. Use `develop` para helpers e `debug` para ativar a depuração passo a passo. | +| `COMPOSER_CACHE_DIR` | Move o cache do Composer para o volume montado, para que persista entre execuções. | ### docker/test/.env -Contains application environment variables for the test container: +Contém as variáveis de ambiente da aplicação para o container de testes: ```ini -# App test environment. -# Note that variables are available in the app only, not in compose.yml. +# Ambiente test da aplicação. +# Note que as variáveis ficam disponíveis apenas na aplicação, não no compose.yml. APP_ENV=test APP_DEBUG=false @@ -142,61 +144,63 @@ XDEBUG_MODE=coverage COMPOSER_CACHE_DIR=/app/runtime/cache/composer ``` -| Variable | Purpose | +| Variável | Finalidade | |----------------------|-----------------------------------------------------------------------------------------------| -| `APP_ENV` | Sets the environment to `test` so the application loads test-specific configuration. | -| `APP_DEBUG` | Disabled in tests to match a realistic execution context. | -| `APP_C3` | Enables [c3](https://github.com/Codeception/c3) remote code coverage collection. | -| `SERVER_NAME` | Caddy server address. | -| `XDEBUG_MODE` | `coverage` activates Xdebug's code coverage driver required for coverage reports. | -| `COMPOSER_CACHE_DIR` | Persistent Composer cache inside the volume. | +| `APP_ENV` | Define o ambiente como `test` para que a aplicação carregue a configuração específica de testes. | +| `APP_DEBUG` | Desativado nos testes para corresponder a um contexto de execução realista. | +| `APP_C3` | Ativa a coleta remota de cobertura de código com [c3](https://github.com/Codeception/c3). | +| `SERVER_NAME` | Endereço do servidor Caddy. | +| `XDEBUG_MODE` | `coverage` ativa o driver de cobertura de código do Xdebug, necessário para os relatórios de cobertura. | +| `COMPOSER_CACHE_DIR` | Cache persistente do Composer dentro do volume. | ### docker/prod/.env -Contains application environment variables for the production container: +Contém as variáveis de ambiente da aplicação para o container de produção: ```ini -# App prod environment. -# Note that variables are available in the app only, not in compose.yml. +# Ambiente prod da aplicação. +# Note que as variáveis ficam disponíveis apenas na aplicação, não no compose.yml. APP_ENV=prod APP_DEBUG=false SERVER_NAME=:80 ``` -The production environment intentionally uses a minimal -configuration. Secrets and host-specific overrides should be managed through -deployment tooling and never committed to version control. +O ambiente de produção usa intencionalmente uma configuração +mínima. Segredos e overrides específicos de host devem ser gerenciados pelas +ferramentas de deploy e nunca commitados no controle de versão. -### Override env files +### Arquivos env de override -Each environment directory contains a `.gitignore` that excludes an -`override.env` file. This file is optional and, when present, is merged on -top of the main `.env` for that environment: +Cada diretório de ambiente contém um `.gitignore` que exclui um arquivo +`override.env`. Esse arquivo é opcional e, quando presente, é mesclado por +cima do `.env` principal daquele ambiente: ``` # docker/dev/override.env.example APP_HOST_PATH=/projects/yiisoft/app ``` -Copy the example file to create your local overrides: +Copie o arquivo de exemplo para criar seus overrides locais: ```sh cp docker/dev/override.env.example docker/dev/override.env ``` -Use override files for developer-specific settings such as Xdebug IDE keys -or local bind paths that should not be shared with the team. +Use arquivos de override para configurações específicas do desenvolvedor, +como chaves de IDE do Xdebug ou caminhos locais de bind, que não devem ser +compartilhados com o time. -## Compose files +## Arquivos Compose -The Compose configuration is split across multiple files that Docker Compose -merges at runtime. This approach avoids duplicating shared settings and -keeps each environment's file focused and small. +A configuração do Compose é dividida em vários arquivos que o Docker Compose +mescla em tempo de execução. Essa abordagem evita duplicar configurações +compartilhadas e mantém o arquivo de cada ambiente pequeno e focado. ### docker/compose.yml (base) -The base file defines shared settings inherited by all environments: +O arquivo base define configurações compartilhadas herdadas por todos os +ambientes: ```yaml services: @@ -209,17 +213,18 @@ volumes: caddy_config: ``` -The `&appconfig` YAML anchor lets environment files reference and extend -this service definition. The `host.docker.internal` entry maps to the -Docker host so containers can reach services running on the host machine -(for example, a local database). +A âncora YAML `&appconfig` permite que os arquivos de ambiente referenciem e +estendam essa definição de serviço. A entrada `host.docker.internal` aponta +para o host Docker, para que os containers alcancem serviços rodando na +máquina host (por exemplo, um banco de dados local). -The two named volumes (`caddy_data` and `caddy_config`) persist Caddy's -certificate storage and configuration across container restarts. +Os dois volumes nomeados (`caddy_data` e `caddy_config`) persistem o +armazenamento de certificados e a configuração do Caddy entre +reinicializações do container. ### docker/dev/compose.yml -Extends the base file for local development: +Estende o arquivo base para desenvolvimento local: ```yaml services: @@ -245,28 +250,27 @@ services: tty: true ``` -Key points: +Pontos principais: -- **`target: dev`** — Selects the `dev` stage from the multi-stage - Dockerfile. -- **`USER_ID` / `GROUP_ID`** — Passed as build arguments so the container - user matches the host user, preventing file permission issues on Linux. -- **`env_file`** — Loads `docker/dev/.env` and, optionally, the developer's - local `override.env`. -- **`ports`** — Exposes port 80 (or `DEV_PORT` from `docker/.env`) on the - host. -- **`volumes`** — Mounts the entire project into `/app` so code changes are - reflected immediately without rebuilding the image. +- **`target: dev`** — Seleciona o estágio `dev` do Dockerfile multi-stage. +- **`USER_ID` / `GROUP_ID`** — Passados como argumentos de build para que o + usuário do container corresponda ao usuário do host, evitando problemas de + permissão de arquivos no Linux. +- **`env_file`** — Carrega `docker/dev/.env` e, opcionalmente, o + `override.env` local do desenvolvedor. +- **`ports`** — Expõe a porta 80 (ou `DEV_PORT` de `docker/.env`) no host. +- **`volumes`** — Monta o projeto inteiro em `/app` para que mudanças no + código sejam refletidas imediatamente, sem rebuild da imagem. ### docker/test/compose.yml -Identical in structure to the dev file but loads `docker/test/.env` and does -not expose ports to the host, since tests run entirely inside the container -network. +Tem a mesma estrutura do arquivo dev, mas carrega `docker/test/.env` e não +expõe portas para o host, já que os testes rodam inteiramente dentro da rede +de containers. ### docker/prod/compose.yml -Targets production deployments using Docker Swarm: +Voltado a deploys em produção usando Docker Swarm: ```yaml services: @@ -310,23 +314,24 @@ networks: external: true ``` -Instead of building an image, the production file references a pre-built -image (`${IMAGE}:${IMAGE_TAG}`). The `deploy` block configures Docker Swarm -behaviour: two replicas with a rolling `start-first` update strategy and -automatic rollback on failure. The `caddy` labels are picked up by a [Caddy -Docker Proxy](https://github.com/lucaslorentz/caddy-docker-proxy) running in -the same Swarm to configure automatic HTTPS routing. +Em vez de fazer build de uma imagem, o arquivo de produção referencia uma +imagem pré-construída (`${IMAGE}:${IMAGE_TAG}`). O bloco `deploy` configura +o comportamento do Docker Swarm: duas réplicas com estratégia de atualização +gradual `start-first` e rollback automático em caso de falha. Os labels +`caddy` são lidos por um [Caddy Docker +Proxy](https://github.com/lucaslorentz/caddy-docker-proxy) rodando no mesmo +Swarm para configurar o roteamento HTTPS automático. > [!NOTE] -> The `caddy_public` network must already exist on the Swarm before deploying. -> See the [Docker Swarm deployment guide](../../cookbook/deployment/docker-swarm.md) for full setup instructions. +> A rede `caddy_public` precisa existir no Swarm antes do deploy. +> Veja o [guia de deploy com Docker Swarm](../../cookbook/deployment/docker-swarm.md) para instruções completas de configuração. -## Multi-stage Dockerfile +## Dockerfile multi-stage -The `docker/Dockerfile` uses [multi-stage -builds](https://docs.docker.com/build/building/multi-stage/) to produce lean -images for each purpose from a single file, avoiding duplication of the base -setup: +O `docker/Dockerfile` usa [builds +multi-stage](https://docs.docker.com/build/building/multi-stage/) para +produzir imagens enxutas para cada finalidade a partir de um único arquivo, +evitando duplicar a configuração base: ```dockerfile FROM composer/composer:2-bin AS composer @@ -380,77 +385,77 @@ COPY --from=prod-builder --chown=www-data:www-data /app /app USER www-data ``` -The Dockerfile defines four stages: +O Dockerfile define quatro estágios: -| Stage | Purpose | +| Estágio | Finalidade | |----------------|--------------------------------------------------------------------------------------------------| -| `composer` | Copies the Composer binary from the official image to avoid installing it in other stages. | -| `base` | Installs FrankenPHP, common PHP extensions, and system packages shared by all environments. | -| `dev` | Extends `base` with Xdebug and Composer. Creates a non-root user matching the host user's UID/GID to prevent permission issues with mounted volumes. | -| `prod-builder` | Extends `base`, copies the application source, and runs `composer install --no-dev` using a build cache. Removes `composer.lock` and `composer.json` afterwards to keep the final image clean. | -| `prod` | Copies only the built application from `prod-builder` into a clean `base` image. This produces a small final image because the Composer binary and intermediate files are not included. | +| `composer` | Copia o binário do Composer da imagem oficial para evitar instalá-lo nos outros estágios. | +| `base` | Instala o FrankenPHP, extensões PHP comuns e pacotes de sistema compartilhados por todos os ambientes. | +| `dev` | Estende `base` com Xdebug e Composer. Cria um usuário não root com o mesmo UID/GID do usuário do host para evitar problemas de permissão com volumes montados. | +| `prod-builder` | Estende `base`, copia o código-fonte da aplicação e executa `composer install --no-dev` usando um cache de build. Remove `composer.lock` e `composer.json` em seguida para manter a imagem final limpa. | +| `prod` | Copia apenas a aplicação construída de `prod-builder` para uma imagem `base` limpa. Isso gera uma imagem final pequena, porque o binário do Composer e os arquivos intermediários não são incluídos. | > [!TIP] -> When building the production image you select a specific stage with `--target prod`. The `prod-builder` -> stage is an intermediate step and is never pushed to a registry. +> Ao construir a imagem de produção, você seleciona um estágio específico com `--target prod`. O estágio `prod-builder` +> é um passo intermediário e nunca é enviado para um registry. -The `dev` target is selected when running `make up` or `make build`, while -`make prod-build` targets `prod`. +O alvo `dev` é selecionado ao executar `make up` ou `make build`, enquanto +`make prod-build` usa o alvo `prod`. -## make commands +## Comandos make -The `Makefile` provides a convenient interface for all common Docker -operations. Run `make` or `make help` to list available targets with their -descriptions. +O `Makefile` oferece uma interface prática para todas as operações Docker +comuns. Execute `make` ou `make help` para listar os alvos disponíveis com +suas descrições. -### Development +### Desenvolvimento -| Command | Description | +| Comando | Descrição | |---------------|----------------------------------------------------------------| -| `make build` | Build (or rebuild) the development Docker image. | -| `make up` | Start the development environment in detached mode. | -| `make down` | Stop and remove containers, networks, and orphaned services. | -| `make stop` | Stop running containers without removing them. | -| `make clear` | Remove all development containers, networks, and volumes. | -| `make shell` | Open an interactive Bash shell inside the running `app` container. | +| `make build` | Faz o build (ou rebuild) da imagem Docker de desenvolvimento. | +| `make up` | Inicia o ambiente de desenvolvimento em modo detached. | +| `make down` | Para e remove containers, redes e serviços órfãos. | +| `make stop` | Para os containers em execução sem removê-los. | +| `make clear` | Remove todos os containers, redes e volumes de desenvolvimento. | +| `make shell` | Abre um shell Bash interativo dentro do container `app` em execução. | -### Running tools +### Executando ferramentas -Commands in this group run inside the development container using `docker -compose run --rm`, so they work even when the container is not currently -running: +Os comandos deste grupo rodam dentro do container de desenvolvimento usando +`docker compose run --rm`, então funcionam mesmo quando o container não está +em execução: -| Command | Description | +| Comando | Descrição | |--------------------------------------|-------------------------------------------------| -| `make yii ` | Run a `./yii` console command. | -| `make composer ` | Run Composer. | -| `make rector` | Run [Rector](https://getrector.com/) for automated PHP refactoring and code quality improvements. | -| `make cs-fix` | Run [PHP CS Fixer](https://cs.symfony.com/). | -| `make psalm` | Run [Psalm](https://psalm.dev/) static analysis. | -| `make composer-dependency-analyser` | Run [Composer Dependency Analyser](https://github.com/shipmonk-rnd/composer-dependency-analyser). | +| `make yii ` | Executa um comando de console `./yii`. | +| `make composer ` | Executa o Composer. | +| `make rector` | Executa o [Rector](https://getrector.com/) para refatoração automatizada de PHP e melhorias de qualidade de código. | +| `make cs-fix` | Executa o [PHP CS Fixer](https://cs.symfony.com/). | +| `make psalm` | Executa a análise estática do [Psalm](https://psalm.dev/). | +| `make composer-dependency-analyser` | Executa o [Composer Dependency Analyser](https://github.com/shipmonk-rnd/composer-dependency-analyser). | ### Testes -| Command | Description | +| Comando | Descrição | |------------------------|-----------------------------------------------------------| -| `make test` | Run the full test suite with Codeception. | -| `make test-coverage` | Run tests and generate an HTML coverage report. | -| `make codecept ` | Run any Codeception command with custom arguments. | +| `make test` | Executa a suíte de testes completa com Codeception. | +| `make test-coverage` | Executa os testes e gera um relatório de cobertura em HTML. | +| `make codecept ` | Executa qualquer comando do Codeception com argumentos personalizados. | -### Production +### Produção -| Command | Description | +| Comando | Descrição | |----------------------|-------------------------------------------------------------------------------------| -| `make prod-build` | Build the production Docker image locally (`--target prod`). | -| `make prod-push` | Push the built image to the registry defined by `IMAGE` and `IMAGE_TAG`. | -| `make prod-deploy` | Deploy the stack to a remote Docker Swarm node defined by `PROD_SSH`. | +| `make prod-build` | Faz o build local da imagem Docker de produção (`--target prod`). | +| `make prod-push` | Envia a imagem construída para o registry definido por `IMAGE` e `IMAGE_TAG`. | +| `make prod-deploy` | Faz o deploy da stack em um nó Docker Swarm remoto definido por `PROD_SSH`. | > [!TIP] -> Most commands accept additional arguments. For example, to install a specific package: +> A maioria dos comandos aceita argumentos adicionais. Por exemplo, para instalar um pacote específico: > ```sh > make composer require yiisoft/yii-db-mysql > ``` -> To run a single test suite: +> Para executar uma única suíte de testes: > ```sh > make test -- Unit > ``` diff --git a/src/pt-BR/guide/tutorial/i18n.md b/src/pt-BR/guide/tutorial/i18n.md index 9d7b4cff..0539a2ab 100644 --- a/src/pt-BR/guide/tutorial/i18n.md +++ b/src/pt-BR/guide/tutorial/i18n.md @@ -1,43 +1,45 @@ -# Internationalization +# Internacionalização -Internationalization prepares an application for more than one -locale. Localization is the locale-specific part: translated text, plural -forms, date and number formats, and view templates for a locale such as -`en-US` or `de`. +A internacionalização prepara uma aplicação para mais de um locale. A +localização é a parte específica de cada locale: textos traduzidos, formas +de plural, formatos de data e número e templates de view para um locale como +`en-US` ou `de`. -In a Yii application, the usual parts are: +Numa aplicação Yii, as partes habituais são: -- locale selection for the current request; -- translated application messages; -- plural and parameter formatting; -- localized view templates for pages that need different markup. +- a escolha do idioma da requisição atual; +- as mensagens traduzidas da aplicação; +- a formatação de plurais e parâmetros; +- templates de view localizados para páginas que precisam de marcação + diferente. -This tutorial assumes a new [yiisoft/app](https://github.com/yiisoft/app) -project. +Este tutorial parte de um projeto novo do +[yiisoft/app](https://github.com/yiisoft/app). -## Install packages +## Instalando os pacotes -`yiisoft/app` already includes `yiisoft/i18n` and `yiisoft/translator`. -Install PHP-file message storage: +O `yiisoft/app` já inclui `yiisoft/i18n` e `yiisoft/translator`. Instale o +armazenamento de mensagens em arquivos PHP: ```sh composer require yiisoft/translator-message-php ``` -Install the extractor as a development dependency: +Instale o extrator como dependência de desenvolvimento: ```sh composer require --dev yiisoft/translator-extractor ``` -The examples use ICU message formatting for plural forms. Make sure the PHP -`intl` extension is enabled. For simple placeholders only, use -`Yiisoft\Translator\SimpleMessageFormatter` in the configuration below. +Os exemplos usam a formatação de mensagens ICU para as formas de +plural. Confira se a extensão `intl` do PHP está habilitada. Se você só +precisa de placeholders simples, use +`Yiisoft\Translator\SimpleMessageFormatter` na configuração abaixo. -## Configure application locale +## Configurando o idioma da aplicação -The application template keeps basic application settings in -`config/common/application.php`. Set the source locale there: +O template da aplicação guarda as configurações básicas em +`config/common/application.php`. Defina ali o idioma de origem: ```php ` attribute through `ApplicationParams`. -When your application chooses locale per request, set the selected locale on the view as shown in -[Choosing locale per request](#choosing-locale-per-request). +O layout padrão usa esse valor no atributo `` por meio de `ApplicationParams`. +Quando a aplicação escolhe o idioma por requisição, defina o idioma escolhido na view, como mostrado em +[Escolhendo o idioma por requisição](#escolhendo-o-idioma-por-requisicao). -Configure translator defaults in `config/common/params.php`: +Configure os padrões do tradutor em `config/common/params.php`: ```php 'yiisoft/translator' => [ @@ -65,13 +67,13 @@ Configure translator defaults in `config/common/params.php`: ], ``` -`locale` is the default translation locale. `fallbackLocale` is used when a -translation is missing for the current locale. `defaultCategory` is the -category used when a call to `translate()` does not specify one. +`locale` é o idioma padrão das traduções. `fallbackLocale` é usado quando +falta uma tradução para o idioma atual. `defaultCategory` é a categoria +usada quando uma chamada a `translate()` não especifica nenhuma. -## Configure message storage +## Configurando o armazenamento de mensagens -Create `config/common/di/translator.php`: +Crie `config/common/di/translator.php`: ```php setTitle($translator->translate('home.title')); ``` -Escape translated text before output. Store trusted HTML separately or -render it from a view template. +Escape o texto traduzido antes de exibi-lo. Guarde HTML confiável +separadamente ou renderize-o a partir de um template de view. -## Choosing locale per request +## Escolhendo o idioma por requisição -For a web application, choose locale early in the middleware stack and apply -it to both the translator and the view. The example below uses the `lang` -query parameter and a fixed allow list: +Numa aplicação web, escolha o idioma cedo na pilha de middlewares e +aplique-o tanto ao tradutor quanto à view. O exemplo abaixo usa o parâmetro +`lang` da query string e uma lista fixa de idiomas permitidos: ```php getLocale()) ?>"> ``` -Use the same approach when locale is stored in a session, a cookie, a user -profile, or a route parameter. +Use a mesma abordagem quando o idioma estiver guardado na sessão, num +cookie, no perfil do usuário ou num parâmetro de rota. -`yiisoft/i18n` provides `Yiisoft\I18n\Locale` for working with BCP 47 locale -codes: +O `yiisoft/i18n` oferece `Yiisoft\I18n\Locale` para trabalhar com códigos de +locale BCP 47: ```php use Yiisoft\I18n\Locale; @@ -295,26 +297,28 @@ echo $locale->region(); // DE echo $locale->fallbackLocale()->asString(); // de ``` -This is useful when you need to derive a language fallback or inspect locale -parts before choosing a supported locale. +Isso é útil quando você precisa derivar um idioma de reserva ou inspecionar +as partes do locale antes de escolher um idioma suportado. -## Localized view files +## Arquivos de view localizados -Use message translation for labels, headings, buttons, validation messages, -and short paragraphs. Use localized view files when a page needs different -markup or a different amount of text for each locale. +Use tradução de mensagens para rótulos, títulos, botões, mensagens de +validação e parágrafos curtos. Use arquivos de view localizados quando uma +página precisa de marcação diferente ou de uma quantidade diferente de texto +para cada idioma. -`yiisoft/view` looks for localized files in a locale subdirectory next to -the original view file. For example, when `src/Web/HomePage/template.php` is -rendered with locale `de-DE`, Yii checks: +O `yiisoft/view` procura arquivos localizados num subdiretório com o nome do +locale, ao lado do arquivo de view original. Por exemplo, quando +`src/Web/HomePage/template.php` é renderizado com o locale `de-DE`, o Yii +verifica: 1. `src/Web/HomePage/de-DE/template.php` 2. `src/Web/HomePage/de/template.php` 3. `src/Web/HomePage/template.php` -The fallback to the two-letter language code is automatic. +O fallback para o código de idioma de duas letras é automático. -You can set the locale for a single render call: +Você pode definir o idioma para uma única chamada de renderização: ```php return $this->viewRenderer @@ -322,15 +326,15 @@ return $this->viewRenderer ->render(__DIR__ . '/template'); ``` -When the locale is set on `WebView` in middleware, the same locale is -applied to views rendered by `WebViewRenderer`. +Quando o idioma é definido no `WebView` dentro de um middleware, o mesmo +idioma é aplicado às views renderizadas pelo `WebViewRenderer`. -## Extract messages +## Extraindo mensagens -Configure the extractor so it can read existing messages and write new IDs -to the same message storage. +Configure o extrator para que ele consiga ler as mensagens existentes e +gravar novos IDs no mesmo armazenamento de mensagens. -Create `config/common/di/translator-extractor.php`: +Crie `config/common/di/translator-extractor.php`: ```php translate('home.welcome'); $translator->translate('cart.items', ['count' => $itemCount]); ``` -It writes missing IDs to: +Ele grava os IDs que faltam em: ``` messages/en-US/app.php messages/de/app.php ``` -After extraction, edit target language files and replace source IDs with -translated text. +Depois da extração, edite os arquivos dos idiomas de destino e troque os IDs +de origem pelo texto traduzido. -Use `--category` when a call belongs to another category: +Use `--category` quando uma chamada pertence a outra categoria: ```sh ./yii translator/extract src --languages=en-US,de --category=shop ``` -The extractor excludes `vendor/` by default. Use `--only` or `--except` when -you need a narrower scan: +O extrator exclui `vendor/` por padrão. Use `--only` ou `--except` quando +precisar de uma varredura mais restrita: ```sh ./yii translator/extract src --languages=en-US,de --only=**/*.php --except=**/runtime/** ``` -## Working with categories +## Trabalhando com categorias -The default `app` category is enough for most application messages. Add -categories when a package or a large feature owns its own message files. +A categoria padrão `app` basta para a maioria das mensagens da +aplicação. Adicione categorias quando um pacote ou um recurso grande tem +seus próprios arquivos de mensagens. -For a `shop` category, create another tagged category source: +Para uma categoria `shop`, crie outro category source com a tag: ```php 'translation.shop' => [ @@ -432,18 +438,18 @@ For a `shop` category, create another tagged category source: ], ``` -Translate with the category name: +Traduza informando o nome da categoria: ```php $translator->translate('checkout.submit', category: 'shop'); ``` -The message files are stored as: +Os arquivos de mensagens ficam assim: ``` messages/de/shop.php messages/en-US/shop.php ``` -Keep message IDs stable. Changing an ID creates a new translation task for -every locale. +Mantenha os IDs de mensagens estáveis. Mudar um ID cria uma nova tarefa de +tradução para cada idioma. diff --git a/src/pt-BR/guide/tutorial/mailing.md b/src/pt-BR/guide/tutorial/mailing.md index e5833e5d..1e80556f 100644 --- a/src/pt-BR/guide/tutorial/mailing.md +++ b/src/pt-BR/guide/tutorial/mailing.md @@ -1,23 +1,23 @@ -# Mailing +# Envio de e-mails -Yii simplifies the composition and sending of email messages using the -[yiisoft/mailer](https://github.com/yiisoft/mailer) package. This package -provides content composition functionality and a basic interface for sending -emails. By default, the package includes a file mailer that writes email -contents into a file instead of sending them. This is particularly useful -during the initial stages of application development. +O Yii simplifica a composição e o envio de e-mails com o pacote +[yiisoft/mailer](https://github.com/yiisoft/mailer). Esse pacote oferece a +composição do conteúdo e uma interface básica para enviar e-mails. Por +padrão, o pacote inclui um mailer de arquivo, que grava o conteúdo dos +e-mails num arquivo em vez de enviá-los. Isso é especialmente útil nas fases +iniciais do desenvolvimento da aplicação. -To send actual emails, you can use the [Symfony -Mailer](https://github.com/yiisoft/mailer-symfony) implementation, which is -used in the examples below. +Para enviar e-mails de verdade, você pode usar a implementação com [Symfony +Mailer](https://github.com/yiisoft/mailer-symfony), que é a usada nos +exemplos abaixo. -## Configuring the Mailer +## Configurando o mailer -The mailer service allows you to create a message instance, populate it with -data, and send it. Typically, you get an instance from the DI container as -`Yiisoft\Mailer\MailerInterface`. +O serviço de mailer permite criar uma instância de mensagem, preenchê-la com +dados e enviá-la. Normalmente, você obtém uma instância do container de DI +como `Yiisoft\Mailer\MailerInterface`. -You can also create an instance manually as follows: +Você também pode criar uma instância manualmente: ```php @@ -32,16 +32,17 @@ $mailer = new \Yiisoft\Mailer\Symfony\Mailer( ); ``` -The `Yiisoft\Mailer\MailerInterface` provides two main methods: +A `Yiisoft\Mailer\MailerInterface` oferece dois métodos principais: -- `send()` - Sends the given email message. -- `sendMultiple()` - Sends many messages at once. +- `send()` - Envia a mensagem de e-mail informada. +- `sendMultiple()` - Envia várias mensagens de uma vez. -## Creating a Message +## Criando uma mensagem -### Simple Text Message +### Mensagem de texto simples -To create a simple message with a text body, use `Yiisoft\Mailer\Message`: +Para criar uma mensagem simples com corpo em texto, use +`Yiisoft\Mailer\Message`: ```php $message = new \Yiisoft\Mailer\Message( @@ -52,7 +53,7 @@ $message = new \Yiisoft\Mailer\Message( ); ``` -### Simple HTML Message +### Mensagem HTML simples ```php $message = new \Yiisoft\Mailer\Message( @@ -63,9 +64,9 @@ $message = new \Yiisoft\Mailer\Message( ); ``` -### HTML Message from template +### Mensagem HTML a partir de um template -For this example, we will use package rendering package +Neste exemplo, vamos usar o pacote de renderização [view](https://github.com/yiisoft/view). ```php @@ -86,9 +87,10 @@ $message = new \Yiisoft\Mailer\Message( ); ``` -### Using Layouts +### Usando layouts -You can also pass parameters to layouts from your template message: +Você também pode passar parâmetros para os layouts a partir do template da +mensagem: ```php /** @@ -113,15 +115,15 @@ $message = new \Yiisoft\Mailer\Message( ); ``` -### Layout Example +### Exemplo de layout -You can wrap the view rendering result in a layout, similar to how layouts -work in web applications. This is useful for setting up shared content like -CSS styles: +Você pode envolver o resultado da renderização da view num layout, do mesmo +jeito que os layouts funcionam em aplicações web. Isso é útil para definir +conteúdo compartilhado, como estilos CSS: ```php @@ -141,95 +143,97 @@ Mailed by Yii ``` -## Adding More Data - -The `Yiisoft\Mailer\MessageInterface` provides several methods to customize -your message: - -- `withCharset()` - Returns a new instance with the specified charset. -- `withFrom()` - Returns a new instance with the specified sender email - address. -- `withTo()` - Returns a new instance with the specified recipient(s) email - address. -- `withReplyTo()` - Returns a new instance with the specified reply-to - address. -- `withCc()` - Returns a new instance with the specified Cc (extra copy - receiver) addresses. -- `withBcc()` - Returns a new instance with the specified Bcc (hidden copy - receiver) addresses. -- `withSubject()` - Returns a new instance with the specified message - subject. -- `withDate()` - Returns a new instance with the specified date when the - message was sent. -- `withPriority()` - Returns a new instance with the specified priority of - this message. -- `withReturnPath()` - Returns a new instance with the specified return-path - (the bounce address) of this message. -- `withSender()` - Returns a new instance with the specified actual sender - email address. -- `withHtmlBody()` - Returns a new instance with the specified message HTML - content. -- `withTextBody()` - Returns a new instance with the specified message plain - text content. -- `withAddedHeader()` - Returns a new instance with the specified added - custom header value. -- `withHeader()` - Returns a new instance with the specified custom header - value. -- `withHeaders()` - Returns a new instance with the specified custom header - values. - -These methods are immutable, meaning they return a new instance of the -message with the updated data. - -Note `with` prefix. It indicates that the method is immutable and returns a -new instance of the class with the changed data. +## Adicionando mais dados + +A `Yiisoft\Mailer\MessageInterface` oferece vários métodos para personalizar +a mensagem: + +- `withCharset()` - Retorna uma nova instância com o charset informado. +- `withFrom()` - Retorna uma nova instância com o endereço de e-mail do + remetente informado. +- `withTo()` - Retorna uma nova instância com o(s) endereço(s) de e-mail + do(s) destinatário(s) informado(s). +- `withReplyTo()` - Retorna uma nova instância com o endereço de resposta + (reply-to) informado. +- `withCc()` - Retorna uma nova instância com os endereços em Cc + (destinatários de cópia) informados. +- `withBcc()` - Retorna uma nova instância com os endereços em Bcc + (destinatários de cópia oculta) informados. +- `withSubject()` - Retorna uma nova instância com o assunto da mensagem + informado. +- `withDate()` - Retorna uma nova instância com a data de envio da mensagem + informada. +- `withPriority()` - Retorna uma nova instância com a prioridade da mensagem + informada. +- `withReturnPath()` - Retorna uma nova instância com o return-path + (endereço de bounce) da mensagem informado. +- `withSender()` - Retorna uma nova instância com o endereço de e-mail do + remetente real informado. +- `withHtmlBody()` - Retorna uma nova instância com o conteúdo HTML da + mensagem informado. +- `withTextBody()` - Retorna uma nova instância com o conteúdo em texto puro + da mensagem informado. +- `withAddedHeader()` - Retorna uma nova instância com o valor de header + personalizado adicionado. +- `withHeader()` - Retorna uma nova instância com o valor de header + personalizado informado. +- `withHeaders()` - Retorna uma nova instância com os valores de headers + personalizados informados. + +Esses métodos são imutáveis, ou seja, retornam uma nova instância da +mensagem com os dados atualizados. + +Repare no prefixo `with`. Ele indica que o método é imutável e retorna uma +nova instância da classe com os dados alterados. ### Getters -The following getters are available to retrieve message data: - -- `getCharset()` - Returns the charset of this message. -- `getFrom()` - Returns the message sender email address. -- `getTo()` - Returns the message recipient(s) email address. -- `getReplyTo()` - Returns the reply-to address of this message. -- `getCc()` - Returns the Cc (extra copy receiver) addresses of this - message. -- `getBcc()` - Returns the Bcc (hidden copy receiver) addresses of this - message. -- `getSubject()` - Returns the message subject. -- `getDate()` - Returns the date when the message was sent, or null if it - wasn't set. -- `getPriority()` - Returns the priority of this message. -- `getReturnPath()` - Returns the return-path (the bounce address) of this - message. -- `getSender()` - Returns the message actual sender email address. -- `getHtmlBody()` - Returns the message HTML body. -- `getTextBody()` - Returns the message text body. -- `getHeader()` - Returns all values for the specified header. -- `__toString()` - Returns string representation of this message. - -## Attaching Files - -You can attach files to your message using the `withAttached()` method: +Os getters a seguir estão disponíveis para obter os dados da mensagem: + +- `getCharset()` - Retorna o charset da mensagem. +- `getFrom()` - Retorna o endereço de e-mail do remetente da mensagem. +- `getTo()` - Retorna o(s) endereço(s) de e-mail do(s) destinatário(s) da + mensagem. +- `getReplyTo()` - Retorna o endereço de resposta (reply-to) da mensagem. +- `getCc()` - Retorna os endereços em Cc (destinatários de cópia) da + mensagem. +- `getBcc()` - Retorna os endereços em Bcc (destinatários de cópia oculta) + da mensagem. +- `getSubject()` - Retorna o assunto da mensagem. +- `getDate()` - Retorna a data de envio da mensagem, ou null se ela não foi + definida. +- `getPriority()` - Retorna a prioridade da mensagem. +- `getReturnPath()` - Retorna o return-path (endereço de bounce) da + mensagem. +- `getSender()` - Retorna o endereço de e-mail do remetente real da + mensagem. +- `getHtmlBody()` - Retorna o corpo HTML da mensagem. +- `getTextBody()` - Retorna o corpo em texto da mensagem. +- `getHeader()` - Retorna todos os valores do header informado. +- `__toString()` - Retorna a representação em string da mensagem. + +## Anexando arquivos + +Você pode anexar arquivos à mensagem com o método `withAttached()`: ```php use Yiisoft\Mailer\File; -// Attach a file from the local file system +// Anexa um arquivo do sistema de arquivos local $message = $message->withAttached( File::fromPath('/path/to/source/file.pdf'), ); -// Create an attachment on-the-fly +// Cria um anexo na hora $message = $message->withAttached( File::fromContent('Attachment content', 'attach.txt', 'text/plain'), ); ``` -## Embedding Images +## Incorporando imagens -You can embed images into the message content using the `withEmbedded()` -method. This is particularly useful when composing messages with views: +Você pode incorporar imagens ao conteúdo da mensagem com o método +`withEmbedded()`. Isso é especialmente útil ao compor mensagens com views: ```php $logo = 'path/to/logo'; @@ -249,16 +253,16 @@ return new \Yiisoft\Mailer\Message( ); ``` -In your view or layout template, you can reference the embedded image using -its CID: +No template da view ou do layout, você pode referenciar a imagem incorporada +pelo seu CID: ```php ``` -## Sending a Message +## Enviando uma mensagem -To send an email message: +Para enviar uma mensagem de e-mail: ```php /** @@ -280,9 +284,9 @@ $message = new \Yiisoft\Mailer\Message( $mailer->send($message); ``` -## Sending Multiple Messages +## Enviando várias mensagens -You can send multiple messages at once: +Você pode enviar várias mensagens de uma vez: ```php $messages = []; @@ -296,34 +300,33 @@ foreach ($users as $user) { $result = $mailer->sendMultiple($messages); ``` -The `sendMultiple()` method returns a `Yiisoft\Mailer\SendResults` object -containing arrays of successfully sent and failed messages. +O método `sendMultiple()` retorna um objeto `Yiisoft\Mailer\SendResults` com +arrays das mensagens enviadas com sucesso e das que falharam. -## Implementing your own mail driver +## Implementando seu próprio driver de e-mail -To create a custom mail solution, implement the -`Yiisoft\Mailer\MailerInterface` and `Yiisoft\Mailer\MessageInterface` -interfaces. +Para criar uma solução de e-mail personalizada, implemente as interfaces +`Yiisoft\Mailer\MailerInterface` e `Yiisoft\Mailer\MessageInterface`. -## For Development +## Para desenvolvimento -For local or test development, you can use simplified implementations of the -mailer that does not send emails. The package provides these -implementations: +Em desenvolvimento local ou em testes, você pode usar implementações +simplificadas do mailer que não enviam e-mails. O pacote oferece estas +implementações: -- `Yiisoft\Mailer\StubMailer` - A simple mailer that stores messages in a - local array. -- `Yiisoft\Mailer\FileMailer` - A mock mailer that saves email messages as - files instead of sending them. -- `Yiisoft\Mailer\NullMailer` - A mailer that discards messages without - sending or storing them. +- `Yiisoft\Mailer\StubMailer` - Um mailer simples que guarda as mensagens + num array local. +- `Yiisoft\Mailer\FileMailer` - Um mailer de mentira que grava as mensagens + de e-mail em arquivos em vez de enviá-las. +- `Yiisoft\Mailer\NullMailer` - Um mailer que descarta as mensagens sem + enviá-las nem guardá-las. -To use one of these mailers, configure it in your development environment -file Example: `environments/local/di.php` +Para usar um desses mailers, configure-o no arquivo de ambiente de +desenvolvimento. Exemplo: `environments/local/di.php` ```php return [ - Yiisoft\Mailer\MailerInterface::class => Yiisoft\Mailer\StubMailer::class, //or any other + Yiisoft\Mailer\MailerInterface::class => Yiisoft\Mailer\StubMailer::class, //ou qualquer outro ]; ``` diff --git a/src/pt-BR/guide/tutorial/performance-tuning.md b/src/pt-BR/guide/tutorial/performance-tuning.md index 2bb48c75..77620c4b 100644 --- a/src/pt-BR/guide/tutorial/performance-tuning.md +++ b/src/pt-BR/guide/tutorial/performance-tuning.md @@ -1,82 +1,83 @@ -# Performance tuning - -There are many factors affecting the performance of your application. Some -are environmental, some are related to your code, while some others are -related to Yii itself. In this section, we will count most of these factors -and explain how you can improve your application performance by adjusting -these factors. - - -## Optimizing your PHP Environment - -A well-configured PHP environment is important. To get maximum performance: - -- Use the latest stable PHP version. Major releases of PHP may bring - significant performance improvements. -- Enable bytecode caching with [Opcache](https://secure.php.net/opcache). - Bytecode caching avoids the time spent on parsing and including PHP - scripts for every incoming request. -- [Tune `realpath()` - cache](https://github.com/samdark/realpath_cache_tuner). -- Make sure [XDebug](https://xdebug.org/) isn't installed in the production - environment. -- Try [PHP 7 preloading](https://wiki.php.net/rfc/preload). - -## Optimizing your code - -Beyond environment configuration, there are code-level optimizations that -can improve your application's performance: - -- Look out for [algorithm - complexity](https://en.wikipedia.org/wiki/Time_complexity). Especially - give attention to `foreach` within `foreach` loops but look out for using - [heavy PHP - functions](https://stackoverflow.com/questions/2473989/list-of-big-o-for-php-functions) - in loops as well. -- [Speeding up +# Ajuste de desempenho + +Muitos fatores afetam o desempenho da sua aplicação. Alguns são do ambiente, +outros estão ligados ao seu código, e outros ao próprio Yii. Nesta seção, +listamos a maioria desses fatores e explicamos como você pode melhorar o +desempenho da aplicação ajustando cada um deles. + + +## Otimizando o ambiente PHP + +Um ambiente PHP bem configurado é importante. Para obter o máximo de +desempenho: + +- Use a versão estável mais recente do PHP. Versões principais do PHP podem + trazer ganhos de desempenho significativos. +- Ative o cache de bytecode com o + [Opcache](https://secure.php.net/opcache). O cache de bytecode evita o + tempo gasto para analisar e incluir os scripts PHP a cada requisição. +- [Ajuste o cache do + `realpath()`](https://github.com/samdark/realpath_cache_tuner). +- Garanta que o [XDebug](https://xdebug.org/) não esteja instalado no + ambiente de produção. +- Experimente o [preload do PHP 7](https://wiki.php.net/rfc/preload). + +## Otimizando o seu código + +Além da configuração do ambiente, há otimizações no nível do código que +podem melhorar o desempenho da aplicação: + +- Fique atento à [complexidade dos + algoritmos](https://en.wikipedia.org/wiki/Time_complexity). Preste + atenção especial a loops `foreach` dentro de `foreach`, mas também ao uso + de [funções PHP + pesadas](https://stackoverflow.com/questions/2473989/list-of-big-o-for-php-functions) + dentro de loops. +- [Acelerando o array_merge()](https://www.exakat.io/speeding-up-array_merge/) -- [Move that foreach() inside the - method](https://www.exakat.io/move-that-foreach-inside-the-method/) -- [Array, classes and anonymous classes memory - usage](https://www.exakat.io/array-classes-and-anonymous-memory-usage/) -- Use fully qualified function names with leading backslashes to optimize - opcache performance. When calling [certain global - functions](https://github.com/php/php-src/blob/944b6b6bbd6f05ad905f5f4ad07445792bee4027/Zend/zend_compile.c#L4291-L4353) - from within a namespace, PHP first searches in the current namespace - before falling back to the global namespace. Adding a leading backslash - (e.g., `\count()` instead of `count()`) tells PHP to directly use the - global function, avoiding the namespace lookup and improving opcache - efficiency. This optimization is best implemented automatically using - tools like [PHP-CS-Fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer) - with the `native_function_invocation` rule. - -The above optimizations would give you a significant performance boost only -if the code in question is executed frequently. That is usually the case for -big loops or batch processing. - -## Using caching techniques - -You can use various caching techniques to significantly improve the -performance of your application. For example, if your application allows -users to enter text in Markdown format, you may consider caching the parsed -Markdown content to avoid parsing the same Markdown text repeatedly in every -request. Please refer to the [Caching](../caching/overview.md) section to -learn about the caching support provided by Yii. - - -## Optimizing session storage - -By default, session data is stored in files. The implementation is locking a file from opening a session to the point it's -closed either by `$session->close()` or at the end of request. -While the session file is locked, all other requests that are trying to use the same session are blocked. That's waiting for the -initial request to release a session file. This is fine for development and probably small projects. But when it comes -to handling massive concurrent requests, it's better to use more sophisticated storage, such as Redis. - -It could be done either by [configuring PHP via +- [Mova aquele foreach() para dentro do + método](https://www.exakat.io/move-that-foreach-inside-the-method/) +- [Uso de memória de arrays, classes e classes + anônimas](https://www.exakat.io/array-classes-and-anonymous-memory-usage/) +- Use nomes de funções totalmente qualificados, com barra invertida no + início, para otimizar o desempenho do opcache. Ao chamar [certas funções + globais](https://github.com/php/php-src/blob/944b6b6bbd6f05ad905f5f4ad07445792bee4027/Zend/zend_compile.c#L4291-L4353) + de dentro de um namespace, o PHP primeiro procura no namespace atual antes + de recorrer ao namespace global. Adicionar a barra invertida no início + (por exemplo, `\count()` em vez de `count()`) diz ao PHP para usar + diretamente a função global, evitando a busca no namespace e melhorando a + eficiência do opcache. O melhor é aplicar essa otimização automaticamente + com ferramentas como o + [PHP-CS-Fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer), usando a + regra `native_function_invocation`. + +As otimizações acima só trazem um ganho de desempenho significativo se o +código em questão for executado com frequência. Normalmente é o caso de +loops grandes ou de processamento em lote. + +## Usando técnicas de cache + +Você pode usar várias técnicas de cache para melhorar bastante o desempenho +da aplicação. Por exemplo, se a sua aplicação permite que os usuários +digitem texto em Markdown, considere guardar em cache o conteúdo Markdown já +processado, para não processar o mesmo texto repetidamente a cada +requisição. Consulte a seção de [Cache](../caching/overview.md) para +conhecer o suporte a cache oferecido pelo Yii. + + +## Otimizando o armazenamento de sessões + +Por padrão, os dados de sessão são guardados em arquivos. A implementação trava o arquivo desde a abertura da sessão até o momento em que ela é +fechada, seja por `$session->close()` ou no fim da requisição. +Enquanto o arquivo de sessão está travado, todas as outras requisições que tentam usar a mesma sessão ficam bloqueadas, esperando a +requisição inicial liberar o arquivo de sessão. Isso serve para desenvolvimento e, provavelmente, para projetos pequenos. Mas quando se trata +de lidar com muitas requisições concorrentes, é melhor usar um armazenamento mais sofisticado, como o Redis. + +Isso pode ser feito [configurando o PHP via php.ini](https://www.digitalocean.com/community/tutorials/how-to-set-up-a-redis-server-as-a-session-handler-for-php-on-ubuntu-14-04) -or [implementing +ou [implementando a SessionHandlerInterface](https://www.sitepoint.com/saving-php-sessions-in-redis/) -and configuring session service as follows: +e configurando o serviço de sessão assim: ```php \Yiisoft\Session\SessionInterface::class => [ @@ -85,106 +86,106 @@ and configuring session service as follows: ], ``` -## Optimizing databases +## Otimizando bancos de dados -Executing DB queries and fetching data from databases are often the main -performance bottleneck in a Web application. Although using [data -caching](../caching/data.md) techniques may ease the performance hit, it -doesn't fully solve the problem. When the database has enormous amounts of -data and the cached data are invalid, fetching the latest data could be -prohibitively expensive without a proper database and query design. +Executar consultas e buscar dados no banco de dados costuma ser o principal +gargalo de desempenho de uma aplicação web. Embora técnicas de [cache de +dados](../caching/data.md) possam amenizar o impacto, elas não resolvem +totalmente o problema. Quando o banco de dados tem uma quantidade enorme de +dados e os dados em cache ficam inválidos, buscar os dados mais recentes +pode ficar caro demais sem um bom projeto de banco de dados e de consultas. -A general technique to improve the performance of DB queries is to create -indices for table columns that need to be filtered by. For example, if you -need to look for a user record by `username`, you should create an index on -`username`. Note that while indexing can make SELECT queries much faster, it -will slow down INSERT, UPDATE and DELETE queries. +Uma técnica geral para melhorar o desempenho das consultas é criar índices +nas colunas das tabelas usadas em filtros. Por exemplo, se você precisa +buscar o registro de um usuário pelo `username`, crie um índice em +`username`. Note que, embora a indexação possa deixar as consultas SELECT +muito mais rápidas, ela deixa as consultas INSERT, UPDATE e DELETE mais +lentas. -For complex DB queries, it's recommended that you create database views to -save the query parsing and preparation time. +Para consultas complexas, é recomendável criar views no banco de dados para +economizar o tempo de análise e preparação da consulta. -Last but not least, use `LIMIT` in your `SELECT` queries. This avoids -fetching an overwhelming amount of data from the database and exhausting the -memory allocated to PHP. +Por último, mas não menos importante, use `LIMIT` nas suas consultas +`SELECT`. Isso evita buscar uma quantidade excessiva de dados no banco e +esgotar a memória alocada para o PHP. -## Optimizing composer autoloader +## Otimizando o autoloader do Composer -Because Composer autoloader is used to include most third-party class files, -you should consider optimizing it by executing the following command: +Como o autoloader do Composer é usado para incluir a maioria dos arquivos de +classes de terceiros, considere otimizá-lo executando o seguinte comando: ``` composer dumpautoload -o ``` -Additionally, you may consider using [authoritative class -maps](https://getcomposer.org/doc/articles/autoloader-optimization.md#optimization-level-2-a-authoritative-class-maps) -and [APCu -cache](https://getcomposer.org/doc/articles/autoloader-optimization.md#optimization-level-2-b-apcu-cache). -Note that both optimizations may or may not be suitable for your particular -case. +Além disso, você pode considerar o uso de [class maps +autoritativos](https://getcomposer.org/doc/articles/autoloader-optimization.md#optimization-level-2-a-authoritative-class-maps) +e do [cache +APCu](https://getcomposer.org/doc/articles/autoloader-optimization.md#optimization-level-2-b-apcu-cache). +Note que essas duas otimizações podem ou não ser adequadas ao seu caso. -## Processing data offline +## Processando dados offline -When a request involves some resource-intensive operations, you should think -of ways to perform those operations in offline mode without having users -wait for them to finish. +Quando uma requisição envolve operações que consomem muitos recursos, pense +em formas de executá-las em modo offline, sem fazer os usuários esperarem +que terminem. -There are two methods to process data offline: pull and push. +Há dois métodos para processar dados offline: pull e push. -In the pull method, whenever a request involves some complex operation, you -create a task and save it in a persistent storage, such as a database. You -then use a separate process (such as a cron job) to pull the tasks and -process them. This method is straightforward to implement, but it has some -drawbacks. For example, the task process needs to periodically pull from the -task storage. If the pull frequency is too low, the tasks may be processed -with great delay, but if the frequency is too high, it will introduce high -overhead. +No método pull, sempre que uma requisição envolve alguma operação complexa, +você cria uma tarefa e a salva num armazenamento persistente, como um banco +de dados. Depois, usa um processo separado (como um cron job) para buscar as +tarefas e processá-las. Esse método é simples de implementar, mas tem +algumas desvantagens. Por exemplo, o processo de tarefas precisa consultar +periodicamente o armazenamento de tarefas. Se a frequência for baixa demais, +as tarefas podem ser processadas com muito atraso; se for alta demais, gera +muito overhead. -In the push method, you would use a message queue (e.g., RabbitMQ, ActiveMQ, -Amazon SQS, etc.) to manage the tasks. Whenever a new task is put in the -queue, it will initiate or notify the task handling process to trigger the -task processing. +No método push, você usa uma fila de mensagens (por exemplo, RabbitMQ, +ActiveMQ, Amazon SQS etc.) para gerenciar as tarefas. Sempre que uma nova +tarefa entra na fila, ela inicia ou notifica o processo responsável, que +dispara o processamento da tarefa. -## Using preloading +## Usando preload -As of PHP 7.4.0, PHP can be configured to preload scripts into the opcache -when the engine starts. You can read more in the -[documentation](https://www.php.net/manual/en/opcache.preloading.php) and -the corresponding [RFC](https://wiki.php.net/rfc/preload). +A partir do PHP 7.4.0, o PHP pode ser configurado para pré-carregar scripts +no opcache quando o engine inicia. Saiba mais na +[documentação](https://www.php.net/manual/en/opcache.preloading.php) e na +[RFC](https://wiki.php.net/rfc/preload) correspondente. -Note that the optimal tradeoff between performance and memory may vary with -the application. "Preload everything" may be the easiest strategy, but not -necessarily the best strategy. +Note que o equilíbrio ideal entre desempenho e memória pode variar conforme +a aplicação. "Pré-carregar tudo" pode ser a estratégia mais fácil, mas não +necessariamente a melhor. -For example, we conducted a simple -[yiisoft/app](https://github.com/yiisoft/app) application template -benchmark. Without preloading and with preloading of the entire composer -class map. +Por exemplo, fizemos um benchmark simples do template de aplicação +[yiisoft/app](https://github.com/yiisoft/app): sem preload e com preload de +todo o class map do Composer. -### Preloading benchmarks +### Benchmarks de preload -The application template benchmark includes configuring classes to injected -dependencies in the bootstrap script. +O benchmark do template de aplicação inclui a configuração das classes para +as dependências injetadas no script de bootstrap. -For both variants, -[ApacheBench](https://httpd.apache.org/docs/2.4/programs/ab.html) was used -with the following run parameters: +Nas duas variantes, foi usado o +[ApacheBench](https://httpd.apache.org/docs/2.4/programs/ab.html) com os +seguintes parâmetros de execução: ```shell ab -n 1000 -c 10 -t 10 ``` -Also, the debug mode was disabled. And an optimized autoloader of the -[Composer](https://getcomposer.org) was used, and development dependencies -weren't used: +Além disso, o modo debug estava desativado. Também foi usado um autoloader +otimizado do [Composer](https://getcomposer.org), sem as dependências de +desenvolvimento: ```shell composer install --optimize-autoloader --no-dev ``` -With preloading enabled, the entire composer class map (825 files) was used: +Com o preload ativado, foi usado todo o class map do Composer (825 +arquivos): ```php $files = require 'vendor/composer/autoload_classmap.php'; @@ -194,26 +195,26 @@ foreach (array_unique($files) as $file) { } ``` -#### Test results +#### Resultados dos testes -| Benchmark | Preloaded files | Opcache memory used | Per request memory used | Time per request | Requests per second | -|--------------------|-----------------|---------------------|-------------------------|------------------|---------------------| -| Without preloading | 0 | 12.32 mb | 1.71 mb | 27.63 ms | 36.55 rq/s | -| With preloading | 825 | 17.86 mb | 1.82 mb | 26.21 ms | 38.42 rq/s | +| Benchmark | Arquivos pré-carregados | Memória do Opcache usada | Memória usada por requisição | Tempo por requisição | Requisições por segundo | +|--------------------|-------------------------|--------------------------|------------------------------|----------------------|-------------------------| +| Sem preload | 0 | 12.32 mb | 1.71 mb | 27.63 ms | 36.55 rq/s | +| Com preload | 825 | 17.86 mb | 1.82 mb | 26.21 ms | 38.42 rq/s | -As you can see, the test results aren't much different, since this is just a -clean application template that contains a few classes. More discussion of -preloading, including benchmarks, can be found in the [composer's -issue](https://github.com/composer/composer/issues/7777). +Como você pode ver, os resultados não são muito diferentes, já que este é +apenas um template de aplicação limpo, com poucas classes. Mais discussões +sobre preload, incluindo benchmarks, estão na [issue do +Composer](https://github.com/composer/composer/issues/7777). -## Performance profiling +## Profiling de desempenho -You should profile your code to find out the performance bottlenecks and -take appropriate measures accordingly. The following profiling tools may be -useful: +Faça o profiling do seu código para encontrar os gargalos de desempenho e +tomar as medidas adequadas. As seguintes ferramentas de profiling podem ser +úteis: - [Blackfire](https://blackfire.io/) - [XHProf](https://secure.php.net/manual/en/book.xhprof.php) -- [XDebug profiler](https://xdebug.org/docs/profiler) +- [Profiler do XDebug](https://xdebug.org/docs/profiler) diff --git a/src/pt-BR/guide/tutorial/using-with-event-loop.md b/src/pt-BR/guide/tutorial/using-with-event-loop.md index e23d13e9..f9fccd26 100644 --- a/src/pt-BR/guide/tutorial/using-with-event-loop.md +++ b/src/pt-BR/guide/tutorial/using-with-event-loop.md @@ -1,22 +1,23 @@ -# Using Yii with event loop +# Usando o Yii com event loop -A normal PHP web request execution cycle consists of setting up an environment, getting a request, processing it to form a response -and sending the result. After the response is sent, execution is terminated and its context is lost. So, for the further - request, the whole sequence is repeated. Such an approach has a big advantage in ease of development since a developer doesn't -have to take much care about memory leaks or properly clean up context. On the other side, initializing everything for -every request takes time and overall consumes up to 50% of processing resources. +O ciclo normal de execução de uma requisição web em PHP consiste em preparar o ambiente, receber a requisição, processá-la para gerar uma resposta +e enviar o resultado. Depois que a resposta é enviada, a execução termina e o contexto se perde. Então, na requisição + seguinte, toda a sequência se repete. Essa abordagem tem uma grande vantagem na facilidade de desenvolvimento, já que o desenvolvedor não +precisa se preocupar muito com vazamentos de memória nem com limpar o contexto corretamente. Por outro lado, inicializar tudo a +cada requisição leva tempo e, no total, consome até 50% dos recursos de processamento. -There is an alternative way of running an application. Event loop. The idea -is to initialize everything possible at once and then process a number of -requests using it. Such an approach is usually called event loop. +Existe outra forma de rodar uma aplicação: o event loop. A ideia é +inicializar tudo o que for possível uma única vez e depois processar várias +requisições usando esse contexto. Essa abordagem costuma ser chamada de +event loop. -There are multiple tools that could be used to achieve it. Notably, +Há várias ferramentas que permitem fazer isso. As principais são [FrankenPHP](https://frankenphp.dev/), [Rapira](https://rapira.rs/), -[RoadRunner](https://roadrunner.dev/) and [Swoole](https://www.swoole.com/). +[RoadRunner](https://roadrunner.dev/) e [Swoole](https://www.swoole.com/). -## Event loop implications +## Implicações do event loop -Event loop worker basically looks like the following: +Um worker de event loop basicamente tem esta cara: ```php initializeContext(); @@ -26,28 +27,30 @@ while ($request = getRequest()) { } ``` -Usually, there are multiple workers processing requests at the same time as -with traditional php-fpm. +Normalmente, há vários workers processando requisições ao mesmo tempo, como +no php-fpm tradicional. -That means that there's more to consider when developing applications. +Isso significa que há mais coisas a considerar ao desenvolver aplicações. -### Processing is blocking +### O processamento é bloqueante -Worker process requests one by one that's current processing is blocking -processing next request. That means that long-running processes, same as in -general PHP applications, should be put into a background via using a queue. +O worker processa as requisições uma a uma, ou seja, o processamento atual +bloqueia o processamento da próxima requisição. Isso significa que processos +demorados, assim como em aplicações PHP comuns, devem ir para segundo plano +usando uma fila. -### Services and state +### Serviços e estado -Since the context in the event loop is shared between all request-responses -processed by a single worker, all changes in the state of a service made by -the previous request may affect the current request. Moreover, it can be a -security problem if data from one user is available to another user. +Como o contexto no event loop é compartilhado entre todas as requisições e +respostas processadas por um mesmo worker, qualquer mudança no estado de um +serviço feita pela requisição anterior pode afetar a requisição atual. Além +disso, isso pode ser um problema de segurança se os dados de um usuário +ficarem disponíveis para outro. -There are two ways of dealing with it. First, you can avoid having state by -making services stateless. PHP's `readonly` keyword may be handy for -it. Second, you can reset the services' state at the end of the request -processing. In this case, a state resetter will help you: +Há duas formas de lidar com isso. A primeira é evitar estado, tornando os +serviços stateless. A palavra-chave `readonly` do PHP pode ajudar nisso. A +segunda é redefinir o estado dos serviços ao fim do processamento da +requisição. Nesse caso, um state resetter vai ajudar você: ```php initializeContext(); @@ -55,11 +58,11 @@ $resetter = $container->get(\Yiisoft\Di\StateResetter::class); while ($request = getRequest()) { $response = process($request); emit($response); - $resetter->reset(); // We should reset the state of such services on every request. + $resetter->reset(); // Precisamos redefinir o estado desses serviços a cada requisição. } ``` -## Integrations +## Integrações - [FrankenPHP](using-yii-with-frankenphp.md) - [Rapira](using-yii-with-rapira.md) diff --git a/src/pt-BR/guide/tutorial/using-yii-with-frankenphp.md b/src/pt-BR/guide/tutorial/using-yii-with-frankenphp.md index 9279338a..9b04fe92 100644 --- a/src/pt-BR/guide/tutorial/using-yii-with-frankenphp.md +++ b/src/pt-BR/guide/tutorial/using-yii-with-frankenphp.md @@ -1,37 +1,37 @@ -# Using Yii with FrankenPHP +# Usando o Yii com FrankenPHP -[FrankenPHP](https://frankenphp.dev/) is an application server for PHP with Caddy built in. It can run Yii in -[worker mode](using-with-event-loop.md), allowing the framework bootstrap to happen once per worker instead of -once per request. +O [FrankenPHP](https://frankenphp.dev/) é um servidor de aplicação PHP com o Caddy embutido. Ele pode rodar o Yii em +[modo worker](using-with-event-loop.md), o que faz o bootstrap do framework acontecer uma vez por worker em vez de +uma vez por requisição. -## Installation +## Instalação -The [FrankenPHP runner](https://github.com/yiisoft/yii-runner-frankenphp) -requires PHP 8.1–8.5. Install FrankenPHP using its [installation -instructions](https://frankenphp.dev/docs/), or use the Docker setup in the -Yii application templates described below. +O [runner para FrankenPHP](https://github.com/yiisoft/yii-runner-frankenphp) +exige PHP 8.1–8.5. Instale o FrankenPHP seguindo as [instruções de +instalação](https://frankenphp.dev/docs/) dele, ou use a configuração Docker +dos templates de aplicação do Yii, descrita abaixo. -Install the runner package with Composer: +Instale o pacote do runner com o Composer: ```shell composer require yiisoft/yii-runner-frankenphp ``` -FrankenPHP works especially well in containerized deployments and is the -runtime used by the Yii application templates Docker setup described in -[Docker in application templates](docker.md). +O FrankenPHP funciona especialmente bem em deploys com containers e é o +runtime usado pela configuração Docker dos templates de aplicação do Yii, +descrita em [Docker nos templates de aplicação](docker.md). > [!NOTE] -> This runner is for worker mode. To use FrankenPHP in classic mode, keep `public/index.php` and -> [yiisoft/yii-runner-http](https://github.com/yiisoft/yii-runner-http), the default HTTP runner in the templates. +> Este runner é para o modo worker. Para usar o FrankenPHP no modo clássico, mantenha o `public/index.php` e o +> [yiisoft/yii-runner-http](https://github.com/yiisoft/yii-runner-http), o runner HTTP padrão dos templates. -## Configuration +## Configuração -First, configure the worker entry script. +Primeiro, configure o script de entrada do worker. -### Worker entry script +### Script de entrada do worker -Create `/worker.php` in the project root: +Crie `/worker.php` na raiz do projeto: ```php run(); ``` -The runner bootstraps the application once and then keeps processing -requests in worker mode. Unlike classic `public/index.php`, this script is -not executed per request. +O runner faz o bootstrap da aplicação uma vez e depois continua processando +requisições em modo worker. Diferente do `public/index.php` clássico, este +script não é executado a cada requisição. -### Server configuration +### Configuração do servidor -FrankenPHP is configured through a `Caddyfile`. For production, it may look -like the following: +O FrankenPHP é configurado por um `Caddyfile`. Em produção, ele pode ficar +assim: ```caddyfile { @@ -108,12 +108,13 @@ like the following: } ``` -This configuration tells FrankenPHP to serve the `public` directory and -handle all requests with `worker.php`. Static assets are still served from -`public`, while PHP requests are processed through the long-running worker. +Essa configuração diz ao FrankenPHP para servir o diretório `public` e +atender todas as requisições com o `worker.php`. Os assets estáticos +continuam sendo servidos de `public`, enquanto as requisições PHP são +processadas pelo worker de longa duração. -For development, add `watch` so FrankenPHP reloads workers when PHP files -change: +Em desenvolvimento, adicione `watch` para que o FrankenPHP recarregue os +workers quando arquivos PHP mudarem: ```caddyfile { @@ -137,14 +138,14 @@ change: } ``` -### Docker setup in Yii application templates +### Configuração Docker nos templates de aplicação do Yii -Yii application templates already ship with a FrankenPHP-based Docker -setup. To switch the application to worker mode, update the files inside the -Docker layout instead of relying on `public/index.php`. +Os templates de aplicação do Yii já vêm com uma configuração Docker baseada +no FrankenPHP. Para passar a aplicação para o modo worker, altere os +arquivos da estrutura Docker em vez de depender do `public/index.php`. -Create `/worker.php` in the project root as shown above, then update the -Caddy configuration used by the container. For development, edit +Crie `/worker.php` na raiz do projeto como mostrado acima e depois altere a +configuração do Caddy usada pelo container. Em desenvolvimento, edite `docker/dev/Caddyfile`: ```caddyfile @@ -169,8 +170,7 @@ Caddy configuration used by the container. For development, edit } ``` -For production, use the same configuration without `watch` in -`docker/Caddyfile`: +Em produção, use a mesma configuração sem `watch` em `docker/Caddyfile`: ```caddyfile { @@ -193,71 +193,72 @@ For production, use the same configuration without `watch` in } ``` -The templates use `dunglas/frankenphp` as the base image in -`docker/Dockerfile`, mount the project into `/app` in development, and pass -runtime configuration through environment files such as `docker/dev/.env` -and `docker/prod/.env`. The default value of `SERVER_NAME` in these files is -`:80`, which matches the examples above. +Os templates usam `dunglas/frankenphp` como imagem base em +`docker/Dockerfile`, montam o projeto em `/app` no desenvolvimento e passam +a configuração de runtime por arquivos de ambiente como `docker/dev/.env` e +`docker/prod/.env`. O valor padrão de `SERVER_NAME` nesses arquivos é `:80`, +que corresponde aos exemplos acima. -After changing `worker.php` and the relevant `Caddyfile`, rebuild the image -and restart the environment: +Depois de alterar o `worker.php` e o `Caddyfile` correspondente, reconstrua +a imagem e reinicie o ambiente: ```shell make build make up ``` -In production, rebuild and deploy the production image using the project's -production Docker workflow. +Em produção, reconstrua a imagem de produção e faça o deploy usando o fluxo +Docker de produção do projeto. -If you switch fully to worker mode, `public/index.php` and -`yiisoft/yii-runner-http` are no longer needed. +Se você passar totalmente para o modo worker, o `public/index.php` e o +`yiisoft/yii-runner-http` deixam de ser necessários. -## Starting a server +## Iniciando o servidor -The exact start command depends on how you run FrankenPHP: +O comando exato para iniciar depende de como você roda o FrankenPHP: -- In the Yii application templates, run `make build` and `make up` after - updating `worker.php` and the relevant `Caddyfile`. -- With the standalone binary, run the following command from the directory - containing your `Caddyfile`: +- Nos templates de aplicação do Yii, execute `make build` e `make up` depois + de alterar o `worker.php` e o `Caddyfile` correspondente. +- Com o binário standalone, execute o seguinte comando no diretório que + contém o seu `Caddyfile`: ```shell frankenphp run --config Caddyfile ``` -The example configuration uses `/app` as the application root. Adjust -`/app/public`, `/app/worker.php`, and the watch path to match your -installation. See the [FrankenPHP configuration -reference](https://frankenphp.dev/docs/config/) for other deployment -options. +A configuração de exemplo usa `/app` como raiz da aplicação. Ajuste +`/app/public`, `/app/worker.php` e o caminho do watch conforme a sua +instalação. Veja a [referência de configuração do +FrankenPHP](https://frankenphp.dev/docs/config/) para outras opções de +deploy. -## On worker scope +## Sobre o escopo do worker -- Each worker's memory is isolated from other workers. -- A single worker handles multiple requests, so services created inside it - may keep state between requests. -- At each iteration of the event loop, every stateful service should be - reset. +- A memória de cada worker é isolada da dos outros workers. +- Um único worker atende várias requisições, então os serviços criados + dentro dele podem manter estado entre requisições. +- A cada iteração do event loop, todo serviço com estado deve ser + redefinido. -For the general implications of long-running workers, see [Using Yii with -event loop](using-with-event-loop.md). +Para as implicações gerais de workers de longa duração, veja [Usando o Yii +com event loop](using-with-event-loop.md). -## Worker mode notes +## Notas sobre o modo worker -- Use the `MAX_REQUESTS` environment variable to limit how many requests a - worker handles before restart. -- The runner calls `Yiisoft\Di\StateResetter::reset()` after each - request. Register resetters for your stateful services as described in the - [Yii DI - documentation](https://github.com/yiisoft/di#resetting-services-state). +- Use a variável de ambiente `MAX_REQUESTS` para limitar quantas requisições + um worker atende antes de ser reiniciado. +- O runner chama `Yiisoft\Di\StateResetter::reset()` depois de cada + requisição. Registre resetters para os seus serviços com estado, como + descrito na [documentação do Yii + DI](https://github.com/yiisoft/di#resetting-services-state). -## Additional configuration +## Configuração adicional -`FrankenPHPApplicationRunner` is configured by default for Yii application -templates and follows the [dependency container -configuration](../concept/configuration.md#container-configuration) concept. +O `FrankenPHPApplicationRunner` vem configurado por padrão para os templates +de aplicação do Yii e segue o conceito de [configuração do container de +dependências](../concept/configuration.md#configuracao-do-container). -The constructor allows overriding the default bootstrap, events, DI, params, -and error-handler configuration. You can also provide a custom config -instance with `withConfig()` and a custom container with `withContainer()`. +O construtor permite sobrescrever a configuração padrão de bootstrap, +eventos, DI, params e tratamento de erros. Você também pode fornecer uma +instância de configuração personalizada com `withConfig()` e um container +personalizado com `withContainer()`. diff --git a/src/pt-BR/guide/tutorial/using-yii-with-rapira.md b/src/pt-BR/guide/tutorial/using-yii-with-rapira.md index 7093ae04..07d024bf 100644 --- a/src/pt-BR/guide/tutorial/using-yii-with-rapira.md +++ b/src/pt-BR/guide/tutorial/using-yii-with-rapira.md @@ -1,36 +1,36 @@ -# Using Yii with Rapira +# Usando o Yii com Rapira -[Rapira](https://rapira.rs/) is a PHP application server written in Rust that embeds the PHP interpreter. -The [Yii Rapira runner](https://github.com/yiisoft/yii-runner-rapira) supports its classic, worker, and dispatcher modes. -Worker and dispatcher modes initialize the application once per worker and reuse it for subsequent requests. -See [Using Yii with event loop](using-with-event-loop.md) for the implications of keeping the application in memory. +O [Rapira](https://rapira.rs/) é um servidor de aplicação PHP escrito em Rust que embute o interpretador PHP. +O [runner do Yii para Rapira](https://github.com/yiisoft/yii-runner-rapira) suporta os modos classic, worker e dispatcher. +Os modos worker e dispatcher inicializam a aplicação uma vez por worker e a reaproveitam nas requisições seguintes. +Veja [Usando o Yii com event loop](using-with-event-loop.md) para as implicações de manter a aplicação na memória. -## Installation +## Instalação -The runner requires PHP 8.4–8.5. Install the Rapira binary following the -[Rapira installation -instructions](https://rapira.rs/docs/intro/installation), using a PHP -version supported by the runner. The Composer packages provide the Yii -integration; the server binary must be installed separately. +O runner exige PHP 8.4–8.5. Instale o binário do Rapira seguindo as +[instruções de instalação do +Rapira](https://rapira.rs/docs/intro/installation), com uma versão do PHP +suportada pelo runner. Os pacotes do Composer fornecem a integração com o +Yii; o binário do servidor precisa ser instalado à parte. -Install the runner and its contract package in your Yii application: +Instale o runner e o pacote de contratos dele na sua aplicação Yii: ```shell composer require yiisoft/yii-runner-rapira:@dev rapira/contract:@dev ``` -These stability flags allow the development versions used by the runner's -installation instructions. +Essas flags de estabilidade permitem as versões de desenvolvimento usadas +nas instruções de instalação do runner. -## Configuration +## Configuração -The following example assumes an application based on `yiisoft/app` or -`yiisoft/app-api`, with `App\Environment` and `src/bootstrap.php` provided -by the template. +O exemplo a seguir supõe uma aplicação baseada em `yiisoft/app` ou +`yiisoft/app-api`, com `App\Environment` e `src/bootstrap.php` fornecidos +pelo template. -### Worker entry script +### Script de entrada do worker -Create `worker.php` in the application root: +Crie `worker.php` na raiz da aplicação: ```php run(); ``` -The runner creates the container, starts the application, converts incoming -requests to PSR-7 requests, and emits responses. It detects the Rapira -execution mode, so the same entry script can be used with all three modes. +O runner cria o container, inicia a aplicação, converte as requisições +recebidas em requisições PSR-7 e emite as respostas. Ele detecta o modo de +execução do Rapira, então o mesmo script de entrada serve para os três +modos. -### Server configuration +### Configuração do servidor -Create `rapira.toml` next to `worker.php`: +Crie `rapira.toml` ao lado de `worker.php`: ```toml [http] @@ -88,56 +89,56 @@ mode = "worker" max_requests = 1000 ``` -This configuration listens on the loopback interface and recycles each -worker after 1,000 requests. For serving files from `public`, follow -Rapira's [static file configuration](https://rapira.rs/docs/static-files). -See the [configuration reference](https://rapira.rs/docs/configuration) for -the other server and pool settings. +Essa configuração escuta na interface de loopback e recicla cada worker +depois de 1.000 requisições. Para servir arquivos de `public`, siga a +[configuração de arquivos estáticos](https://rapira.rs/docs/static-files) do +Rapira. Veja a [referência de +configuração](https://rapira.rs/docs/configuration) para as outras opções do +servidor e do pool. -## Starting a server +## Iniciando o servidor -Run the following command from the application root: +Execute o seguinte comando na raiz da aplicação: ```shell rapira serve rapira.toml ``` -Open `http://127.0.0.1:8000` to access the application. Restart the server -after changing application code or configuration. +Abra `http://127.0.0.1:8000` para acessar a aplicação. Reinicie o servidor +depois de alterar o código ou a configuração da aplicação. -## Execution modes +## Modos de execução -Set `mode` in the `[http.pool]` section of `rapira.toml` to choose how -requests are processed: +Defina `mode` na seção `[http.pool]` do `rapira.toml` para escolher como as +requisições são processadas: -- `classic` initializes the application for each request, similarly to - PHP-FPM. -- `worker` keeps the application in memory and receives requests through - PHP's SAPI superglobals. -- `dispatcher` keeps the application in memory and receives request objects - through Rapira's dispatcher API. The Yii runner processes these requests - sequentially within each worker. +- `classic` inicializa a aplicação a cada requisição, como no PHP-FPM. +- `worker` mantém a aplicação na memória e recebe as requisições pelas + superglobais da SAPI do PHP. +- `dispatcher` mantém a aplicação na memória e recebe objetos de requisição + pela API de dispatcher do Rapira. O runner do Yii processa essas + requisições sequencialmente dentro de cada worker. -See [Rapira execution modes](https://rapira.rs/docs/execution-modes) for -details. +Veja [os modos de execução do +Rapira](https://rapira.rs/docs/execution-modes) para mais detalhes. -## On worker scope +## Sobre o escopo do worker -In worker and dispatcher modes, services may retain state between -requests. The runner calls `Yiisoft\Di\StateResetter::reset()` after each -request, but you must configure resetters for your own stateful services. -See the [Yii DI -documentation](https://github.com/yiisoft/di#resetting-services-state). +Nos modos worker e dispatcher, os serviços podem manter estado entre +requisições. O runner chama `Yiisoft\Di\StateResetter::reset()` depois de +cada requisição, mas você precisa configurar resetters para os seus próprios +serviços com estado. Veja a [documentação do Yii +DI](https://github.com/yiisoft/di#resetting-services-state). -The `max_requests` setting limits how long a worker lives; it does not -replace resetting request-specific state. +A opção `max_requests` limita quanto tempo um worker vive; ela não substitui +a redefinição do estado específico de cada requisição. -## Additional configuration +## Configuração adicional -`RapiraApplicationRunner` uses the application templates' web configuration -groups by default. Its constructor accepts alternative groups, configuration -directories, and a temporary error handler. Use `withConfig()` to supply a -custom configuration instance or `withContainer()` to supply a PSR-11 -container. See the [runner -documentation](https://github.com/yiisoft/yii-runner-rapira#configuration) -for examples. +O `RapiraApplicationRunner` usa por padrão os grupos de configuração web dos +templates de aplicação. O construtor aceita grupos alternativos, diretórios +de configuração e um error handler temporário. Use `withConfig()` para +fornecer uma instância de configuração personalizada ou `withContainer()` +para fornecer um container PSR-11. Veja a [documentação do +runner](https://github.com/yiisoft/yii-runner-rapira#configuration) para +exemplos. diff --git a/src/pt-BR/guide/tutorial/using-yii-with-roadrunner.md b/src/pt-BR/guide/tutorial/using-yii-with-roadrunner.md index 80b18078..baf6d31e 100644 --- a/src/pt-BR/guide/tutorial/using-yii-with-roadrunner.md +++ b/src/pt-BR/guide/tutorial/using-yii-with-roadrunner.md @@ -1,31 +1,31 @@ -# Using Yii with RoadRunner +# Usando o Yii com RoadRunner -[RoadRunner](https://roadrunner.dev/) is a Golang-powered application server that integrates well with PHP. It runs -it as workers and each worker may handle multiple requests. Such an operation mode is often called -[event loop](using-with-event-loop.md) and allows not re-initializing a framework for each request that improves -performance significantly. +O [RoadRunner](https://roadrunner.dev/) é um servidor de aplicação escrito em Go que se integra bem ao PHP. Ele roda +o PHP como workers, e cada worker pode atender várias requisições. Esse modo de operação costuma ser chamado de +[event loop](using-with-event-loop.md) e evita reinicializar o framework a cada requisição, o que melhora +bastante o desempenho. -## Installation +## Instalação -RoadRunner works on Linux, macOS and Windows. The best way to install it is -to use a Composer: +O RoadRunner funciona no Linux, macOS e Windows. A melhor forma de +instalá-lo é pelo Composer: ``` composer require yiisoft/yii-runner-roadrunner ``` -After installation is done, run +Terminada a instalação, execute ``` ./vendor/bin/rr get ``` -That would download ready to use RoadRunner server `rr` binary. +Isso baixa o binário `rr` do servidor RoadRunner, pronto para uso. -## Configuration +## Configuração -First, we need to configure the server itself. Create `/.rr.yaml` and add -the following config: +Primeiro, precisamos configurar o próprio servidor. Crie `/.rr.yaml` e +adicione a seguinte configuração: ```yaml version: '3' @@ -39,7 +39,7 @@ rpc: http: address: :8080 pool: - debug: false # set to true for local development only + debug: false # defina como true apenas no desenvolvimento local supervisor: max_worker_memory: 192 middleware: [static, gzip, headers, sendfile] @@ -56,28 +56,28 @@ logs: ``` > [!INFO] -> Read more about TLS, HTTP/2, HTTP/3 configuration and other middleware [on the RoadRunner docs](https://docs.roadrunner.dev/docs/http/http). +> Saiba mais sobre configuração de TLS, HTTP/2, HTTP/3 e outros middlewares [na documentação do RoadRunner](https://docs.roadrunner.dev/docs/http/http). -We're specifying that the entry script is `worker.php`, the server listens -on port 8080, `public` directory files are served statically except `.php` -and `.htaccess`. The `max_worker_memory` is a soft limit: if a worker -exceeds 192 MB, it will restart after finishing its current request. Also, -we're sending an additional header. +Estamos definindo que o script de entrada é o `worker.php`, que o servidor +escuta na porta 8080 e que os arquivos do diretório `public` são servidos +estaticamente, exceto `.php` e `.htaccess`. O `max_worker_memory` é um +limite flexível: se um worker passar de 192 MB, ele reinicia depois de +terminar a requisição atual. Também estamos enviando um header adicional. -## KV cache +## Cache KV -RoadRunner has a [KV -plugin](https://docs.roadrunner.dev/docs/key-value/overview-kv) that can be -used as a PSR-16 cache storage. It is useful when the application already -runs under RoadRunner and needs a cache shared by workers. +O RoadRunner tem um [plugin +KV](https://docs.roadrunner.dev/docs/key-value/overview-kv) que pode ser +usado como armazenamento de cache PSR-16. Ele é útil quando a aplicação já +roda no RoadRunner e precisa de um cache compartilhado entre os workers. -Install the PHP bridge and Yii cache package: +Instale a ponte PHP e o pacote de cache do Yii: ``` composer require spiral/roadrunner-kv yiisoft/cache ``` -Add a KV storage to `.rr.yaml`: +Adicione um armazenamento KV ao `.rr.yaml`: ```yaml kv: @@ -87,11 +87,11 @@ kv: interval: 60 ``` -The `memory` driver stores values inside the RoadRunner process, so its data -is lost when RoadRunner stops. For persistent cache storage, use another KV -driver from the RoadRunner documentation. +O driver `memory` guarda os valores dentro do processo do RoadRunner, então +os dados se perdem quando o RoadRunner para. Para um armazenamento de cache +persistente, use outro driver KV da documentação do RoadRunner. -Create `config/common/di/roadrunner-kv.php`: +Crie `config/common/di/roadrunner-kv.php`: ```php run(); ``` -## Starting a server +## Iniciando o servidor -To start a server, execute the following command: +Para iniciar o servidor, execute o seguinte comando: ``` ./rr serve ``` -## On worker scope +## Sobre o escopo do worker -- Each worker's scope is isolated from other workers. Memory isn't shared. -- A single worker serves multiple requests where the scope is shared. -- At each iteration of the event loop, every service that depends on state - should be reset. +- O escopo de cada worker é isolado dos outros workers. A memória não é + compartilhada. +- Um único worker atende várias requisições, e nelas o escopo é + compartilhado. +- A cada iteração do event loop, todo serviço que depende de estado deve ser + redefinido. diff --git a/src/pt-BR/guide/tutorial/using-yii-with-swoole.md b/src/pt-BR/guide/tutorial/using-yii-with-swoole.md index 76365322..067ef988 100644 --- a/src/pt-BR/guide/tutorial/using-yii-with-swoole.md +++ b/src/pt-BR/guide/tutorial/using-yii-with-swoole.md @@ -1,51 +1,51 @@ -# Using Yii with Swoole +# Usando o Yii com Swoole -[Swoole](https://www.swoole.com/) is a PHP extension for event-driven, coroutine-based network applications. It -includes an HTTP server, coroutine APIs, and runtime hooks for common blocking I/O functions. +O [Swoole](https://www.swoole.com/) é uma extensão PHP para aplicações de rede orientadas a eventos e baseadas em corrotinas. Ela +inclui um servidor HTTP, APIs de corrotinas e hooks de runtime para as funções de I/O bloqueantes mais comuns. -Swoole allows Yii request handlers to run as workers. Each worker may handle -multiple requests. Such an operation mode is often called [event -loop](using-with-event-loop.md) and allows not re-initializing a framework -for each request that improves performance significantly. +O Swoole permite que os handlers de requisição do Yii rodem como +workers. Cada worker pode atender várias requisições. Esse modo de operação +costuma ser chamado de [event loop](using-with-event-loop.md) e evita +reinicializar o framework a cada requisição, o que melhora bastante o +desempenho. -## Installation +## Instalação -Swoole supports Linux, macOS, Cygwin, and WSL. Install the extension through -PECL: +O Swoole suporta Linux, macOS, Cygwin e WSL. Instale a extensão pelo PECL: ```bash pecl install swoole ``` -If PECL doesn't enable the extension automatically, add it to your +Se o PECL não habilitar a extensão automaticamente, adicione-a ao seu `php.ini`: ```ini extension=swoole.so ``` -Check that PHP loads the extension: +Confira se o PHP carrega a extensão: ```bash php --ri swoole ``` -The Swoole project also provides a [Docker -image](https://github.com/swoole/docker-swoole) and documents source builds -with optional features such as OpenSSL, sockets, MySQL, PostgreSQL, and curl -hooks. +O projeto Swoole também oferece uma [imagem +Docker](https://github.com/swoole/docker-swoole) e documenta builds a partir +do código-fonte com recursos opcionais, como hooks para OpenSSL, sockets, +MySQL, PostgreSQL e curl. -## Putting up a server +## Subindo um servidor -Swoole passes `Swoole\Http\Request` and `Swoole\Http\Response` objects to -request callbacks. Yii handles PSR-7 requests and responses, so add a -converter package: +O Swoole passa objetos `Swoole\Http\Request` e `Swoole\Http\Response` para +os callbacks de requisição. O Yii trabalha com requisições e respostas +PSR-7, então adicione um pacote conversor: ```shell composer require ilexn/swoole-convert-psr7 ``` -Create an entry script, `server.php`: +Crie um script de entrada, `server.php`: ```php on('shutdown', static function (Server $server) use ($application) { $server->start(); ``` -## Starting a server +## Iniciando o servidor -To start a server, execute the following command: +Para iniciar o servidor, execute o seguinte comando: ``` php server.php ``` -## On scope +## Sobre o escopo -A scope is shared, so at each iteration of the event loop every service that -depends on state should be reset. +O escopo é compartilhado, então a cada iteração do event loop todo serviço +que depende de estado deve ser redefinido. ## Sessões -Avoid native PHP sessions, including `Yiisoft\Session\Session`, when Swoole -coroutines handle overlapping requests within one worker: they share session -state and can expose one user's data to another request. - -For requests handled one at a time, close the session and reset services -between requests. `yiisoft/session` prevents stale session ID reuse, but -does not isolate overlapping coroutines. - -For authentication, consider tokens such as -[JWT](https://jwt.io/introduction) instead of native sessions, especially -for APIs. If you need session features, use an implementation that isolates -each coroutine's session data; changing the native storage handler to Redis -is not enough. - -See the [Swoole -guidance](https://github.com/swoole/swoole-src/issues/4478#issuecomment-962840796) -and [Yii session discussion](https://github.com/yiisoft/session/issues/25). +Evite as sessões nativas do PHP, incluindo `Yiisoft\Session\Session`, quando +corrotinas do Swoole atendem requisições simultâneas dentro de um mesmo +worker: elas compartilham o estado da sessão e podem expor os dados de um +usuário a outra requisição. + +Para requisições atendidas uma por vez, feche a sessão e redefina os +serviços entre as requisições. O `yiisoft/session` impede o reuso de IDs de +sessão antigos, mas não isola corrotinas simultâneas. + +Para autenticação, considere tokens como [JWT](https://jwt.io/introduction) +em vez de sessões nativas, principalmente em APIs. Se você precisa de +recursos de sessão, use uma implementação que isole os dados de sessão de +cada corrotina; trocar o handler de armazenamento nativo para Redis não +basta. + +Veja as [orientações do +Swoole](https://github.com/swoole/swoole-src/issues/4478#issuecomment-962840796) +e a [discussão sobre sessões no +Yii](https://github.com/yiisoft/session/issues/25). diff --git a/src/pt-BR/guide/views/asset.md b/src/pt-BR/guide/views/asset.md index ee79c6d1..e75533a0 100644 --- a/src/pt-BR/guide/views/asset.md +++ b/src/pt-BR/guide/views/asset.md @@ -1,43 +1,42 @@ # Assets -Asset management is crucial for modern web applications. Assets include CSS -stylesheets, JavaScript files, images, fonts, and other static -resources. Yii3 provides a comprehensive asset management system through the -`yiisoft/assets` package that handles dependencies, optimization, and -deployment of these resources. +O gerenciamento de assets é essencial em aplicações web modernas. Assets +incluem folhas de estilo CSS, arquivos JavaScript, imagens, fontes e outros +recursos estáticos. O Yii3 oferece um sistema completo de gerenciamento de +assets por meio do pacote `yiisoft/assets`, que cuida das dependências, da +otimização e da publicação desses recursos. -## Installation +## Instalação -The asset management functionality is provided by the `yiisoft/assets` -package: +A funcionalidade de gerenciamento de assets vem do pacote `yiisoft/assets`: ```bash composer require yiisoft/assets ``` -This package is included by default in the `yiisoft/app` application -template. +Esse pacote já vem incluído por padrão no template de aplicação +`yiisoft/app`. -## Basic Concepts +## Conceitos básicos -### Asset Bundles +### Asset bundles -An asset bundle is a collection of related asset files (CSS, JavaScript, -images) that are logically grouped together. Asset bundles can depend on -other bundles, allowing for proper dependency management. +Um asset bundle é um conjunto de arquivos de asset relacionados (CSS, +JavaScript, imagens) agrupados logicamente. Asset bundles podem depender de +outros bundles, o que permite gerenciar as dependências corretamente. ### Asset Manager -The Asset Manager is responsible for: - Resolving asset bundle dependencies -- Publishing assets from protected directories to web-accessible locations - -Combining and minifying assets (when configured) - Generating proper URLs -for assets +O Asset Manager é responsável por: - Resolver as dependências dos asset +bundles - Publicar assets de diretórios protegidos em locais acessíveis pela +web - Combinar e minificar assets (quando configurado) - Gerar as URLs +corretas dos assets -## Creating Asset Bundles +## Criando asset bundles -### Basic Asset Bundle +### Asset bundle básico -Here's a simple asset bundle definition: +Esta é uma definição simples de asset bundle: ```php 'print'], ['css/admin/mobile.css', 'media' => 'screen and (max-width: 768px)'], ]; - // JavaScript files with attributes + // Arquivos JavaScript com atributos public array $js = [ 'js/admin/core.js', ['js/admin/charts.js', 'defer' => true], ['js/admin/analytics.js', 'async' => true], ]; - // Global options for all JS files in this bundle + // Opções globais para todos os arquivos JS deste bundle public array $jsOptions = [ 'data-admin' => 'true', ]; - // Global options for all CSS files in this bundle + // Opções globais para todos os arquivos CSS deste bundle public array $cssOptions = [ 'data-bundle' => 'admin', ]; @@ -136,11 +135,11 @@ final class AdminAsset extends AssetBundle } ``` -## Using Asset Bundles +## Usando asset bundles -### In Controllers +### Em controllers -Register asset bundles in your controllers or views: +Registre os asset bundles nos seus controllers ou views: ```php assetManager->register(MainAsset::class); return $this->viewRenderer->render('index', [ @@ -173,7 +172,7 @@ final class SiteController public function admin(): ResponseInterface { - // Register multiple asset bundles + // Registra vários asset bundles $this->assetManager->registerMany([ MainAsset::class, AdminAsset::class, @@ -184,9 +183,9 @@ final class SiteController } ``` -### In Views +### Em views -You can also register assets directly in views: +Você também pode registrar assets diretamente nas views: ```php register(ProductAsset::class); ?>

- +
``` -### With WebView Integration +### Com integração à WebView -The recommended approach is to integrate with WebView for automatic asset -rendering: +A abordagem recomendada é integrar com a WebView para que os assets sejam +renderizados automaticamente: ```php register(MainAsset::class); -// Add all registered assets to the view +// Adiciona todos os assets registrados à view $this->addCssFiles($assetManager->getCssFiles()); $this->addCssStrings($assetManager->getCssStrings()); $this->addJsFiles($assetManager->getJsFiles()); @@ -241,16 +240,16 @@ $this->addJsVars($assetManager->getJsVars()); ?>
- +
``` -## Asset Publishing +## Publicação de assets -### Source Path Publishing +### Publicação a partir do source path -When assets are located in non-web-accessible directories (like vendor -packages), they need to be published: +Quando os assets ficam em diretórios não acessíveis pela web (como pacotes +do vendor), eles precisam ser publicados: ```php publish('@vendor/company/package/assets'); -// Get the published URL +// Obtém a URL publicada $publishedUrl = $assetManager->getPublishedUrl('@vendor/company/package/assets'); ``` -## Third-party Library Assets +## Assets de bibliotecas de terceiros -### jQuery Asset Bundle +### Asset bundle do jQuery ```php [ - // Base path for published assets + // Caminho base dos assets publicados 'basePath' => '@webroot/assets', - // Base URL for assets + // URL base dos assets 'baseUrl' => '@web/assets', - // Asset converter configuration + // Configuração do conversor de assets 'converter' => [ 'commands' => [ 'scss' => ['sass', '{from}', '{to}', '--style=compressed'], @@ -420,9 +421,9 @@ return [ ]; ``` -### Environment-specific Assets +### Assets por ambiente -Configure different assets for different environments: +Configure assets diferentes para cada ambiente: ```php css = ['css/main.css', 'css/debug.css']; $this->js = ['js/main.js', 'js/debug.js']; } else { - // Production assets (minified) + // Assets de produção (minificados) $this->css = ['css/main.min.css']; $this->js = ['js/main.min.js']; } @@ -456,33 +457,33 @@ final class MainAsset extends AssetBundle } ``` -## Asset Optimization +## Otimização de assets -### Asset Combination +### Combinação de assets -Combine multiple CSS or JavaScript files into single files: +Combine vários arquivos CSS ou JavaScript em arquivos únicos: ```php /** * @var \Yiisoft\Assets\AssetManager $assetManager */ -// Enable asset combination +// Habilita a combinação de assets $assetManager->setCombine(true); -// Set combination options +// Define as opções de combinação $assetManager->setCombineOptions([ - 'css' => true, // Combine CSS files - 'js' => true, // Combine JavaScript files + 'css' => true, // Combina os arquivos CSS + 'js' => true, // Combina os arquivos JavaScript ]); ``` -### Asset Compression +### Compressão de assets -Configure asset compression for production: +Configure a compressão de assets para produção: ```php -// In your asset manager configuration +// Na configuração do seu asset manager 'converter' => [ 'commands' => [ 'css' => ['cleancss', '{from}', '-o', '{to}'], @@ -491,9 +492,9 @@ Configure asset compression for production: ], ``` -## Working with Asset Converter +## Trabalhando com o conversor de assets -### SCSS/SASS Compilation +### Compilação de SCSS/SASS ```php addCssFiles()` and `$this->addJsFiles()` in your layout -- Verify that `$this->head()`, `$this->beginBody()`, and `$this->endBody()` are called in the layout - -**Permission issues:** -- Check that the web server has write permissions to the assets directory -- Verify the published assets directory is web-accessible +## Boas práticas + +1. **Organize por funcionalidade**: agrupe assets relacionados em bundles + lógicos +2. **Gerencie as dependências**: declare corretamente as dependências entre + bundles +3. **Use nomes significativos**: dê nomes claros aos seus asset bundles +4. **Otimize por ambiente**: use assets minificados em produção +5. **Considere uma CDN**: use CDN para bibliotecas populares quando fizer + sentido +6. **Versione seus assets**: inclua números de versão nos nomes dos arquivos + para invalidar o cache +7. **Reduza as requisições HTTP**: combine assets relacionados quando + possível +8. **Otimize o tamanho dos arquivos**: comprima e minifique os assets para + produção + +## Solução de problemas + +### Problemas comuns + +**Asset não encontrado:** +- Verifique se o arquivo de asset existe no caminho especificado +- Confira se `$basePath` e `$baseUrl` estão configurados corretamente +- Garanta que os assets foram publicados se você usa `$sourcePath` + +**Dependências não carregam:** +- Confira se os bundles de dependência estão registrados corretamente +- Verifique se há dependências circulares +- Garanta que os bundles de dependência estão configurados corretamente + +**Assets não aparecem no HTML:** +- Verifique se você chama `$this->addCssFiles()` e `$this->addJsFiles()` no seu layout +- Confira se `$this->head()`, `$this->beginBody()` e `$this->endBody()` são chamados no layout + +**Problemas de permissão:** +- Verifique se o servidor web tem permissão de escrita no diretório de assets +- Confira se o diretório de assets publicados é acessível pela web diff --git a/src/pt-BR/guide/views/script-style-meta.md b/src/pt-BR/guide/views/script-style-meta.md index 4a899f47..82120fc7 100644 --- a/src/pt-BR/guide/views/script-style-meta.md +++ b/src/pt-BR/guide/views/script-style-meta.md @@ -1,26 +1,26 @@ -# Scripts, styles and meta tags +# Scripts, estilos e meta tags -Modern web applications require careful management of CSS styles, JavaScript -code, and HTML meta tags. Yii3 provides a comprehensive system for -registering and organizing these resources through the `WebView` class, -which is part of the `yiisoft/view` package. +Aplicações web modernas exigem um gerenciamento cuidadoso de estilos CSS, +código JavaScript e meta tags HTML. O Yii3 oferece um sistema completo para +registrar e organizar esses recursos por meio da classe `WebView`, que faz +parte do pacote `yiisoft/view`. -## Overview +## Visão geral -The `WebView` class extends the basic `View` class with web-specific -functionality, allowing you to: +A classe `WebView` estende a classe básica `View` com funcionalidades +específicas para a web, permitindo que você: -- Register CSS files and inline styles -- Register JavaScript files and inline scripts -- Manage HTML meta tags and link tags -- Control the position where resources are rendered -- Handle dependencies between resources +- Registre arquivos CSS e estilos inline +- Registre arquivos JavaScript e scripts inline +- Gerencie meta tags e link tags HTML +- Controle a posição em que os recursos são renderizados +- Lide com dependências entre recursos -## CSS management +## Gerenciamento de CSS -### Registering CSS Files +### Registrando arquivos CSS -You can register CSS files to be included in your HTML pages: +Você pode registrar arquivos CSS para incluí-los nas suas páginas HTML: ```php registerCssFile('/css/styles.css'); -// Register CSS file with attributes +// Registra um arquivo CSS com atributos $this->registerCssFile('/css/print.css', WebView::POSITION_HEAD, [ 'media' => 'print', ]); -// Register CSS file with custom key to avoid duplicates +// Registra um arquivo CSS com uma chave personalizada para evitar duplicatas $this->registerCssFile('/css/theme.css', WebView::POSITION_HEAD, [], 'theme-css'); ``` -### Registering Inline CSS +### Registrando CSS inline -For inline CSS styles, use the `registerCss()` method: +Para estilos CSS inline, use o método `registerCss()`: ```php -// Register inline CSS +// Registra CSS inline $this->registerCss(' .highlight { background-color: yellow; @@ -62,7 +62,7 @@ $this->registerCss(' } ', WebView::POSITION_HEAD); -// With custom attributes +// Com atributos personalizados $this->registerCss(' @media print { .no-print { display: none; } @@ -70,20 +70,20 @@ $this->registerCss(' ', WebView::POSITION_HEAD, ['id' => 'print-styles']); ``` -### CSS from Files +### CSS a partir de arquivos -You can also register CSS content from external files: +Você também pode registrar o conteúdo CSS de arquivos externos: ```php -// Read CSS from a file and register as inline CSS +// Lê o CSS de um arquivo e o registra como CSS inline $this->registerCssFromFile('/path/to/dynamic-styles.css', WebView::POSITION_HEAD, [ 'id' => 'dynamic-styles', ]); ``` -### Using Style Tags +### Usando tags style -For more control, you can use HTML style tags directly: +Para ter mais controle, você pode usar tags style do HTML diretamente: ```php use Yiisoft\Html\Html; @@ -100,37 +100,37 @@ $styleTag = Html::style(' $this->registerStyleTag($styleTag, WebView::POSITION_HEAD); ``` -## JavaScript management +## Gerenciamento de JavaScript -### Registering JavaScript Files +### Registrando arquivos JavaScript -Include external JavaScript files using `registerJsFile()`: +Inclua arquivos JavaScript externos com `registerJsFile()`: ```php -// Register a JavaScript file +// Registra um arquivo JavaScript $this->registerJsFile('/js/main.js'); -// Register with attributes (async loading) +// Registra com atributos (carregamento assíncrono) $this->registerJsFile('/js/analytics.js', WebView::POSITION_END, [ 'async' => true, ]); -// Register with defer attribute +// Registra com o atributo defer $this->registerJsFile('/js/interactive.js', WebView::POSITION_END, [ 'defer' => true, ]); -// Register from CDN +// Registra a partir de uma CDN $this->registerJsFile('https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js', WebView::POSITION_END, [], 'jquery'); ``` -### Registering Inline JavaScript +### Registrando JavaScript inline -Add inline JavaScript code with `registerJs()`: +Adicione código JavaScript inline com `registerJs()`: ```php -// Register inline JavaScript +// Registra JavaScript inline $this->registerJs(' document.addEventListener("DOMContentLoaded", function() { console.log("Page loaded!"); @@ -138,7 +138,7 @@ $this->registerJs(' }); ', WebView::POSITION_END); -// Register JavaScript that should run when DOM is ready +// Registra JavaScript que deve rodar quando o DOM estiver pronto $this->registerJs(' function showAlert(message) { alert(message); @@ -146,12 +146,12 @@ $this->registerJs(' ', WebView::POSITION_READY); ``` -### JavaScript Variables +### Variáveis JavaScript -Pass PHP data to JavaScript using `registerJsVar()`: +Passe dados do PHP para o JavaScript com `registerJsVar()`: ```php -// Register JavaScript variables +// Registra variáveis JavaScript $this->registerJsVar('apiUrl', 'https://api.example.com'); $this->registerJsVar('currentUser', [ 'id' => $user->getId(), @@ -164,7 +164,7 @@ $this->registerJsVar('config', [ ]); ``` -This generates JavaScript code like: +Isso gera um código JavaScript como este: ```html ``` -### Using Script Tags +### Usando tags script -For more control over script tags: +Para ter mais controle sobre as tags script: ```php use Yiisoft\Html\Html; @@ -192,30 +192,30 @@ $scriptTag = Html::script(' $this->registerScriptTag($scriptTag, WebView::POSITION_END); ``` -## Position Constants +## Constantes de posição -Resources can be positioned at different locations in the HTML document: +Os recursos podem ser posicionados em diferentes pontos do documento HTML: ```php use Yiisoft\View\WebView; -// In the section +// Na seção WebView::POSITION_HEAD -// At the beginning of +// No início do WebView::POSITION_BEGIN -// At the end of (before ) +// No fim do (antes de ) WebView::POSITION_END -// When DOM is ready (jQuery document.ready equivalent) +// Quando o DOM estiver pronto (equivalente ao document.ready do jQuery) WebView::POSITION_READY -// When page is fully loaded (window.onload equivalent) +// Quando a página terminar de carregar (equivalente ao window.onload) WebView::POSITION_LOAD ``` -Example layout showing where each position is rendered: +Exemplo de layout mostrando onde cada posição é renderizada: ```php - + head() ?> - + beginBody() ?>
- + endBody() ?> @@ -250,34 +250,34 @@ declare(strict_types=1); ## Meta tags -### Basic Meta Tags +### Meta tags básicas -Register meta tags for SEO and page information: +Registre meta tags para SEO e informações da página: ```php -// Register meta tags using array syntax +// Registra meta tags usando a sintaxe de array $this->registerMeta(['name' => 'description', 'content' => 'Page description']); $this->registerMeta(['name' => 'keywords', 'content' => 'yii, php, framework']); $this->registerMeta(['name' => 'author', 'content' => 'John Doe']); $this->registerMeta(['name' => 'robots', 'content' => 'index, follow']); -// Viewport for responsive design +// Viewport para design responsivo $this->registerMeta(['name' => 'viewport', 'content' => 'width=device-width, initial-scale=1']); -// Open Graph tags for social media +// Tags Open Graph para redes sociais $this->registerMeta(['property' => 'og:title', 'content' => 'Page Title']); $this->registerMeta(['property' => 'og:description', 'content' => 'Page description']); $this->registerMeta(['property' => 'og:image', 'content' => 'https://example.com/image.jpg']); ``` -### Using Meta Tag Objects +### Usando objetos de meta tag -For more control, use the `Html::meta()` helper: +Para ter mais controle, use o helper `Html::meta()`: ```php use Yiisoft\Html\Html; -// Create meta tags with the Html helper +// Cria meta tags com o helper Html $this->registerMetaTag( Html::meta() ->name('description') @@ -287,22 +287,22 @@ $this->registerMetaTag( $this->registerMetaTag( Html::meta() ->httpEquiv('refresh') - ->content('300') // Refresh every 5 minutes + ->content('300') // Atualiza a cada 5 minutos ); ``` -### Preventing Duplicate Meta Tags +### Evitando meta tags duplicadas -Use keys to prevent duplicate meta tags: +Use chaves para evitar meta tags duplicadas: ```php -// First registration +// Primeiro registro $this->registerMeta([ 'name' => 'description', 'content' => 'Original description' ], 'description'); -// This will override the previous one +// Este sobrescreve o anterior $this->registerMeta([ 'name' => 'description', 'content' => 'Updated description' @@ -311,9 +311,9 @@ $this->registerMeta([ ## Link tags -### Basic Link Tags +### Link tags básicas -Register various types of link tags: +Registre vários tipos de link tags: ```php // Favicon @@ -323,7 +323,7 @@ $this->registerLink([ 'href' => '/favicon.png', ]); -// RSS feed +// Feed RSS $this->registerLink([ 'rel' => 'alternate', 'type' => 'application/rss+xml', @@ -331,13 +331,13 @@ $this->registerLink([ 'href' => '/feed.rss', ]); -// Canonical URL +// URL canônica $this->registerLink([ 'rel' => 'canonical', 'href' => 'https://example.com/canonical-url', ]); -// Preload resources +// Pré-carregamento de recursos $this->registerLink([ 'rel' => 'preload', 'href' => '/fonts/main.woff2', @@ -347,19 +347,19 @@ $this->registerLink([ ]); ``` -### Using Link Tag Objects +### Usando objetos de link tag ```php use Yiisoft\Html\Html; -// CSS stylesheet +// Folha de estilo CSS $this->registerLinkTag( Html::link('/css/main.css', [ 'rel' => 'stylesheet', ]) ); -// DNS prefetch +// Prefetch de DNS $this->registerLinkTag( Html::link('https://fonts.googleapis.com', [ 'rel' => 'dns-prefetch', @@ -367,11 +367,11 @@ $this->registerLinkTag( ); ``` -## Practical Examples +## Exemplos práticos -### Complete Page Setup +### Configuração completa de uma página -Here's how you might set up a complete page with all types of resources: +Veja como montar uma página completa com todos os tipos de recursos: ```php setTitle($title); // Meta tags $this->registerMeta(['name' => 'description', 'content' => $description]); $this->registerMeta(['name' => 'keywords', 'content' => 'ecommerce, products, online shop']); -// Open Graph tags +// Tags Open Graph $this->registerMeta(['property' => 'og:title', 'content' => $title]); $this->registerMeta(['property' => 'og:description', 'content' => $description]); $this->registerMeta(['property' => 'og:image', 'content' => $product['image']]); -// CSS files +// Arquivos CSS $this->registerCssFile('/css/product.css'); $this->registerCssFile('/css/responsive.css', WebView::POSITION_HEAD, [ 'media' => 'screen and (max-width: 768px)', ]); -// JavaScript files +// Arquivos JavaScript $this->registerJsFile('/js/product-gallery.js', WebView::POSITION_END); $this->registerJsFile('/js/shopping-cart.js', WebView::POSITION_END); -// JavaScript variables +// Variáveis JavaScript $this->registerJsVar('productData', $product); $this->registerJsVar('cartApiUrl', '/api/cart'); -// Inline JavaScript +// JavaScript inline $this->registerJs(' document.addEventListener("DOMContentLoaded", function() { initProductGallery(); @@ -422,7 +422,7 @@ $this->registerJs(' }); ', WebView::POSITION_END); -// Page-specific styles +// Estilos específicos da página $this->registerCss(' .product-special { background: linear-gradient(45deg, #ff6b6b, #4ecdc4); @@ -433,13 +433,13 @@ $this->registerCss(' ?>
- +
``` -### Conditional Resource Loading +### Carregamento condicional de recursos -Load resources based on conditions: +Carregue recursos de acordo com condições: ```php registerCssFile('/css/dark-theme.css'); } else { $this->registerCssFile('/css/light-theme.css'); } -// Admin-specific resources +// Recursos específicos da área admin if ($isAdmin) { $this->registerCssFile('/css/admin-toolbar.css'); $this->registerJsFile('/js/admin-functions.js'); } -// Role-based JavaScript configuration +// Configuração JavaScript baseada no papel do usuário $this->registerJsVar('userPermissions', [ 'canEdit' => in_array($userRole, ['admin', 'editor']), 'canDelete' => $userRole === 'admin', @@ -475,31 +475,35 @@ $this->registerJsVar('userPermissions', [ ?> ``` -## Best Practices +## Boas práticas -1. **Use appropriate positions**: Place CSS in `POSITION_HEAD`, JavaScript - at `POSITION_END` -2. **Minimize inline resources**: Prefer external files for better caching -3. **Use keys for duplicates**: Prevent duplicate resources with meaningful - keys -4. **Optimize loading**: Use `async` and `defer` attributes for non-critical - JavaScript -5. **Group related resources**: Keep related CSS and JS files together -6. **Use CDNs wisely**: Balance performance with reliability -7. **Validate meta tags**: Ensure proper SEO meta tags are set -8. **Consider security**: Be careful with inline scripts and CSP policies +1. **Use as posições adequadas**: coloque o CSS em `POSITION_HEAD` e o + JavaScript em `POSITION_END` +2. **Reduza os recursos inline**: prefira arquivos externos, que aproveitam + melhor o cache +3. **Use chaves contra duplicatas**: evite recursos duplicados com chaves + significativas +4. **Otimize o carregamento**: use os atributos `async` e `defer` para + JavaScript não crítico +5. **Agrupe recursos relacionados**: mantenha juntos os arquivos CSS e JS + relacionados +6. **Use CDNs com critério**: equilibre desempenho e confiabilidade +7. **Valide as meta tags**: garanta que as meta tags de SEO estejam + definidas corretamente +8. **Pense na segurança**: tenha cuidado com scripts inline e políticas de + CSP -## Working with Asset Bundles +## Trabalhando com asset bundles -For more complex asset management, consider using asset bundles: +Para um gerenciamento de assets mais complexo, considere usar asset bundles: ```php -// Register an asset bundle (covered in detail in the Assets guide) +// Registra um asset bundle (explicado em detalhes no guia de Assets) $assetBundle = $this->assetManager->register(MainAsset::class); -// Add all CSS files from the bundle +// Adiciona todos os arquivos CSS do bundle $this->addCssFiles($this->assetManager->getCssFiles()); -// Add all JavaScript files from the bundle +// Adiciona todos os arquivos JavaScript do bundle $this->addJsFiles($this->assetManager->getJsFiles()); ``` diff --git a/src/pt-BR/guide/views/template-engines.md b/src/pt-BR/guide/views/template-engines.md index 9d15ee9f..ed4b9c17 100644 --- a/src/pt-BR/guide/views/template-engines.md +++ b/src/pt-BR/guide/views/template-engines.md @@ -1,27 +1,28 @@ # Template engines -Yii3 supports multiple template engines through a flexible renderer -system. By default, PHP is used as the template engine, but you can easily -add support for other engines like Twig and -[Blade](https://github.com/lee-to/yii-blade), or create your own custom +O Yii3 suporta várias template engines por meio de um sistema flexível de +renderers. Por padrão, o PHP é usado como template engine, mas você pode +adicionar suporte a outras engines como Twig e +[Blade](https://github.com/lee-to/yii-blade), ou criar seus próprios renderers. -PHP templates were described in the "[View](view.md)" guide section. +Os templates PHP foram descritos na seção "[View](view.md)" do guia. -## Twig Template Engine +## Template engine Twig -Twig is a modern template engine that provides a more designer-friendly -syntax. To use Twig in your Yii3 application, you need to install the Twig -extension. +O Twig é uma template engine moderna, com uma sintaxe mais amigável para +designers. Para usar o Twig na sua aplicação Yii3, instale a extensão do +Twig. ```bash composer require yiisoft/view-twig ``` -Now you can use `.twig` templates. For example, `views/site/about.twig`: +Agora você pode usar templates `.twig`. Por exemplo, +`views/site/about.twig`: ```twig -{# Variable type hints for IDE support #} +{# Dicas de tipo das variáveis para suporte na IDE #} {# @var user \App\Entity\User #} {# @var posts \App\Entity\Post[] #} @@ -46,32 +47,32 @@ Now you can use `.twig` templates. For example, `views/site/about.twig`: ``` -### Twig Features +### Recursos do Twig -**Automatic Escaping**: Twig automatically escapes variables for HTML context: +**Escape automático**: o Twig escapa as variáveis automaticamente para o contexto HTML: ```twig -{# Automatically escaped #} +{# Escapado automaticamente #}

{{ title }}

-{# Raw output (use carefully) #} +{# Saída bruta (use com cuidado) #}
{{ content|raw }}
``` -**Filters and Functions**: Twig provides many built-in filters and functions: +**Filtros e funções**: o Twig oferece muitos filtros e funções nativos: ```twig -{# Date formatting #} +{# Formatação de data #} -{# String manipulation #} +{# Manipulação de strings #}

{{ description|truncate(100) }}

-{# URL generation #} +{# Geração de URLs #} Profile ``` -**Template Inheritance**: Twig supports template inheritance: +**Herança de templates**: o Twig suporta herança de templates: **views/layout/main.twig** ```twig @@ -100,12 +101,12 @@ Now you can use `.twig` templates. For example, `views/site/about.twig`: {% endblock %} ``` -### Rendering Twig Templates +### Renderizando templates Twig -Use Twig templates the same way as PHP templates: +Use templates Twig da mesma forma que templates PHP: ```php -// In your controller +// No seu controller public function about(): ResponseInterface { return $this->viewRenderer->render('about.twig', [ @@ -115,9 +116,9 @@ public function about(): ResponseInterface } ``` -## Custom Template Engines +## Template engines personalizadas -You can create custom template engines by implementing the +Você pode criar template engines personalizadas implementando a `TemplateRendererInterface`: ```php @@ -139,7 +140,7 @@ final class MarkdownRenderer implements TemplateRendererInterface { $content = file_get_contents($template); - // Replace placeholders with parameters + // Substitui os placeholders pelos parâmetros foreach ($parameters as $key => $value) { $content = str_replace("{{$key}}", (string) $value, $content); } @@ -149,12 +150,12 @@ final class MarkdownRenderer implements TemplateRendererInterface } ``` -Register your custom renderer: +Registre o seu renderer personalizado: ```php use Yiisoft\Container\Reference; -// In configuration +// Na configuração 'yiisoft/view' => [ 'renderers' => [ 'md' => Reference::to(App\View\MarkdownRenderer::class), @@ -162,7 +163,7 @@ use Yiisoft\Container\Reference; ], ``` -Now you can use `.md` template files: +Agora você pode usar arquivos de template `.md`: **views/content/help.md** ```markdown @@ -177,31 +178,35 @@ This is a Markdown template with **bold** and *italic* text. - Feature 3 ``` -## Choosing the Right Template Engine - -**Use PHP templates when:** -- You need maximum flexibility and performance -- Your team is comfortable with PHP -- You want to leverage existing PHP knowledge -- You need complex logic in templates (though this should be minimized) - -**Use Twig templates when:** -- You want stricter separation between logic and presentation -- You work with designers who prefer cleaner syntax -- You need automatic escaping and security features -- You want template inheritance and advanced features - -**Use custom templates when:** -- You have specific requirements not met by PHP or Twig -- You're working with specialized content formats -- You need integration with external template systems - -## Best Practices - -1. **Keep templates simple**: Move complex logic to controllers or services -2. **Always escape output**: Prevent XSS attacks by properly escaping - variables -3. **Use meaningful names**: Name your templates and variables clearly -4. **Organize templates**: Group related templates in subdirectories -5. **Document variables**: Always add type hints for better IDE support -6. **Avoid business logic**: Keep business logic in models and services +## Escolhendo a template engine certa + +**Use templates PHP quando:** +- Você precisa do máximo de flexibilidade e desempenho +- Seu time está à vontade com PHP +- Você quer aproveitar o conhecimento de PHP que já tem +- Você precisa de lógica complexa nos templates (embora isso deva ser minimizado) + +**Use templates Twig quando:** +- Você quer uma separação mais rígida entre lógica e apresentação +- Você trabalha com designers que preferem uma sintaxe mais limpa +- Você precisa de escape automático e recursos de segurança +- Você quer herança de templates e recursos avançados + +**Use templates personalizados quando:** +- Você tem requisitos específicos que o PHP ou o Twig não atendem +- Você trabalha com formatos de conteúdo especializados +- Você precisa integrar com sistemas de template externos + +## Boas práticas + +1. **Mantenha os templates simples**: leve a lógica complexa para + controllers ou serviços +2. **Sempre escape a saída**: evite ataques XSS escapando as variáveis + corretamente +3. **Use nomes significativos**: dê nomes claros aos seus templates e + variáveis +4. **Organize os templates**: agrupe templates relacionados em subdiretórios +5. **Documente as variáveis**: sempre adicione dicas de tipo para um suporte + melhor da IDE +6. **Evite lógica de negócio**: mantenha a lógica de negócio em models e + serviços diff --git a/src/pt-BR/guide/views/view-injections.md b/src/pt-BR/guide/views/view-injections.md index 5a7e5f03..4d0429c0 100644 --- a/src/pt-BR/guide/views/view-injections.md +++ b/src/pt-BR/guide/views/view-injections.md @@ -1,21 +1,21 @@ -# View injections +# Injeções de view -The view injections are designed to provide a standardized way to pass -parameters to the common layer of views in an application. It allows -developers to manage the data that will be available across various views, -ensuring flexibility and reusability of code. +As injeções de view oferecem uma forma padronizada de passar parâmetros para +a camada comum das views de uma aplicação. Com elas, você gerencia os dados +que ficarão disponíveis em várias views, o que garante flexibilidade e +reaproveitamento de código. -The view injections could be used if you require `yiisoft/yii-view-renderer` -package: +Você pode usar as injeções de view se a sua aplicação exige o pacote +`yiisoft/yii-view-renderer`: ```sh composer require yiisoft/yii-view-renderer ``` -## Configuration +## Configuração -In config `params.php`: +Na configuração `params.php`: ```php @@ -29,17 +29,17 @@ In config `params.php`: ], ``` -## New injections +## Novas injeções -Start by defining a class that will implement the -`Yiisoft\Yii\View\Renderer\CommonParametersInjectionInterface`. This class -will be responsible for providing the parameters you want to inject into -your view templates and layouts. +Comece definindo uma classe que implemente +`Yiisoft\Yii\View\Renderer\CommonParametersInjectionInterface`. Essa classe +fornece os parâmetros que você quer injetar nos templates de view e nos +layouts. ```php class MyCustomParametersInjection implements Yiisoft\Yii\View\Renderer\CommonParametersInjectionInterface { - // Class properties and methods will go here + // As propriedades e os métodos da classe ficam aqui public function __construct(UserService $userService) { @@ -57,7 +57,7 @@ class MyCustomParametersInjection implements Yiisoft\Yii\View\Renderer\CommonPar } ``` -Add your new Injection to `params.php`: +Adicione a nova injeção ao `params.php`: ```php 'yiisoft/yii-view' => [ @@ -68,14 +68,14 @@ Add your new Injection to `params.php`: ], ``` -## Using Separate Injections for Different Layouts +## Usando injeções separadas para layouts diferentes -If your application has multiple layouts, you can create separate parameter -injections for each layout. This approach allows you to tailor the -parameters injected into each layout according to its specific needs, -enhancing the flexibility and maintainability of your application. +Se a sua aplicação tem vários layouts, você pode criar injeções de +parâmetros separadas para cada um. Assim, os parâmetros injetados em cada +layout atendem às necessidades específicas dele, o que deixa a aplicação +mais flexível e fácil de manter. -Create your custom ViewInjection for a specific layout: +Crie a sua ViewInjection personalizada para um layout específico: ```php readonly final class CartViewInjection implements CommonParametersInjectionInterface @@ -93,8 +93,8 @@ readonly final class CartViewInjection implements CommonParametersInjectionInter } ``` -Add your new injection to `params.php` under specific layout name. In the -following example, it's `@layout/cart`: +Adicione a nova injeção ao `params.php` sob o nome de um layout +específico. No exemplo a seguir, é `@layout/cart`: ```php 'yiisoft/yii-view' => [ @@ -106,7 +106,7 @@ following example, it's `@layout/cart`: ->get(Cart::class); return new LayoutSpecificInjections( - '@layout/cart', // layout name for injection + '@layout/cart', // nome do layout para a injeção new CartViewInjection($cart) ); diff --git a/src/pt-BR/guide/views/view.md b/src/pt-BR/guide/views/view.md index a68cf1c9..abe00f96 100644 --- a/src/pt-BR/guide/views/view.md +++ b/src/pt-BR/guide/views/view.md @@ -1,52 +1,53 @@ # Views -View is responsible for presenting data to end users. You give it a template -with some placeholders and presentation logic and some data. The view is -passing data to the template executing template logic. The end result is -ready to be passed to end user, be it a browser, a file to download, an -email to send or something else. +A view é responsável por apresentar os dados ao usuário final. Você entrega +a ela um template com alguns placeholders e lógica de apresentação, além de +alguns dados. A view passa os dados para o template e executa a lógica do +template. O resultado final está pronto para ser entregue ao usuário final, +seja um navegador, um arquivo para download, um e-mail a ser enviado ou +outra coisa. ```mermaid flowchart LR - A[Data] --> V[View] + A[Dados] --> V[View] B[Template] --> V V --> C[HTML] - C --> D[Browser] + C --> D[Navegador] ``` -In Yii3 views are typically PHP files that contain presentation logic and -HTML markup. The view system provides a flexible way to organize your -presentation layer and supports features like layouts and partial -views. Instead of using plain PHP templates, you can leverage one of the -template engines such as [Twig](template-engines.md) or +No Yii3, as views normalmente são arquivos PHP com lógica de apresentação e +marcação HTML. O sistema de views oferece uma forma flexível de organizar a +camada de apresentação e suporta recursos como layouts e views parciais. Em +vez de templates PHP puros, você pode usar uma das template engines, como +[Twig](template-engines.md) ou [Blade](https://github.com/lee-to/yii-blade). -## Installation +## Instalação -For basic view functionality, you need the `yiisoft/view` package: +Para a funcionalidade básica de views, você precisa do pacote +`yiisoft/view`: ```sh composer require yiisoft/view ``` -For web applications, you should also install the -`yiisoft/yii-view-renderer` package which provides -[PSR-7](https://www.php-fig.org/psr/psr-7/) compatibility and web-specific -features: +Em aplicações web, instale também o pacote `yiisoft/yii-view-renderer`, que +oferece compatibilidade com [PSR-7](https://www.php-fig.org/psr/psr-7/) e +recursos específicos para a web: ```sh composer require yiisoft/yii-view-renderer ``` -These packages are included by default in the `yiisoft/app` application -template. +Esses pacotes já vêm incluídos por padrão no template de aplicação +`yiisoft/app`. -## Basic Concepts +## Conceitos básicos -A view template file contains presentation logic. In the `yiisoft/app` -template, view files are typically stored alongside their controllers (e.g., -`src/Web/Echo/Action.php`). Here's a simple view file example, -`src/Web/Echo/template.php`: +Um arquivo de template de view contém lógica de apresentação. No template +`yiisoft/app`, os arquivos de view normalmente ficam junto dos seus +controllers (por exemplo, `src/Web/Echo/Action.php`). Este é um exemplo +simples de arquivo de view, `src/Web/Echo/template.php`: ```php The message is:

``` -Here `$message` is a view data that is passed when you render a template -with the help of `WebViewRenderer`. For example, `src/Web/Echo/Action.php`: +Aqui, `$message` é um dado da view passado quando você renderiza um template +com o `WebViewRenderer`. Por exemplo, `src/Web/Echo/Action.php`: ```php beginPage() endPage() ?> ``` -In the template above `$applicationParams` is an array of parameters from +No template acima, `$applicationParams` é um array de parâmetros de `config/common/application.php`. -`$aliases` refers to [aliases component](../concept/aliases.md) that is used -to get the base URL of the application at the server for URLs. +`$aliases` se refere ao [componente de aliases](../concept/aliases.md), +usado para obter a URL base da aplicação no servidor para montar URLs. -`$this` is an instance of the view that we use to get page title and output -assets. Both standard and custom. +`$this` é uma instância da view que usamos para obter o título da página e +gerar a saída dos assets, tanto os padrão quanto os personalizados. -With `$assetManager->register(MainAsset::class);` we register an asset that defines `css` to include to the page. It is -automatically copied to `public/assets` on first use. It is not very useful for a single CSS file but becomes handy as -the number of assets grows. +Com `$assetManager->register(MainAsset::class);` registramos um asset que define o `css` a ser incluído na página. Ele é +copiado automaticamente para `public/assets` no primeiro uso. Isso não ajuda muito com um único arquivo CSS, mas se torna útil +conforme o número de assets cresce. > [!IMPORTANT] -> No output in plain PHP templates is encoded you should not forget to use `Html::encode()` to prevent -XSS security vulnerabilities. +> Nenhuma saída em templates PHP puros é codificada, então não se esqueça de usar `Html::encode()` para evitar +vulnerabilidades de segurança do tipo XSS. -More about what's available in layout could be read in -[yiisoft/view](https://github.com/yiisoft/view) documentation. +Você encontra mais detalhes sobre o que está disponível no layout na +documentação do [yiisoft/view](https://github.com/yiisoft/view). -### Rendering without layout +### Renderizando sem layout -Sometimes you need to render a view without a layout (for example, for AJAX -responses): +Às vezes você precisa renderizar uma view sem layout (por exemplo, para +respostas AJAX): ```php public function ajaxContent(): ResponseInterface @@ -206,18 +208,18 @@ public function ajaxContent(): ResponseInterface ->render('ajax-content', ['data' => $data]); } -// Or use the renderPartial method +// Ou use o método renderPartial public function ajaxContent(): ResponseInterface { return $this->viewRenderer->renderPartial('ajax-content', ['data' => $data]); } ``` -## Nested Views and Partials +## Views aninhadas e parciais -### Rendering Sub-views +### Renderizando sub-views -You can render other views from within a view using the `$this->render()` method: +Você pode renderizar outras views de dentro de uma view com o método `$this->render()`: ```php ``` -### Using Blocks +### Usando blocos -Blocks allow you to define content in one view and display it in another, -typically in layouts: +Os blocos permitem definir conteúdo em uma view e exibi-lo em outra, +normalmente nos layouts: ```php -// In a view file +// Em um arquivo de view setBlock('sidebar', $this->render('_sidebar', ['items' => $sidebarItems])) ?> -// In the layout file +// No arquivo de layout hasBlock('sidebar')): ?> ``` -## Rendering as String +## Renderizando como string -If you need the rendered content as a string instead of a PSR-7 response: +Se você precisa do conteúdo renderizado como string em vez de uma resposta +PSR-7: ```php public function getEmailContent(): string @@ -284,21 +287,21 @@ public function getEmailContent(): string } ``` -## View Events +## Eventos de view -The view system triggers events during the rendering process that you can -listen to: +O sistema de views dispara eventos durante a renderização, e você pode +escutá-los: ```php use Yiisoft\View\Event\WebView\BeforeRender; use Yiisoft\View\Event\WebView\AfterRender; -// Example event listener +// Exemplo de listener de eventos final class ViewEventListener { public function onBeforeRender(BeforeRender $event): void { - // Add global CSS class based on view name + // Adiciona uma classe CSS global com base no nome da view if (str_contains($event->getFile(), 'admin/')) { $event->getView()->registerCssClass('admin-view'); } @@ -306,7 +309,7 @@ final class ViewEventListener public function onAfterRender(AfterRender $event): void { - // Log rendering time + // Registra no log o tempo de renderização $this->logger->info('View rendered', [ 'view' => $event->getFile(), 'time' => $event->getRenderTime(), diff --git a/src/pt-BR/guide/views/widget.md b/src/pt-BR/guide/views/widget.md index 9242128a..c63f1517 100644 --- a/src/pt-BR/guide/views/widget.md +++ b/src/pt-BR/guide/views/widget.md @@ -1,49 +1,51 @@ # Widgets -Widgets are reusable, self-contained components that encapsulate complex -HTML generation logic. They provide a clean way to create configurable UI -elements that can be used across different views and applications. Yii3 -provides a flexible widget system through the `yiisoft/widget` package. +Widgets são componentes reutilizáveis e autocontidos que encapsulam uma +lógica complexa de geração de HTML. Eles oferecem uma forma limpa de criar +elementos de interface configuráveis, que podem ser usados em diferentes +views e aplicações. O Yii3 oferece um sistema de widgets flexível por meio +do pacote `yiisoft/widget`. -## Installation +## Instalação -The widget functionality is provided by the `yiisoft/widget` package: +A funcionalidade de widgets vem do pacote `yiisoft/widget`: ```bash composer require yiisoft/widget ``` -For ready-made widgets (like forms, navigation, etc.), you can also install: +Para widgets prontos (como formulários, navegação etc.), você também pode +instalar: ```bash composer require yiisoft/yii-widgets ``` -These packages are included by default in the `yiisoft/app` application -template. +Esses pacotes já vêm incluídos por padrão no template de aplicação +`yiisoft/app`. -## Basic Concepts +## Conceitos básicos -### Widget Class +### Classe do widget -A widget is a PHP class that extends the abstract `Widget` class and -implements a `render()` method that returns HTML content as a string. +Um widget é uma classe PHP que estende a classe abstrata `Widget` e +implementa um método `render()` que devolve o conteúdo HTML como string. -### Widget Factory +### Widget factory -The `WidgetFactory` is responsible for creating widget instances and can -inject dependencies through the DI container. +A `WidgetFactory` é responsável por criar as instâncias dos widgets e pode +injetar dependências por meio do container de DI. -### Widget Configuration +### Configuração de widgets -Widgets can be configured with properties and methods, making them highly -customizable and reusable across different contexts. +Os widgets podem ser configurados com propriedades e métodos, o que os torna +altamente personalizáveis e reutilizáveis em diferentes contextos. -## Creating Custom Widgets +## Criando widgets próprios -### Simple Widget +### Widget simples -Here's a basic widget that displays an alert message: +Este é um widget básico que exibe uma mensagem de alerta: ```php ``` -### Widget with Dependencies +### Widget com dependências -Widgets can use dependency injection for services: +Os widgets podem usar injeção de dependência para receber serviços: ```php [ 'type()' => ['info'], @@ -239,7 +241,7 @@ $widgetDefaults = [ WidgetFactory::initialize($container, $widgetDefaults); ``` -### DI Container Configuration +### Configuração do container de DI **config/web/di.php** ```php @@ -247,7 +249,7 @@ use App\Widget\AlertWidget; use App\Widget\UserMenuWidget; return [ - // Widget configurations can be defined here if needed + // Configurações de widgets podem ser definidas aqui, se necessário AlertWidget::class => static fn() => new AlertWidget(), UserMenuWidget::class => static fn( @@ -257,11 +259,11 @@ return [ ]; ``` -## Advanced Widget Examples +## Exemplos avançados de widgets -### Data List Widget +### Widget de lista de dados -A widget that displays a list of items with pagination: +Um widget que exibe uma lista de itens com paginação: ```php ``` -### Form Widget +### Widget de formulário -A widget that simplifies form rendering: +Um widget que simplifica a renderização de formulários: ```php items as $index => $item) { if ($index === $itemCount - 1) { - // Last item (current page) - no link + // Último item (página atual) - sem link $links[] = Html::span($item['label'], ['class' => 'breadcrumb-item active']); } else { - // Regular breadcrumb item with link + // Item de breadcrumb comum, com link $url = isset($item['url']) ? (is_array($item['url']) ? $this->urlGenerator->generate($item['url'][0], $item['url'][1] ?? []) @@ -551,11 +553,11 @@ final class BreadcrumbWidget extends Widget } ``` -## Widget Best Practices +## Boas práticas com widgets -### Configuration Pattern +### Padrão de configuração -Use immutable configuration methods: +Use métodos de configuração imutáveis: ```php public function someProperty($value): self @@ -566,9 +568,9 @@ public function someProperty($value): self } ``` -### Validation +### Validação -Validate widget configuration in the render method: +Valide a configuração do widget no método render: ```php protected function render(): string @@ -577,13 +579,13 @@ protected function render(): string throw new InvalidArgumentException('Items cannot be empty.'); } - // ... render logic + // ... lógica de renderização } ``` -### HTML Encoding +### Codificação de HTML -Always encode user data: +Sempre codifique os dados vindos do usuário: ```php protected function render(): string @@ -594,9 +596,9 @@ protected function render(): string } ``` -### Asset Management +### Gerenciamento de assets -Register widget-specific assets: +Registre os assets específicos do widget: ```php assetManager->register(ChartWidgetAsset::class); - // Render widget content + // Renderiza o conteúdo do widget return $this->renderChart(); } } ``` -## Using Widgets in Layouts +## Usando widgets em layouts -Widgets are particularly useful in layouts for common UI elements: +Os widgets são especialmente úteis em layouts, para elementos de interface +comuns: **views/layout/main.php** ```php @@ -648,7 +651,7 @@ use App\Widget\UserMenuWidget; - +
@@ -667,11 +670,11 @@ use App\Widget\UserMenuWidget; ``` -## Testing Widgets +## Testando widgets -### Unit Testing +### Testes unitários -Test widget rendering logic: +Teste a lógica de renderização do widget: ```php viewRenderer->renderPartialAsString($template, $data); } ``` -### Event Integration +### Integração com eventos ```php protected function render(): string @@ -762,6 +765,7 @@ protected function render(): string } ``` -Widgets provide a powerful way to create reusable, configurable UI -components in Yii3 applications. They help maintain clean separation of -concerns and make your views more maintainable and testable. +Os widgets oferecem uma forma eficaz de criar componentes de interface +reutilizáveis e configuráveis em aplicações Yii3. Eles ajudam a manter uma +separação clara de responsabilidades e deixam suas views mais fáceis de +manter e testar. From 13e8c1b62f780361af08bc85f398bfb1c4369dfa Mon Sep 17 00:00:00 2001 From: Yuri Neves Date: Fri, 23 Oct 2026 14:18:15 -0300 Subject: [PATCH 07/11] Translate cookbook to Brazilian Portuguese --- ...okbook_configuring-webservers_apache.md.po | 58 +- ...kbook_configuring-webservers_general.md.po | 35 +- .../cookbook_configuring-webservers_iis.md.po | 37 +- ...book_configuring-webservers_lighttpd.md.po | 17 +- ...ok_configuring-webservers_nginx-unit.md.po | 68 +- ...ookbook_configuring-webservers_nginx.md.po | 59 +- .../pt-BR/cookbook_configuring-xdebug.md.po | 222 +++-- ...ookbook_custom-hydrator-type-casters.md.po | 448 ++++++++-- .../cookbook_custom-migration-template.md.po | 125 ++- ...okbook_deployment_angie-docker-proxy.md.po | 188 ++-- .../cookbook_deployment_autoscaling.md.po | 141 +-- ...okbook_deployment_docker-swarm-caddy.md.po | 800 +++++++++-------- ...book_deployment_docker-swarm-traefik.md.po | 813 +++++++++++------- .../cookbook_deployment_docker-swarm.md.po | 10 +- ...deployment_rolling-update-migrations.md.po | 190 ++-- .../cookbook_disabling-csrf-protection.md.po | 136 +-- .../pt-BR/cookbook_making-http-requests.md.po | 196 ++++- .../cookbook_opening-files-in-phpstorm.md.po | 99 ++- .../cookbook_organizing-code_domain.md.po | 81 +- .../cookbook_organizing-code_service.md.po | 101 ++- ...ing-by-use-case-with-vertical-slices.md.po | 68 +- _translations/po/pt-BR/cookbook_preface.md.po | 24 +- .../pt-BR/cookbook_sentry-integration.md.po | 114 ++- ...kbook_third-party-integrations_index.md.po | 14 +- ..._symfony-messenger-integration-guide.md.po | 331 ++++++- ..._symfony-scheduler-integration-guide.md.po | 303 +++++-- ...kbook_using-htmx-for-partial-reloads.md.po | 347 +++++++- ...okbook_using-yii-in-third-party-apps.md.po | 154 +++- .../pt-BR/cookbook_working-on-windows.md.po | 58 +- .../cookbook/configuring-webservers/apache.md | 44 +- .../configuring-webservers/general.md | 48 +- .../cookbook/configuring-webservers/iis.md | 20 +- .../configuring-webservers/lighttpd.md | 8 +- .../configuring-webservers/nginx-unit.md | 29 +- .../cookbook/configuring-webservers/nginx.md | 41 +- src/pt-BR/cookbook/configuring-xdebug.md | 209 ++--- .../cookbook/custom-hydrator-type-casters.md | 389 +++++---- .../cookbook/custom-migration-template.md | 69 +- .../cookbook/deployment/angie-docker-proxy.md | 157 ++-- src/pt-BR/cookbook/deployment/autoscaling.md | 200 ++--- .../cookbook/deployment/docker-swarm-caddy.md | 322 +++---- .../deployment/docker-swarm-traefik.md | 316 +++---- src/pt-BR/cookbook/deployment/docker-swarm.md | 6 +- .../deployment/rolling-update-migrations.md | 270 +++--- .../cookbook/disabling-csrf-protection.md | 161 ++-- src/pt-BR/cookbook/making-http-requests.md | 58 +- .../cookbook/opening-files-in-phpstorm.md | 90 +- src/pt-BR/cookbook/organizing-code/domain.md | 112 ++- src/pt-BR/cookbook/organizing-code/service.md | 82 +- ...turing-by-use-case-with-vertical-slices.md | 69 +- src/pt-BR/cookbook/preface.md | 37 +- src/pt-BR/cookbook/sentry-integration.md | 79 +- .../third-party-integrations/index.md | 16 +- .../symfony-messenger-integration-guide.md | 50 +- .../symfony-scheduler-integration-guide.md | 55 +- .../using-htmx-for-partial-reloads.md | 129 +-- .../cookbook/using-yii-in-third-party-apps.md | 125 +-- src/pt-BR/cookbook/working-on-windows.md | 93 +- 58 files changed, 5346 insertions(+), 3175 deletions(-) diff --git a/_translations/po/pt-BR/cookbook_configuring-webservers_apache.md.po b/_translations/po/pt-BR/cookbook_configuring-webservers_apache.md.po index 05ba666e..19b7dace 100644 --- a/_translations/po/pt-BR/cookbook_configuring-webservers_apache.md.po +++ b/_translations/po/pt-BR/cookbook_configuring-webservers_apache.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-10-15 10:10+0000\n" "PO-Revision-Date: 2026-10-15 10:10+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,12 +19,12 @@ msgstr "" #: ../src/cookbook/configuring-webservers/apache.md #, no-wrap msgid "Configuring web servers: Apache" -msgstr "" +msgstr "Configurando servidores web: Apache" #. type: Plain text #: ../src/cookbook/configuring-webservers/apache.md msgid "Use the following configuration in Apache's `httpd.conf` file or within a virtual host configuration. Note that you should replace `path/to/app/public` with the actual path for `app/public`." -msgstr "" +msgstr "Use a configuração a seguir no arquivo `httpd.conf` do Apache ou na configuração de um virtual host. Substitua `path/to/app/public` pelo caminho real de `app/public`." #. type: Fenced code block (apache) #: ../src/cookbook/configuring-webservers/apache.md @@ -53,11 +53,33 @@ msgid "" " # ...other settings...\n" "\n" msgstr "" +"# Define o document root como \"app/public\"\n" +"DocumentRoot \"path/to/app/public\"\n" +"\n" +"\n" +" # usa mod_rewrite para suportar URLs amigáveis\n" +" RewriteEngine on\n" +" \n" +" # Não permite acesso a URLs com o nome do script\n" +" RewriteCond %{THE_REQUEST} index.php [NC]\n" +" RewriteRule . - [R=404,L]\n" +" \n" +" # Se um diretório ou arquivo existir, usa a requisição diretamente\n" +" RewriteCond %{REQUEST_FILENAME} !-f\n" +" RewriteCond %{REQUEST_FILENAME} !-d\n" +" \n" +" # Caso contrário, encaminha a requisição para index.php\n" +" RewriteRule . index.php\n" +" \n" +" SetEnv APP_ENV dev\n" +"\n" +" # ...outras configurações...\n" +"\n" #. type: Plain text #: ../src/cookbook/configuring-webservers/apache.md msgid "In case you have `AllowOverride All` you can add `.htaccess` file with the following configuration instead of using `httpd.conf`:" -msgstr "" +msgstr "Se você tiver `AllowOverride All`, pode adicionar um arquivo `.htaccess` com a configuração a seguir em vez de usar o `httpd.conf`:" #. type: Fenced code block (apache) #: ../src/cookbook/configuring-webservers/apache.md @@ -81,16 +103,30 @@ msgid "" "\n" "# ...other settings...\n" msgstr "" +"# usa mod_rewrite para suportar URLs amigáveis\n" +"RewriteEngine on\n" +"\n" +"# Não permite acesso a URLs com o nome do script\n" +"RewriteCond %{THE_REQUEST} index.php [NC]\n" +"RewriteRule . - [R=404,L]\n" +"\n" +"# Se um diretório ou arquivo existir, usa a requisição diretamente\n" +"RewriteCond %{REQUEST_FILENAME} !-f\n" +"RewriteCond %{REQUEST_FILENAME} !-d\n" +"\n" +"# Caso contrário, encaminha a requisição para index.php\n" +"RewriteRule . index.php\n" +"\n" +"SetEnv APP_ENV dev\n" +"\n" +"# ...outras configurações...\n" #. type: Plain text #: ../src/cookbook/configuring-webservers/apache.md msgid "In the above, note the usage of `SetEnv`. Since Yii3 application templates use environment variables, this is a possible place to set them. In production environment remember to set `APP_ENV` to `prod`." -msgstr "" +msgstr "Observe o uso de `SetEnv` acima. Como os templates de aplicação do Yii3 usam variáveis de ambiente, este é um lugar possível para defini-las. Em produção, lembre-se de definir `APP_ENV` como `prod`." #. type: Plain text -#: ../src/cookbook/configuring-webservers/apache.md -#: ../src/cookbook/configuring-webservers/iis.md -#: ../src/cookbook/configuring-webservers/lighttpd.md -#: ../src/cookbook/configuring-webservers/nginx-unit.md +#: ../src/cookbook/configuring-webservers/apache.md ../src/cookbook/configuring-webservers/iis.md ../src/cookbook/configuring-webservers/lighttpd.md ../src/cookbook/configuring-webservers/nginx-unit.md msgid "See [application logs](general.md#application-logs) for logging configuration." -msgstr "" +msgstr "Veja [logs da aplicação](general.md#logs-da-aplicacao) para a configuração de logs." diff --git a/_translations/po/pt-BR/cookbook_configuring-webservers_general.md.po b/_translations/po/pt-BR/cookbook_configuring-webservers_general.md.po index 62ba593b..fe40cfba 100644 --- a/_translations/po/pt-BR/cookbook_configuring-webservers_general.md.po +++ b/_translations/po/pt-BR/cookbook_configuring-webservers_general.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-10-15 10:10+0000\n" "PO-Revision-Date: 2026-10-15 10:10+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,12 +19,12 @@ msgstr "" #: ../src/cookbook/configuring-webservers/general.md #, no-wrap msgid "Configuring web servers: General" -msgstr "" +msgstr "Configurando servidores web: geral" #. type: Plain text #: ../src/cookbook/configuring-webservers/general.md msgid "On a production server, if you don't use Docker, configure your web server to serve only the application's public files. Point the document root of your web server to the `app/public` folder." -msgstr "" +msgstr "Em um servidor de produção, se você não usa Docker, configure seu servidor web para servir apenas os arquivos públicos da aplicação. Aponte o document root do servidor web para a pasta `app/public`." #. type: Plain text #: ../src/cookbook/configuring-webservers/general.md @@ -34,67 +34,70 @@ msgid "" "> If you're running your Yii application behind a reverse proxy, you might need to configure\n" "> [Trusted proxies and headers](../../guide/security/trusted-request.md).\n" msgstr "" +"> [!IMPORTANT]\n" +"> Se você executa sua aplicação Yii atrás de um proxy reverso, pode ser necessário configurar\n" +"> [proxies e headers confiáveis](../../guide/security/trusted-request.md).\n" #. type: Title ## #: ../src/cookbook/configuring-webservers/general.md #, no-wrap msgid "Application logs" -msgstr "" +msgstr "Logs da aplicação" #. type: Plain text #: ../src/cookbook/configuring-webservers/general.md msgid "Yii3 application templates write application logs to standard output (`stdout`, or `php://stdout`) by default. They don't create application log files. Standard error (`stderr`) requires explicit log target configuration. Docker collects container output, but on a server without containers you must configure where that output goes or [configure a file target](../../guide/runtime/logging.md#logging-to-files). Web server access and error log settings don't configure Yii's log targets." -msgstr "" +msgstr "Os templates de aplicação do Yii3 escrevem os logs da aplicação na saída padrão (`stdout`, ou `php://stdout`) por padrão. Eles não criam arquivos de log da aplicação. A saída de erro padrão (`stderr`) exige configuração explícita de destino de log. O Docker coleta a saída dos containers, mas em um servidor sem containers você precisa configurar para onde essa saída vai ou [configurar um destino de arquivo](../../guide/runtime/logging.md#logs-em-arquivos). As configurações de log de acesso e de erro do servidor web não configuram os destinos de log do Yii." #. type: Title ### #: ../src/cookbook/configuring-webservers/general.md #, no-wrap msgid "PHP-FPM" -msgstr "" +msgstr "PHP-FPM" #. type: Plain text #: ../src/cookbook/configuring-webservers/general.md msgid "If your web server uses PHP-FPM, enable worker output capture in the application's PHP-FPM pool configuration:" -msgstr "" +msgstr "Se o seu servidor web usa PHP-FPM, habilite a captura da saída dos workers na configuração do pool PHP-FPM da aplicação:" #. type: Fenced code block (ini) #: ../src/cookbook/configuring-webservers/general.md #, no-wrap msgid "catch_workers_output = yes\n" -msgstr "" +msgstr "catch_workers_output = yes\n" #. type: Plain text #: ../src/cookbook/configuring-webservers/general.md msgid "Reload PHP-FPM after changing its configuration. PHP-FPM sends worker standard output and standard error to its main error log. The `error_log` directive in `php-fpm.conf` sets the destination. Without this setting, PHP-FPM redirects both streams to `/dev/null` by default. See the [PHP-FPM configuration reference](https://www.php.net/manual/en/install.fpm.configuration.php)." -msgstr "" +msgstr "Recarregue o PHP-FPM depois de alterar a configuração. O PHP-FPM envia a saída padrão e a saída de erro dos workers para o seu log de erro principal. A diretiva `error_log` em `php-fpm.conf` define o destino. Sem essa configuração, o PHP-FPM redireciona as duas saídas para `/dev/null` por padrão. Veja a [referência de configuração do PHP-FPM](https://www.php.net/manual/en/install.fpm.configuration.php)." #. type: Title ## #: ../src/cookbook/configuring-webservers/general.md #, no-wrap msgid "Specific server configurations" -msgstr "" +msgstr "Configurações específicas de servidores" #. type: Bullet: '- ' #: ../src/cookbook/configuring-webservers/general.md msgid "[Nginx](nginx.md)" -msgstr "" +msgstr "[Nginx](nginx.md)" #. type: Bullet: '- ' #: ../src/cookbook/configuring-webservers/general.md msgid "[Apache](apache.md)" -msgstr "" +msgstr "[Apache](apache.md)" #. type: Bullet: '- ' #: ../src/cookbook/configuring-webservers/general.md msgid "[Lighttpd](lighttpd.md)" -msgstr "" +msgstr "[Lighttpd](lighttpd.md)" #. type: Bullet: '- ' #: ../src/cookbook/configuring-webservers/general.md msgid "[Nginx Unit](nginx-unit.md)" -msgstr "" +msgstr "[Nginx Unit](nginx-unit.md)" #. type: Bullet: '- ' #: ../src/cookbook/configuring-webservers/general.md msgid "[IIS](iis.md)" -msgstr "" +msgstr "[IIS](iis.md)" diff --git a/_translations/po/pt-BR/cookbook_configuring-webservers_iis.md.po b/_translations/po/pt-BR/cookbook_configuring-webservers_iis.md.po index 2b9e5617..02d01538 100644 --- a/_translations/po/pt-BR/cookbook_configuring-webservers_iis.md.po +++ b/_translations/po/pt-BR/cookbook_configuring-webservers_iis.md.po @@ -8,31 +8,28 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-10-15 10:10+0000\n" "PO-Revision-Date: 2026-10-15 10:10+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Plain text -#: ../src/cookbook/configuring-webservers/apache.md -#: ../src/cookbook/configuring-webservers/iis.md -#: ../src/cookbook/configuring-webservers/lighttpd.md -#: ../src/cookbook/configuring-webservers/nginx-unit.md +#: ../src/cookbook/configuring-webservers/apache.md ../src/cookbook/configuring-webservers/iis.md ../src/cookbook/configuring-webservers/lighttpd.md ../src/cookbook/configuring-webservers/nginx-unit.md msgid "See [application logs](general.md#application-logs) for logging configuration." -msgstr "" +msgstr "Veja [logs da aplicação](general.md#logs-da-aplicacao) para a configuração de logs." #. type: Title # #: ../src/cookbook/configuring-webservers/iis.md #, no-wrap msgid "Configuring web servers: IIS" -msgstr "" +msgstr "Configurando servidores web: IIS" #. type: Plain text #: ../src/cookbook/configuring-webservers/iis.md msgid "When you use [IIS](https://www.iis.net/), host the application in a virtual host (Website) where the document root points to the `path/to/app/public` folder and configure the website to run PHP. In that `public` folder, place a file named `web.config` at `path/to/app/public/web.config`. Use the following content:" -msgstr "" +msgstr "Ao usar o [IIS](https://www.iis.net/), hospede a aplicação em um virtual host (Website) cujo document root aponte para a pasta `path/to/app/public` e configure o site para executar PHP. Nessa pasta `public`, coloque um arquivo chamado `web.config` em `path/to/app/public/web.config`. Use o seguinte conteúdo:" #. type: Fenced code block (xml) #: ../src/cookbook/configuring-webservers/iis.md @@ -59,8 +56,28 @@ msgid "" " \n" "\n" msgstr "" +"\n" +"\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" #. type: Plain text #: ../src/cookbook/configuring-webservers/iis.md msgid "Also, [IIS documentation](https://learn.microsoft.com/en-us/iis/) could be useful to configure PHP on IIS." -msgstr "" +msgstr "A [documentação do IIS](https://learn.microsoft.com/en-us/iis/) também pode ser útil para configurar o PHP no IIS." diff --git a/_translations/po/pt-BR/cookbook_configuring-webservers_lighttpd.md.po b/_translations/po/pt-BR/cookbook_configuring-webservers_lighttpd.md.po index a6e025df..61eab00b 100644 --- a/_translations/po/pt-BR/cookbook_configuring-webservers_lighttpd.md.po +++ b/_translations/po/pt-BR/cookbook_configuring-webservers_lighttpd.md.po @@ -8,35 +8,32 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-10-15 10:10+0000\n" "PO-Revision-Date: 2026-10-15 10:10+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Plain text -#: ../src/cookbook/configuring-webservers/apache.md -#: ../src/cookbook/configuring-webservers/iis.md -#: ../src/cookbook/configuring-webservers/lighttpd.md -#: ../src/cookbook/configuring-webservers/nginx-unit.md +#: ../src/cookbook/configuring-webservers/apache.md ../src/cookbook/configuring-webservers/iis.md ../src/cookbook/configuring-webservers/lighttpd.md ../src/cookbook/configuring-webservers/nginx-unit.md msgid "See [application logs](general.md#application-logs) for logging configuration." -msgstr "" +msgstr "Veja [logs da aplicação](general.md#logs-da-aplicacao) para a configuração de logs." #. type: Title # #: ../src/cookbook/configuring-webservers/lighttpd.md #, no-wrap msgid "Configuring web servers: lighttpd" -msgstr "" +msgstr "Configurando servidores web: lighttpd" #. type: Plain text #: ../src/cookbook/configuring-webservers/lighttpd.md #, no-wrap msgid "To use [lighttpd](https://www.lighttpd.net/) >= 1.4.24, put `index.php` in the web root and add the following to the configuration:\n" -msgstr "" +msgstr "Para usar o [lighttpd](https://www.lighttpd.net/) >= 1.4.24, coloque o `index.php` na raiz web e adicione o seguinte à configuração:\n" #. type: Fenced code block #: ../src/cookbook/configuring-webservers/lighttpd.md #, no-wrap msgid "url.rewrite-if-not-file = (\"(.*)\" => \"/index.php/$0\")\n" -msgstr "" +msgstr "url.rewrite-if-not-file = (\"(.*)\" => \"/index.php/$0\")\n" diff --git a/_translations/po/pt-BR/cookbook_configuring-webservers_nginx-unit.md.po b/_translations/po/pt-BR/cookbook_configuring-webservers_nginx-unit.md.po index ca9d0a9f..f07ca3a6 100644 --- a/_translations/po/pt-BR/cookbook_configuring-webservers_nginx-unit.md.po +++ b/_translations/po/pt-BR/cookbook_configuring-webservers_nginx-unit.md.po @@ -8,36 +8,33 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-10-15 10:10+0000\n" "PO-Revision-Date: 2026-10-15 10:10+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Plain text -#: ../src/cookbook/configuring-webservers/apache.md -#: ../src/cookbook/configuring-webservers/iis.md -#: ../src/cookbook/configuring-webservers/lighttpd.md -#: ../src/cookbook/configuring-webservers/nginx-unit.md +#: ../src/cookbook/configuring-webservers/apache.md ../src/cookbook/configuring-webservers/iis.md ../src/cookbook/configuring-webservers/lighttpd.md ../src/cookbook/configuring-webservers/nginx-unit.md msgid "See [application logs](general.md#application-logs) for logging configuration." -msgstr "" +msgstr "Veja [logs da aplicação](general.md#logs-da-aplicacao) para a configuração de logs." #. type: Title # #: ../src/cookbook/configuring-webservers/nginx-unit.md #, no-wrap msgid "Configuring web servers: NGINX Unit and FreeUnit" -msgstr "" +msgstr "Configurando servidores web: NGINX Unit e FreeUnit" #. type: Plain text #: ../src/cookbook/configuring-webservers/nginx-unit.md msgid "Run Yii-based apps using [NGINX Unit](https://unit.nginx.org/) with a PHP language module. The same configuration format is used by [FreeUnit](https://github.com/freeunitorg/freeunit), a community LTS fork of Unit. With FreeUnit Docker images, such as `ghcr.io/freeunitorg/freeunit:latest-php8.5`, put the configuration in `/var/lib/unit/config.json`." -msgstr "" +msgstr "Execute aplicações baseadas em Yii usando o [NGINX Unit](https://unit.nginx.org/) com um módulo de linguagem PHP. O mesmo formato de configuração é usado pelo [FreeUnit](https://github.com/freeunitorg/freeunit), um fork LTS do Unit mantido pela comunidade. Com as imagens Docker do FreeUnit, como `ghcr.io/freeunitorg/freeunit:latest-php8.5`, coloque a configuração em `/var/lib/unit/config.json`." #. type: Plain text #: ../src/cookbook/configuring-webservers/nginx-unit.md msgid "Here is a sample configuration." -msgstr "" +msgstr "Aqui está um exemplo de configuração." #. type: Fenced code block (json) #: ../src/cookbook/configuring-webservers/nginx-unit.md @@ -91,13 +88,60 @@ msgid "" " }\n" "}\n" msgstr "" +"{\n" +" \"listeners\": {\n" +" \"*:80\": {\n" +" \"pass\": \"routes\"\n" +" }\n" +" },\n" +"\n" +" \"routes\": [\n" +" {\n" +" \"match\": {\n" +" \"uri\": [\n" +" \"!/assets/*\",\n" +" \"*.php\",\n" +" \"*.php/*\"\n" +" ]\n" +" },\n" +"\n" +" \"action\": {\n" +" \"pass\": \"applications/yii/direct\"\n" +" }\n" +" },\n" +" {\n" +" \"action\": {\n" +" \"share\": \"/path/to/app/public$uri\",\n" +" \"fallback\": {\n" +" \"pass\": \"applications/yii/index\"\n" +" }\n" +" }\n" +" }\n" +" ],\n" +"\n" +" \"applications\": {\n" +" \"yii\": {\n" +" \"type\": \"php\",\n" +" \"targets\": {\n" +" \"direct\": {\n" +" \"root\": \"/path/to/app/public/\"\n" +" },\n" +"\n" +" \"index\": {\n" +" \"root\": \"/path/to/app/public/\",\n" +" \"script\": \"index.php\"\n" +" }\n" +" }\n" +" }\n" +" }\n" +"}\n" #. type: Plain text #: ../src/cookbook/configuring-webservers/nginx-unit.md msgid "You can also [set up](https://unit.nginx.org/configuration/#php) your PHP environment or supply a custom `php.ini` in the same configuration." -msgstr "" +msgstr "Você também pode [configurar](https://unit.nginx.org/configuration/#php) o ambiente PHP ou fornecer um `php.ini` personalizado na mesma configuração." #. type: Plain text #: ../src/cookbook/configuring-webservers/nginx-unit.md msgid "Since Yii3 application templates use environment variables, you can set them in `applications.yii.environment`. In a production environment, remember to set `APP_ENV` to `prod`." -msgstr "" +msgstr "Como os templates de aplicação do Yii3 usam variáveis de ambiente, você pode defini-las em `applications.yii.environment`. Em produção, lembre-se de definir `APP_ENV` como `prod`." diff --git a/_translations/po/pt-BR/cookbook_configuring-webservers_nginx.md.po b/_translations/po/pt-BR/cookbook_configuring-webservers_nginx.md.po index b42ff0a9..b00b8550 100644 --- a/_translations/po/pt-BR/cookbook_configuring-webservers_nginx.md.po +++ b/_translations/po/pt-BR/cookbook_configuring-webservers_nginx.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-10-15 10:10+0000\n" "PO-Revision-Date: 2026-10-15 10:10+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,12 +19,12 @@ msgstr "" #: ../src/cookbook/configuring-webservers/nginx.md #, no-wrap msgid "Configuring web servers: Nginx" -msgstr "" +msgstr "Configurando servidores web: Nginx" #. type: Plain text #: ../src/cookbook/configuring-webservers/nginx.md msgid "To use [Nginx](https:/nginx.org/), install PHP as an [FPM SAPI](https://secure.php.net/install.fpm). Use the following Nginx configuration, replacing `path/to/app/public` with the actual path for `app/public` and `mysite.test` with the actual hostname to serve." -msgstr "" +msgstr "Para usar o [Nginx](https:/nginx.org/), instale o PHP como [FPM SAPI](https://secure.php.net/install.fpm). Use a configuração do Nginx a seguir, substituindo `path/to/app/public` pelo caminho real de `app/public` e `mysite.test` pelo hostname real a ser servido." #. type: Fenced code block (nginx) #: ../src/cookbook/configuring-webservers/nginx.md @@ -74,23 +74,66 @@ msgid "" " }\n" "}\n" msgstr "" +"server {\n" +" charset utf-8;\n" +" client_max_body_size 128M;\n" +"\n" +" listen 80; ## escuta em ipv4\n" +" #listen [::]:80 default_server ipv6only=on; ## escuta em ipv6\n" +"\n" +" server_name mysite.test;\n" +" root /path/to/app/public;\n" +" index index.php;\n" +"\n" +" access_log /path/to/basic/log/access.log;\n" +" error_log /path/to/basic/log/error.log;\n" +"\n" +" location / {\n" +" # Redireciona para index.php tudo que não for um arquivo real\n" +" try_files $uri $uri/ /index.php$is_args$args;\n" +" }\n" +"\n" +" # descomente para evitar que o Yii processe chamadas a arquivos estáticos inexistentes\n" +" #location ~ \\.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {\n" +" # try_files $uri =404;\n" +" #}\n" +" #error_page 404 /404.html;\n" +"\n" +" # bloqueia o acesso a arquivos php no diretório /assets\n" +" location ~ ^/assets/.*\\.php$ {\n" +" deny all;\n" +" }\n" +"\n" +" location ~ \\.php$ {\n" +" include fastcgi_params;\n" +" fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;\n" +" fastcgi_pass 127.0.0.1:9000;\n" +" #fastcgi_pass unix:/var/run/php8-fpm.sock;\n" +" try_files $uri =404;\n" +" fastcgi_param APP_ENV \"dev\";\n" +" }\n" +"\n" +" location ~* /\\. {\n" +" deny all;\n" +" }\n" +"}\n" #. type: Plain text #: ../src/cookbook/configuring-webservers/nginx.md msgid "When you use this configuration, also set `cgi.fix_pathinfo=0` in the `php.ini` file to avoid many unnecessary system `stat()` calls." -msgstr "" +msgstr "Ao usar essa configuração, defina também `cgi.fix_pathinfo=0` no arquivo `php.ini` para evitar muitas chamadas de sistema `stat()` desnecessárias." #. type: Plain text #: ../src/cookbook/configuring-webservers/nginx.md msgid "Also, note that when running an HTTPS server, you need to add `fastcgi_param HTTPS on;` so that Yii can detect if a connection is secure." -msgstr "" +msgstr "Além disso, ao executar um servidor HTTPS, você precisa adicionar `fastcgi_param HTTPS on;` para que o Yii consiga detectar se a conexão é segura." #. type: Plain text #: ../src/cookbook/configuring-webservers/nginx.md msgid "In the above, note the usage of `fastcgi_param APP_ENV`. Since Yii3 application templates use environment variables, this is a possible place to set them. In production environment remember to set `APP_ENV` to `prod`." -msgstr "" +msgstr "Observe o uso de `fastcgi_param APP_ENV` acima. Como os templates de aplicação do Yii3 usam variáveis de ambiente, este é um lugar possível para defini-las. Em produção, lembre-se de definir `APP_ENV` como `prod`." #. type: Plain text #: ../src/cookbook/configuring-webservers/nginx.md msgid "The Nginx `access_log` and `error_log` directives above don't capture PHP-FPM worker output. See [application logs](general.md#application-logs) for logging configuration." -msgstr "" +msgstr "As diretivas `access_log` e `error_log` do Nginx acima não capturam a saída dos workers do PHP-FPM. Veja [logs da aplicação](general.md#logs-da-aplicacao) para a configuração de logs." diff --git a/_translations/po/pt-BR/cookbook_configuring-xdebug.md.po b/_translations/po/pt-BR/cookbook_configuring-xdebug.md.po index a270cba1..652f5695 100644 --- a/_translations/po/pt-BR/cookbook_configuring-xdebug.md.po +++ b/_translations/po/pt-BR/cookbook_configuring-xdebug.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-05-07 14:37+0000\n" "PO-Revision-Date: 2026-05-07 14:37+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,33 +19,33 @@ msgstr "" #: ../src/cookbook/configuring-xdebug.md #, no-wrap msgid "Configuring Xdebug" -msgstr "" +msgstr "Configurando o Xdebug" #. type: Plain text #: ../src/cookbook/configuring-xdebug.md msgid "Xdebug lets an IDE stop PHP code on breakpoints while the application handles a web request, console command, or test. The IDE listens for debug connections. PHP starts the request and Xdebug connects back to the IDE." -msgstr "" +msgstr "O Xdebug permite que a IDE pare o código PHP em breakpoints enquanto a aplicação processa uma requisição web, um comando de console ou um teste. A IDE escuta conexões de depuração. O PHP inicia a requisição e o Xdebug se conecta de volta à IDE." #. type: Plain text #: ../src/cookbook/configuring-xdebug.md msgid "Yii works with the regular Xdebug setup. Configure Xdebug for the PHP runtime that executes the code and make sure the IDE can map runtime paths to project files." -msgstr "" +msgstr "O Yii funciona com a configuração comum do Xdebug. Configure o Xdebug no runtime PHP que executa o código e garanta que a IDE consiga mapear os caminhos do runtime para os arquivos do projeto." #. type: Title ## #: ../src/cookbook/configuring-xdebug.md #, no-wrap msgid "Check Xdebug" -msgstr "" +msgstr "Verificando o Xdebug" #. type: Plain text #: ../src/cookbook/configuring-xdebug.md msgid "Use Xdebug 3. The default debug port is `9003`." -msgstr "" +msgstr "Use o Xdebug 3. A porta de depuração padrão é `9003`." #. type: Plain text #: ../src/cookbook/configuring-xdebug.md msgid "Without Docker, install Xdebug for the PHP executable that runs the application, then check it:" -msgstr "" +msgstr "Sem Docker, instale o Xdebug no executável PHP que roda a aplicação e depois verifique:" #. type: Fenced code block (shell) #: ../src/cookbook/configuring-xdebug.md @@ -54,11 +54,13 @@ msgid "" "php --version\n" "php --ri xdebug\n" msgstr "" +"php --version\n" +"php --ri xdebug\n" #. type: Plain text #: ../src/cookbook/configuring-xdebug.md msgid "In `php.ini` or an Xdebug-specific ini file, enable step debugging:" -msgstr "" +msgstr "No `php.ini` ou em um arquivo ini específico do Xdebug, habilite a depuração passo a passo:" #. type: Fenced code block (ini) #: ../src/cookbook/configuring-xdebug.md @@ -69,16 +71,20 @@ msgid "" "xdebug.client_host=127.0.0.1\n" "xdebug.client_port=9003\n" msgstr "" +"xdebug.mode=develop,debug\n" +"xdebug.start_with_request=trigger\n" +"xdebug.client_host=127.0.0.1\n" +"xdebug.client_port=9003\n" #. type: Plain text #: ../src/cookbook/configuring-xdebug.md msgid "`trigger` starts a debug session only when a browser extension, query parameter, cookie, or `XDEBUG_SESSION` environment variable asks for it." -msgstr "" +msgstr "`trigger` inicia uma sessão de depuração apenas quando uma extensão do navegador, um parâmetro de query string, um cookie ou a variável de ambiente `XDEBUG_SESSION` pedir." #. type: Plain text #: ../src/cookbook/configuring-xdebug.md msgid "With Docker, the Yii application template installs Xdebug in the development image. Enable step debugging in `docker/dev/override.env`:" -msgstr "" +msgstr "Com Docker, o template de aplicação do Yii instala o Xdebug na imagem de desenvolvimento. Habilite a depuração passo a passo em `docker/dev/override.env`:" #. type: Fenced code block (dotenv) #: ../src/cookbook/configuring-xdebug.md @@ -87,22 +93,24 @@ msgid "" "XDEBUG_MODE=develop,debug\n" "XDEBUG_CONFIG=\"client_host=host.docker.internal idekey=phpstorm\"\n" msgstr "" +"XDEBUG_MODE=develop,debug\n" +"XDEBUG_CONFIG=\"client_host=host.docker.internal idekey=phpstorm\"\n" #. type: Plain text #: ../src/cookbook/configuring-xdebug.md msgid "Keep the default `SERVER_NAME=:80` from `docker/dev/.env` unless the application needs a different Caddy address. Set the browser port with `DEV_PORT` in `docker/.env`:" -msgstr "" +msgstr "Mantenha o `SERVER_NAME=:80` padrão de `docker/dev/.env`, a menos que a aplicação precise de outro endereço no Caddy. Defina a porta do navegador com `DEV_PORT` em `docker/.env`:" #. type: Fenced code block (dotenv) #: ../src/cookbook/configuring-xdebug.md #, no-wrap msgid "DEV_PORT=80\n" -msgstr "" +msgstr "DEV_PORT=80\n" #. type: Plain text #: ../src/cookbook/configuring-xdebug.md msgid "On Linux, Docker must resolve `host.docker.internal` to the host gateway. The current Yii application template already has this in `docker/compose.yml`:" -msgstr "" +msgstr "No Linux, o Docker precisa resolver `host.docker.internal` para o gateway do host. O template de aplicação atual do Yii já traz isso em `docker/compose.yml`:" #. type: Fenced code block (yaml) #: ../src/cookbook/configuring-xdebug.md @@ -113,23 +121,27 @@ msgid "" " extra_hosts:\n" " - \"host.docker.internal:host-gateway\"\n" msgstr "" +"services:\n" +" app:\n" +" extra_hosts:\n" +" - \"host.docker.internal:host-gateway\"\n" #. type: Plain text #: ../src/cookbook/configuring-xdebug.md msgid "Rebuild the development image if Xdebug was added after the image had already been built:" -msgstr "" +msgstr "Reconstrua a imagem de desenvolvimento se o Xdebug foi adicionado depois que a imagem já tinha sido construída:" #. type: Fenced code block (shell) #: ../src/cookbook/configuring-xdebug.md #, no-wrap msgid "make build\n" -msgstr "" +msgstr "make build\n" #. type: Title ## #: ../src/cookbook/configuring-xdebug.md #, no-wrap msgid "PhpStorm" -msgstr "" +msgstr "PhpStorm" #. type: Plain text #: ../src/cookbook/configuring-xdebug.md @@ -138,6 +150,8 @@ msgid "" "In **Settings** > **PHP** > **Debug**, check that Xdebug listens on port `9003`. Start listening with\n" "**Run** > **Start Listening for PHP Debug Connections**.\n" msgstr "" +"Em **Settings** > **PHP** > **Debug**, verifique se o Xdebug escuta na porta `9003`. Comece a escutar com\n" +"**Run** > **Start Listening for PHP Debug Connections**.\n" #. type: Plain text #: ../src/cookbook/configuring-xdebug.md @@ -146,63 +160,65 @@ msgid "" "For browser debugging, install a browser extension from **Settings** > **PHP** > **Debug**. In the extension options,\n" "use `phpstorm` as the IDE key.\n" msgstr "" +"Para depurar pelo navegador, instale uma extensão de navegador a partir de **Settings** > **PHP** > **Debug**. Nas opções da extensão,\n" +"use `phpstorm` como IDE key.\n" #. type: Plain text #: ../src/cookbook/configuring-xdebug.md #, no-wrap msgid "When PHP runs in Docker, configure a server in **Settings** > **PHP** > **Servers**:\n" -msgstr "" +msgstr "Quando o PHP roda no Docker, configure um servidor em **Settings** > **PHP** > **Servers**:\n" #. type: Bullet: '- ' #: ../src/cookbook/configuring-xdebug.md msgid "Name: `localhost`." -msgstr "" +msgstr "Nome: `localhost`." #. type: Bullet: '- ' #: ../src/cookbook/configuring-xdebug.md msgid "Host: `localhost`." -msgstr "" +msgstr "Host: `localhost`." #. type: Bullet: '- ' #: ../src/cookbook/configuring-xdebug.md msgid "Port: `80`, or the host port configured by `DEV_PORT`." -msgstr "" +msgstr "Porta: `80`, ou a porta do host configurada em `DEV_PORT`." #. type: Bullet: '- ' #: ../src/cookbook/configuring-xdebug.md msgid "Debugger: `Xdebug`." -msgstr "" +msgstr "Depurador: `Xdebug`." #. type: Bullet: '- ' #: ../src/cookbook/configuring-xdebug.md msgid "Path mapping: map the project root on the host to `/app` in the container." -msgstr "" +msgstr "Mapeamento de caminhos: mapeie a raiz do projeto no host para `/app` no container." #. type: Plain text #: ../src/cookbook/configuring-xdebug.md msgid "Use the project root for the mapping. Mapping only `public/` leaves files under `src/`, `config/`, and `vendor/` unmapped. The path in the container must match the path used by PHP. In the default template, the project is mounted into `/app`." -msgstr "" +msgstr "Use a raiz do projeto no mapeamento. Mapear só `public/` deixa sem mapeamento os arquivos em `src/`, `config/` e `vendor/`. O caminho no container precisa ser igual ao caminho usado pelo PHP. No template padrão, o projeto é montado em `/app`." #. type: Plain text #: ../src/cookbook/configuring-xdebug.md msgid "For local PHP, PhpStorm usually uses the same filesystem paths as PHP, so path mappings are usually unnecessary." -msgstr "" +msgstr "Com PHP local, o PhpStorm normalmente usa os mesmos caminhos do sistema de arquivos que o PHP, então mapeamentos de caminhos costumam ser desnecessários." #. type: Title ## #: ../src/cookbook/configuring-xdebug.md #, no-wrap msgid "VS Code" -msgstr "" +msgstr "VS Code" #. type: Plain text #: ../src/cookbook/configuring-xdebug.md msgid "Install the [PHP Debug](https://marketplace.visualstudio.com/items?itemName=xdebug.php-debug) extension." -msgstr "" +msgstr "Instale a extensão [PHP Debug](https://marketplace.visualstudio.com/items?itemName=xdebug.php-debug)." #. type: Plain text #: ../src/cookbook/configuring-xdebug.md msgid "For PHP that runs on the same filesystem as VS Code, create `.vscode/launch.json`:" -msgstr "" +msgstr "Para PHP rodando no mesmo sistema de arquivos que o VS Code, crie `.vscode/launch.json`:" #. type: Fenced code block (json) #: ../src/cookbook/configuring-xdebug.md @@ -220,11 +236,22 @@ msgid "" " ]\n" "}\n" msgstr "" +"{\n" +" \"version\": \"0.2.0\",\n" +" \"configurations\": [\n" +" {\n" +" \"name\": \"Listen for Xdebug\",\n" +" \"type\": \"php\",\n" +" \"request\": \"launch\",\n" +" \"port\": 9003\n" +" }\n" +" ]\n" +"}\n" #. type: Plain text #: ../src/cookbook/configuring-xdebug.md msgid "For Docker, add path mappings:" -msgstr "" +msgstr "Para Docker, adicione mapeamentos de caminhos:" #. type: Fenced code block (json) #: ../src/cookbook/configuring-xdebug.md @@ -245,27 +272,41 @@ msgid "" " ]\n" "}\n" msgstr "" +"{\n" +" \"version\": \"0.2.0\",\n" +" \"configurations\": [\n" +" {\n" +" \"name\": \"Listen for Xdebug\",\n" +" \"type\": \"php\",\n" +" \"request\": \"launch\",\n" +" \"port\": 9003,\n" +" \"pathMappings\": {\n" +" \"/app\": \"${workspaceFolder}\"\n" +" }\n" +" }\n" +" ]\n" +"}\n" #. type: Plain text #: ../src/cookbook/configuring-xdebug.md msgid "Start this configuration before running the web request, command, or test." -msgstr "" +msgstr "Inicie essa configuração antes de executar a requisição web, o comando ou o teste." #. type: Title ## #: ../src/cookbook/configuring-xdebug.md #, no-wrap msgid "Zed" -msgstr "" +msgstr "Zed" #. type: Plain text #: ../src/cookbook/configuring-xdebug.md msgid "Install or enable the PHP extension in Zed. It provides the `Xdebug` debug adapter." -msgstr "" +msgstr "Instale ou habilite a extensão PHP no Zed. Ela fornece o adaptador de depuração `Xdebug`." #. type: Plain text #: ../src/cookbook/configuring-xdebug.md msgid "Create `.zed/debug.json`:" -msgstr "" +msgstr "Crie `.zed/debug.json`:" #. type: Fenced code block (json) #: ../src/cookbook/configuring-xdebug.md @@ -280,6 +321,14 @@ msgid "" " }\n" "]\n" msgstr "" +"[\n" +" {\n" +" \"label\": \"PHP: Listen to Xdebug\",\n" +" \"adapter\": \"Xdebug\",\n" +" \"request\": \"launch\",\n" +" \"port\": 9003\n" +" }\n" +"]\n" #. type: Fenced code block (json) #: ../src/cookbook/configuring-xdebug.md @@ -297,106 +346,117 @@ msgid "" " }\n" "]\n" msgstr "" +"[\n" +" {\n" +" \"label\": \"PHP: Listen to Xdebug\",\n" +" \"adapter\": \"Xdebug\",\n" +" \"request\": \"launch\",\n" +" \"port\": 9003,\n" +" \"pathMappings\": {\n" +" \"/app\": \"$ZED_WORKTREE_ROOT\"\n" +" }\n" +" }\n" +"]\n" #. type: Plain text #: ../src/cookbook/configuring-xdebug.md msgid "Start the configuration with **debugger: start** before running the web request, command, or test. Zed can also load debug configurations from `.vscode/launch.json` when `.zed/debug.json` is absent." -msgstr "" +msgstr "Inicie a configuração com **debugger: start** antes de executar a requisição web, o comando ou o teste. O Zed também consegue carregar configurações de depuração de `.vscode/launch.json` quando `.zed/debug.json` não existe." #. type: Title ## #: ../src/cookbook/configuring-xdebug.md #, no-wrap msgid "Debug a web request" -msgstr "" +msgstr "Depurando uma requisição web" #. type: Plain text #: ../src/cookbook/configuring-xdebug.md msgid "Without Docker:" -msgstr "" +msgstr "Sem Docker:" #. type: Bullet: '3. ' #: ../src/cookbook/configuring-xdebug.md msgid "Start listening in the IDE." -msgstr "" +msgstr "Comece a escutar na IDE." #. type: Bullet: '4. ' #: ../src/cookbook/configuring-xdebug.md msgid "Put a breakpoint in an action or middleware." -msgstr "" +msgstr "Coloque um breakpoint em uma action ou middleware." #. type: Bullet: '3. ' #: ../src/cookbook/configuring-xdebug.md msgid "Start the built-in server with an Xdebug trigger:" -msgstr "" +msgstr "Inicie o servidor embutido com um trigger do Xdebug:" #. type: Fenced code block (shell) #: ../src/cookbook/configuring-xdebug.md #, no-wrap msgid " ./yii serve --xdebug\n" -msgstr "" +msgstr " ./yii serve --xdebug\n" #. type: Bullet: '4. ' #: ../src/cookbook/configuring-xdebug.md msgid "Open or reload the page in the browser." -msgstr "" +msgstr "Abra ou recarregue a página no navegador." #. type: Plain text #: ../src/cookbook/configuring-xdebug.md msgid "The `--xdebug` option passes `XDEBUG_MODE=debug XDEBUG_TRIGGER=yes` to the built-in PHP server. If you use another web server, enable debugging with the browser extension and reload the page." -msgstr "" +msgstr "A opção `--xdebug` passa `XDEBUG_MODE=debug XDEBUG_TRIGGER=yes` para o servidor embutido do PHP. Se você usa outro servidor web, habilite a depuração com a extensão do navegador e recarregue a página." #. type: Plain text #: ../src/cookbook/configuring-xdebug.md msgid "With Docker:" -msgstr "" +msgstr "Com Docker:" #. type: Bullet: '1. ' #: ../src/cookbook/configuring-xdebug.md msgid "Add the Docker Xdebug variables to `docker/dev/override.env`." -msgstr "" +msgstr "Adicione as variáveis do Xdebug para Docker em `docker/dev/override.env`." #. type: Bullet: '2. ' #: ../src/cookbook/configuring-xdebug.md msgid "Start or restart the development containers:" -msgstr "" +msgstr "Inicie ou reinicie os containers de desenvolvimento:" #. type: Fenced code block (shell) #: ../src/cookbook/configuring-xdebug.md #, no-wrap msgid " make up\n" -msgstr "" +msgstr " make up\n" #. type: Bullet: '5. ' #: ../src/cookbook/configuring-xdebug.md msgid "Enable debugging in the browser extension and reload the page." -msgstr "" +msgstr "Habilite a depuração na extensão do navegador e recarregue a página." #. type: Plain text #: ../src/cookbook/configuring-xdebug.md msgid "If the IDE accepts a connection and the breakpoint stays inactive, check path mappings first." -msgstr "" +msgstr "Se a IDE aceita a conexão e o breakpoint continua inativo, verifique primeiro os mapeamentos de caminhos." #. type: Title ## #: ../src/cookbook/configuring-xdebug.md #, no-wrap msgid "Debug a console command" -msgstr "" +msgstr "Depurando um comando de console" #. type: Plain text #: ../src/cookbook/configuring-xdebug.md msgid "Without Docker, start the command with an Xdebug trigger:" -msgstr "" +msgstr "Sem Docker, inicie o comando com um trigger do Xdebug:" #. type: Fenced code block (shell) #: ../src/cookbook/configuring-xdebug.md #, no-wrap msgid "XDEBUG_MODE=debug XDEBUG_SESSION=phpstorm ./yii hello\n" -msgstr "" +msgstr "XDEBUG_MODE=debug XDEBUG_SESSION=phpstorm ./yii hello\n" #. type: Plain text #: ../src/cookbook/configuring-xdebug.md msgid "With Docker, pass the trigger to the container:" -msgstr "" +msgstr "Com Docker, passe o trigger para o container:" #. type: Fenced code block (shell) #: ../src/cookbook/configuring-xdebug.md @@ -408,33 +468,38 @@ msgid "" " -e PHP_IDE_CONFIG=serverName=localhost \\\n" " app ./yii hello\n" msgstr "" +"docker compose -f docker/compose.yml -f docker/dev/compose.yml run --rm \\\n" +" -e XDEBUG_MODE=debug \\\n" +" -e XDEBUG_SESSION=phpstorm \\\n" +" -e PHP_IDE_CONFIG=serverName=localhost \\\n" +" app ./yii hello\n" #. type: Plain text #: ../src/cookbook/configuring-xdebug.md msgid "Use the command name and arguments you need instead of `hello`." -msgstr "" +msgstr "Use o nome do comando e os argumentos de que você precisa no lugar de `hello`." #. type: Title ## #: ../src/cookbook/configuring-xdebug.md #, no-wrap msgid "Debug tests" -msgstr "" +msgstr "Depurando testes" #. type: Plain text #: ../src/cookbook/configuring-xdebug.md msgid "Without Docker, start the test runner with an Xdebug trigger:" -msgstr "" +msgstr "Sem Docker, inicie o executor de testes com um trigger do Xdebug:" #. type: Fenced code block (shell) #: ../src/cookbook/configuring-xdebug.md #, no-wrap msgid "XDEBUG_MODE=debug XDEBUG_SESSION=phpstorm vendor/bin/codecept run\n" -msgstr "" +msgstr "XDEBUG_MODE=debug XDEBUG_SESSION=phpstorm vendor/bin/codecept run\n" #. type: Plain text #: ../src/cookbook/configuring-xdebug.md msgid "With Docker, configure `docker/test/override.env`:" -msgstr "" +msgstr "Com Docker, configure `docker/test/override.env`:" #. type: Fenced code block (dotenv) #: ../src/cookbook/configuring-xdebug.md @@ -443,11 +508,13 @@ msgid "" "XDEBUG_MODE=debug,coverage\n" "XDEBUG_CONFIG=\"client_host=host.docker.internal idekey=phpstorm\"\n" msgstr "" +"XDEBUG_MODE=debug,coverage\n" +"XDEBUG_CONFIG=\"client_host=host.docker.internal idekey=phpstorm\"\n" #. type: Plain text #: ../src/cookbook/configuring-xdebug.md msgid "Then run the test container with a trigger:" -msgstr "" +msgstr "Depois, rode o container de testes com um trigger:" #. type: Fenced code block (shell) #: ../src/cookbook/configuring-xdebug.md @@ -458,83 +525,84 @@ msgid "" " -e PHP_IDE_CONFIG=serverName=localhost \\\n" " app ./vendor/bin/codecept run\n" msgstr "" +"docker compose -f docker/compose.yml -f docker/test/compose.yml run --rm \\\n" +" -e XDEBUG_SESSION=phpstorm \\\n" +" -e PHP_IDE_CONFIG=serverName=localhost \\\n" +" app ./vendor/bin/codecept run\n" #. type: Plain text #: ../src/cookbook/configuring-xdebug.md msgid "Use `make test` for regular test runs. Use the explicit `docker compose` command when you need to pass debug-only environment variables to one run." -msgstr "" +msgstr "Use `make test` para execuções normais dos testes. Use o comando `docker compose` explícito quando precisar passar variáveis de ambiente só de depuração para uma execução." #. type: Title ## -#: ../src/cookbook/configuring-xdebug.md -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md -#: ../src/guide/views/asset.md +#: ../src/cookbook/configuring-xdebug.md ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md ../src/guide/views/asset.md #, no-wrap msgid "Troubleshooting" -msgstr "" +msgstr "Solução de problemas" #. type: Bullet: '- ' #: ../src/cookbook/configuring-xdebug.md msgid "The IDE must listen before PHP starts the request." -msgstr "" +msgstr "A IDE precisa estar escutando antes de o PHP iniciar a requisição." #. type: Bullet: '- ' #: ../src/cookbook/configuring-xdebug.md msgid "Xdebug connects from PHP to the IDE. Allow incoming connections to port `9003` in the host firewall." -msgstr "" +msgstr "O Xdebug se conecta do PHP para a IDE. Libere conexões de entrada na porta `9003` no firewall do host." #. type: Bullet: '- ' #: ../src/cookbook/configuring-xdebug.md msgid "In Docker, `client_host` must be reachable from the container. The Yii template uses `host.docker.internal`." -msgstr "" +msgstr "No Docker, o `client_host` precisa ser acessível a partir do container. O template do Yii usa `host.docker.internal`." #. type: Bullet: '- ' #: ../src/cookbook/configuring-xdebug.md msgid "For CLI and tests, set `XDEBUG_SESSION=phpstorm` or another trigger accepted by your Xdebug configuration." -msgstr "" +msgstr "Para CLI e testes, defina `XDEBUG_SESSION=phpstorm` ou outro trigger aceito pela sua configuração do Xdebug." #. type: Bullet: '- ' #: ../src/cookbook/configuring-xdebug.md msgid "For Docker path mappings, map the host project root to `/app`." -msgstr "" +msgstr "Para mapeamentos de caminhos no Docker, mapeie a raiz do projeto no host para `/app`." #. type: Bullet: '- ' #: ../src/cookbook/configuring-xdebug.md msgid "To inspect connection attempts, temporarily add `log=/app/runtime/xdebug.log` to `XDEBUG_CONFIG`." -msgstr "" +msgstr "Para inspecionar as tentativas de conexão, adicione temporariamente `log=/app/runtime/xdebug.log` ao `XDEBUG_CONFIG`." #. type: Title ## #: ../src/cookbook/configuring-xdebug.md #, no-wrap msgid "See also" -msgstr "" +msgstr "Veja também" #. type: Bullet: '- ' #: ../src/cookbook/configuring-xdebug.md msgid "[Xdebug step debugging](https://xdebug.org/docs/step_debug)" -msgstr "" +msgstr "[Depuração passo a passo do Xdebug](https://xdebug.org/docs/step_debug)" #. type: Bullet: '- ' #: ../src/cookbook/configuring-xdebug.md msgid "[PhpStorm Xdebug documentation](https://www.jetbrains.com/help/phpstorm/configuring-xdebug.html)" -msgstr "" +msgstr "[Documentação do Xdebug no PhpStorm](https://www.jetbrains.com/help/phpstorm/configuring-xdebug.html)" #. type: Bullet: '- ' #: ../src/cookbook/configuring-xdebug.md msgid "[PhpStorm servers and path mappings](https://www.jetbrains.com/help/phpstorm/servers.html)" -msgstr "" +msgstr "[Servidores e mapeamentos de caminhos no PhpStorm](https://www.jetbrains.com/help/phpstorm/servers.html)" #. type: Bullet: '- ' #: ../src/cookbook/configuring-xdebug.md msgid "[VS Code PHP Debug](https://github.com/xdebug/vscode-php-debug)" -msgstr "" +msgstr "[VS Code PHP Debug](https://github.com/xdebug/vscode-php-debug)" #. type: Bullet: '- ' #: ../src/cookbook/configuring-xdebug.md msgid "[Zed PHP documentation](https://zed.dev/docs/languages/php#debugging)" -msgstr "" +msgstr "[Documentação de PHP no Zed](https://zed.dev/docs/languages/php#debugging)" #. type: Bullet: '- ' #: ../src/cookbook/configuring-xdebug.md msgid "[Docker in application templates](../guide/tutorial/docker.md)" -msgstr "" +msgstr "[Docker nos templates de aplicação](../guide/tutorial/docker.md)" diff --git a/_translations/po/pt-BR/cookbook_custom-hydrator-type-casters.md.po b/_translations/po/pt-BR/cookbook_custom-hydrator-type-casters.md.po index 35a830db..bd045858 100644 --- a/_translations/po/pt-BR/cookbook_custom-hydrator-type-casters.md.po +++ b/_translations/po/pt-BR/cookbook_custom-hydrator-type-casters.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-10-15 11:09+0000\n" "PO-Revision-Date: 2026-10-15 11:09+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,53 +19,53 @@ msgstr "" #: ../src/cookbook/custom-hydrator-type-casters.md #, no-wrap msgid "Custom hydrator type casters" -msgstr "" +msgstr "Type casters personalizados para o hydrator" #. type: Plain text #: ../src/cookbook/custom-hydrator-type-casters.md msgid "[Yii Hydrator](https://github.com/yiisoft/hydrator) creates objects and fills them with data from arrays. It's used directly and by packages built on top of it:" -msgstr "" +msgstr "O [Yii Hydrator](https://github.com/yiisoft/hydrator) cria objetos e os preenche com dados de arrays. Ele é usado diretamente e por pacotes construídos sobre ele:" #. type: Bullet: '- ' #: ../src/cookbook/custom-hydrator-type-casters.md msgid "[Yii Input HTTP](https://github.com/yiisoft/input-http) fills request input objects from query parameters, request body, and, with the help of [Yii Router](https://github.com/yiisoft/router), route arguments." -msgstr "" +msgstr "O [Yii Input HTTP](https://github.com/yiisoft/input-http) preenche objetos de entrada da requisição a partir de parâmetros da query string, do corpo da requisição e, com a ajuda do [Yii Router](https://github.com/yiisoft/router), dos argumentos da rota." #. type: Bullet: '- ' #: ../src/cookbook/custom-hydrator-type-casters.md msgid "[Yii Form Model](https://github.com/yiisoft/form-model) provides `FormHydrator` that fills form models from submitted data." -msgstr "" +msgstr "O [Yii Form Model](https://github.com/yiisoft/form-model) fornece o `FormHydrator`, que preenche form models com os dados enviados." #. type: Plain text #: ../src/cookbook/custom-hydrator-type-casters.md msgid "The incoming data is usually \"raw\": HTTP requests, database rows, and queue messages contain strings, numbers, and arrays. Before assigning a value to a property or passing it to a constructor parameter, the hydrator converts it to the declared type. A *type caster* performs this conversion. By writing your own type caster, you teach the hydrator to create your types, such as value objects, from raw data." -msgstr "" +msgstr "Os dados recebidos geralmente são \"brutos\": requisições HTTP, linhas do banco de dados e mensagens de fila contêm strings, números e arrays. Antes de atribuir um valor a uma propriedade ou passá-lo a um parâmetro do construtor, o hydrator o converte para o tipo declarado. Um *type caster* faz essa conversão. Ao escrever seu próprio type caster, você ensina o hydrator a criar seus tipos, como value objects, a partir de dados brutos." #. type: Title ## #: ../src/cookbook/custom-hydrator-type-casters.md #, no-wrap msgid "Why custom type casters" -msgstr "" +msgstr "Por que type casters personalizados" #. type: Plain text #: ../src/cookbook/custom-hydrator-type-casters.md msgid "Out of the box, the hydrator uses a composite type caster with two casters:" -msgstr "" +msgstr "Por padrão, o hydrator usa um type caster composto com dois casters:" #. type: Bullet: '- ' #: ../src/cookbook/custom-hydrator-type-casters.md msgid "`PhpNativeTypeCaster` casts values to built-in PHP types, such as `int`, `string`, `bool`, and `array`." -msgstr "" +msgstr "`PhpNativeTypeCaster` converte valores para tipos nativos do PHP, como `int`, `string`, `bool` e `array`." #. type: Bullet: '- ' #: ../src/cookbook/custom-hydrator-type-casters.md msgid "`HydratorTypeCaster` creates nested objects from arrays using the hydrator itself." -msgstr "" +msgstr "`HydratorTypeCaster` cria objetos aninhados a partir de arrays usando o próprio hydrator." #. type: Plain text #: ../src/cookbook/custom-hydrator-type-casters.md msgid "That's enough for DTOs with scalar properties, but not for a rich domain model. Consider a property typed as `UserId`, `Email`, or `Money`. The incoming value is a string, and neither of the default casters knows how to turn it into such an object. So you end up declaring the property as `string` and converting it by hand wherever it's used:" -msgstr "" +msgstr "Isso basta para DTOs com propriedades escalares, mas não para um modelo de domínio rico. Considere uma propriedade tipada como `UserId`, `Email` ou `Money`. O valor recebido é uma string, e nenhum dos casters padrão sabe transformá-lo em um objeto desses. Assim, você acaba declarando a propriedade como `string` e convertendo-a manualmente onde quer que ela seja usada:" #. type: Fenced code block (php) #: ../src/cookbook/custom-hydrator-type-casters.md @@ -83,11 +83,22 @@ msgid "" " // Report the error somehow.\n" "}\n" msgstr "" +"final class CreatePostForm extends FormModel\n" +"{\n" +" public string $authorId = '';\n" +"}\n" +"\n" +"// Em toda action que usa o formulário:\n" +"try {\n" +" $authorId = new UserId($form->authorId);\n" +"} catch (InvalidArgumentException) {\n" +" // Reporte o erro de alguma forma.\n" +"}\n" #. type: Plain text #: ../src/cookbook/custom-hydrator-type-casters.md msgid "With a type caster for `UserId`, you can declare the property with its real type. The conversion happens during hydration:" -msgstr "" +msgstr "Com um type caster para `UserId`, você pode declarar a propriedade com seu tipo real. A conversão acontece durante a hidratação:" #. type: Fenced code block (php) #: ../src/cookbook/custom-hydrator-type-casters.md @@ -100,119 +111,125 @@ msgid "" "\n" "// $form->authorId is already an instance of UserId.\n" msgstr "" +"final class CreatePostForm extends FormModel\n" +"{\n" +" public ?UserId $authorId = null;\n" +"}\n" +"\n" +"// $form->authorId já é uma instância de UserId.\n" #. type: Plain text #: ../src/cookbook/custom-hydrator-type-casters.md msgid "The conversion logic lives in a single place. Once you register the caster, the hydrator applies it to every property and constructor parameter of the matching type in every object it creates." -msgstr "" +msgstr "A lógica de conversão fica em um único lugar. Depois que você registra o caster, o hydrator o aplica a todas as propriedades e parâmetros de construtor do tipo correspondente em todos os objetos que ele cria." #. type: Plain text #: ../src/cookbook/custom-hydrator-type-casters.md msgid "Typical use cases are:" -msgstr "" +msgstr "Casos de uso típicos:" #. type: Bullet: '- ' #: ../src/cookbook/custom-hydrator-type-casters.md msgid "value objects, such as entity IDs, emails, phone numbers, and money amounts." -msgstr "" +msgstr "value objects, como IDs de entidades, e-mails, números de telefone e valores monetários." #. type: Bullet: '- ' #: ../src/cookbook/custom-hydrator-type-casters.md msgid "types from third-party libraries, such as UUIDs, dates, or currencies." -msgstr "" +msgstr "tipos de bibliotecas de terceiros, como UUIDs, datas ou moedas." #. type: Bullet: '- ' #: ../src/cookbook/custom-hydrator-type-casters.md msgid "consistent normalization of values, for example, parsing dates in a format specific to your application." -msgstr "" +msgstr "normalização consistente de valores, por exemplo, interpretar datas em um formato específico da sua aplicação." #. type: Title ## #: ../src/cookbook/custom-hydrator-type-casters.md #, no-wrap msgid "Anatomy of a type caster" -msgstr "" +msgstr "Anatomia de um type caster" #. type: Plain text #: ../src/cookbook/custom-hydrator-type-casters.md msgid "A type caster implements `Yiisoft\\Hydrator\\TypeCaster\\TypeCasterInterface` with a single method:" -msgstr "" +msgstr "Um type caster implementa `Yiisoft\\Hydrator\\TypeCaster\\TypeCasterInterface`, que tem um único método:" #. type: Fenced code block (php) #: ../src/cookbook/custom-hydrator-type-casters.md #, no-wrap msgid "public function cast(mixed $value, TypeCastContext $context): Result;\n" -msgstr "" +msgstr "public function cast(mixed $value, TypeCastContext $context): Result;\n" #. type: Bullet: '- ' #: ../src/cookbook/custom-hydrator-type-casters.md msgid "`$value` is the raw value to convert." -msgstr "" +msgstr "`$value` é o valor bruto a ser convertido." #. type: Bullet: '- ' #: ../src/cookbook/custom-hydrator-type-casters.md msgid "`$context` is a `Yiisoft\\Hydrator\\TypeCaster\\TypeCastContext`. Its `getReflectionType()` method returns the declared type of the target property or constructor parameter. Use it to decide whether the caster supports the target type." -msgstr "" +msgstr "`$context` é um `Yiisoft\\Hydrator\\TypeCaster\\TypeCastContext`. Seu método `getReflectionType()` retorna o tipo declarado da propriedade ou do parâmetro de construtor de destino. Use-o para decidir se o caster suporta o tipo de destino." #. type: Bullet: '- ' #: ../src/cookbook/custom-hydrator-type-casters.md msgid "The method returns a `Yiisoft\\Hydrator\\Result`: `Result::success($convertedValue)` if the conversion succeeded or `Result::fail()` if the caster can't handle the value." -msgstr "" +msgstr "O método retorna um `Yiisoft\\Hydrator\\Result`: `Result::success($convertedValue)` se a conversão deu certo ou `Result::fail()` se o caster não consegue lidar com o valor." #. type: Plain text #: ../src/cookbook/custom-hydrator-type-casters.md msgid "Follow these rules when writing a type caster:" -msgstr "" +msgstr "Siga estas regras ao escrever um type caster:" #. type: Bullet: '1. ' #: ../src/cookbook/custom-hydrator-type-casters.md msgid "**Check the target type first.** If the declared type isn't the one your caster is responsible for, return `Result::fail()` right away so other casters can handle the value." -msgstr "" +msgstr "**Verifique o tipo de destino primeiro.** Se o tipo declarado não for aquele pelo qual seu caster é responsável, retorne `Result::fail()` imediatamente para que outros casters possam lidar com o valor." #. type: Bullet: '2. ' #: ../src/cookbook/custom-hydrator-type-casters.md msgid "**Handle both named and union types.** PHP represents a nullable type such as `?Email` (or `Email|null`) with `ReflectionNamedType` and `Email|string` with `ReflectionUnionType`. In the latter case, look for your type among its subtypes." -msgstr "" +msgstr "**Trate tipos nomeados e tipos união.** O PHP representa um tipo anulável como `?Email` (ou `Email|null`) com `ReflectionNamedType` e `Email|string` com `ReflectionUnionType`. No segundo caso, procure seu tipo entre os subtipos." #. type: Bullet: '3. ' #: ../src/cookbook/custom-hydrator-type-casters.md msgid "**Don't handle `null` yourself.** If the value is `null`, just return `Result::fail()`. `PhpNativeTypeCaster` returns `null` for any type that allows it, so a `null` value assigned to `?Email` stays `null`." -msgstr "" +msgstr "**Não trate `null` você mesmo.** Se o valor for `null`, apenas retorne `Result::fail()`. O `PhpNativeTypeCaster` retorna `null` para qualquer tipo que o permita, então um valor `null` atribuído a `?Email` continua `null`." #. type: Bullet: '4. ' #: ../src/cookbook/custom-hydrator-type-casters.md msgid "**Accept already converted values.** If the value is already an instance of the target type, return it as is." -msgstr "" +msgstr "**Aceite valores já convertidos.** Se o valor já for uma instância do tipo de destino, retorne-o como está." #. type: Bullet: '5. ' #: ../src/cookbook/custom-hydrator-type-casters.md msgid "**Fail instead of throwing.** If your caster can't convert the value, for example, a malformed string, return `Result::fail()`. An exception would break the whole hydration." -msgstr "" +msgstr "**Falhe em vez de lançar exceções.** Se seu caster não consegue converter o valor, por exemplo, uma string malformada, retorne `Result::fail()`. Uma exceção quebraria toda a hidratação." #. type: Plain text #: ../src/cookbook/custom-hydrator-type-casters.md msgid "Keep in mind what happens when no caster succeeds:" -msgstr "" +msgstr "Tenha em mente o que acontece quando nenhum caster tem sucesso:" #. type: Bullet: '- ' #: ../src/cookbook/custom-hydrator-type-casters.md msgid "For a property, the cast fails silently. The hydrator doesn't set the property or report an error, so the property keeps its default value. Reporting the problem to the user is the job of the validation that runs after hydration. See [Null and invalid values](#null-and-invalid-values) for an example." -msgstr "" +msgstr "Para uma propriedade, a conversão falha silenciosamente. O hydrator não define a propriedade nem reporta um erro, então a propriedade mantém seu valor padrão. Reportar o problema ao usuário é papel da validação que roda após a hidratação. Veja [Valores nulos e inválidos](#valores-nulos-e-invalidos) para um exemplo." #. type: Bullet: '- ' #: ../src/cookbook/custom-hydrator-type-casters.md msgid "For a constructor parameter, the hydrator omits the argument. If the parameter has a default value, it's used. Otherwise, object creation fails with `WrongConstructorArgumentsCountException`, even for a nullable parameter without a default value." -msgstr "" +msgstr "Para um parâmetro de construtor, o hydrator omite o argumento. Se o parâmetro tiver um valor padrão, ele é usado. Caso contrário, a criação do objeto falha com `WrongConstructorArgumentsCountException`, mesmo para um parâmetro anulável sem valor padrão." #. type: Title ## #: ../src/cookbook/custom-hydrator-type-casters.md #, no-wrap msgid "Registering a type caster" -msgstr "" +msgstr "Registrando um type caster" #. type: Plain text #: ../src/cookbook/custom-hydrator-type-casters.md msgid "Combine type casters with `CompositeTypeCaster`. It tries the casters one by one and uses the result of the first one that succeeds. To add your caster, redefine `TypeCasterInterface` in the DI container configuration, for example, in `config/common/di/hydrator.php`. The `HydratorInterface` implementation from the container uses this chain, as do packages that rely on it, such as Yii Input HTTP:" -msgstr "" +msgstr "Combine type casters com `CompositeTypeCaster`. Ele tenta os casters um a um e usa o resultado do primeiro que tiver sucesso. Para adicionar seu caster, redefina `TypeCasterInterface` na configuração do container de DI, por exemplo, em `config/common/di/hydrator.php`. A implementação de `HydratorInterface` do container usa essa cadeia, assim como os pacotes que dependem dela, como o Yii Input HTTP:" #. type: Fenced code block (php) #: ../src/cookbook/custom-hydrator-type-casters.md @@ -236,26 +253,43 @@ msgid "" " ),\n" "];\n" msgstr "" +" static fn() => new CompositeTypeCaster(\n" +" new UuidValueTypeCaster(),\n" +" new PhpNativeTypeCaster(),\n" +" new HydratorTypeCaster(),\n" +" ),\n" +"];\n" #. type: Plain text #: ../src/cookbook/custom-hydrator-type-casters.md msgid "Since the first successful result wins, the order matters:" -msgstr "" +msgstr "Como o primeiro resultado bem-sucedido vence, a ordem importa:" #. type: Bullet: '- ' #: ../src/cookbook/custom-hydrator-type-casters.md msgid "Put custom casters before `PhpNativeTypeCaster`. Otherwise, for a property declared as `UserId|string`, `PhpNativeTypeCaster` accepts a string as is, and your caster never runs." -msgstr "" +msgstr "Coloque os casters personalizados antes do `PhpNativeTypeCaster`. Caso contrário, para uma propriedade declarada como `UserId|string`, o `PhpNativeTypeCaster` aceita a string como está, e seu caster nunca é executado." #. type: Bullet: '- ' #: ../src/cookbook/custom-hydrator-type-casters.md msgid "Keep the default casters in the list. `PhpNativeTypeCaster` casts scalar values to built-in types, and `HydratorTypeCaster` creates nested objects from arrays." -msgstr "" +msgstr "Mantenha os casters padrão na lista. O `PhpNativeTypeCaster` converte valores escalares para tipos nativos, e o `HydratorTypeCaster` cria objetos aninhados a partir de arrays." #. type: Plain text #: ../src/cookbook/custom-hydrator-type-casters.md msgid "If a caster has dependencies, take it from the container:" -msgstr "" +msgstr "Se um caster tiver dependências, obtenha-o do container:" #. type: Fenced code block (php) #: ../src/cookbook/custom-hydrator-type-casters.md @@ -280,17 +314,35 @@ msgid "" " ),\n" "];\n" msgstr "" +" static fn(ContainerInterface $container) => new CompositeTypeCaster(\n" +" $container->get(MoneyTypeCaster::class),\n" +" new PhpNativeTypeCaster(),\n" +" new HydratorTypeCaster(),\n" +" ),\n" +"];\n" #. type: Title ### #: ../src/cookbook/custom-hydrator-type-casters.md #, no-wrap msgid "Registering for form models" -msgstr "" +msgstr "Registrando para form models" #. type: Plain text #: ../src/cookbook/custom-hydrator-type-casters.md msgid "`FormHydrator` from Yii Form Model doesn't use `TypeCasterInterface`. Its DI configuration creates a dedicated hydrator with its own chain of type casters, so add your caster there as well:" -msgstr "" +msgstr "O `FormHydrator` do Yii Form Model não usa `TypeCasterInterface`. Sua configuração de DI cria um hydrator dedicado com sua própria cadeia de type casters, então adicione seu caster lá também:" #. type: Fenced code block (php) #: ../src/cookbook/custom-hydrator-type-casters.md @@ -329,39 +381,71 @@ msgid "" " ],\n" "];\n" msgstr "" +" [\n" +" '__construct()' => [\n" +" 'hydrator' => DynamicReference::to([\n" +" 'class' => Hydrator::class,\n" +" '__construct()' => [\n" +" 'typeCaster' => new CompositeTypeCaster(\n" +" new NullTypeCaster(emptyString: true),\n" +" new UuidValueTypeCaster(),\n" +" new PhpNativeTypeCaster(),\n" +" new NonArrayTypeCaster(),\n" +" new HydratorTypeCaster(),\n" +" ),\n" +" ],\n" +" ]),\n" +" ],\n" +" ],\n" +"];\n" #. type: Plain text #: ../src/cookbook/custom-hydrator-type-casters.md msgid "This definition replaces the one from the package, so keep its type casters. This example uses the list from `config/di.php` of Yii Form Model 1.1. Check it against the version you use. `NullTypeCaster` turns empty strings submitted by forms into `null` for nullable properties, so it stays first." -msgstr "" +msgstr "Essa definição substitui a do pacote, então mantenha os type casters dele. Este exemplo usa a lista do `config/di.php` do Yii Form Model 1.1. Confira com a versão que você usa. O `NullTypeCaster` transforma strings vazias enviadas por formulários em `null` para propriedades anuláveis, por isso ele continua em primeiro." #. type: Title ## #: ../src/cookbook/custom-hydrator-type-casters.md #, no-wrap msgid "Example: UUID value objects" -msgstr "" +msgstr "Exemplo: value objects de UUID" #. type: Plain text #: ../src/cookbook/custom-hydrator-type-casters.md msgid "Entity IDs often use value objects, such as `UserId`, `PostId`, and `OrderId`, instead of plain strings. Such objects make method signatures self-documenting and prevent passing a post ID where a method expects a user ID. The following example shows how to write a type caster that creates them from UUID strings." -msgstr "" +msgstr "IDs de entidades frequentemente usam value objects, como `UserId`, `PostId` e `OrderId`, em vez de strings simples. Esses objetos tornam as assinaturas dos métodos autodocumentadas e impedem que você passe um ID de post onde um método espera um ID de usuário. O exemplo a seguir mostra como escrever um type caster que os cria a partir de strings UUID." #. type: Title ### #: ../src/cookbook/custom-hydrator-type-casters.md #, no-wrap msgid "Value objects" -msgstr "" +msgstr "Value objects" #. type: Plain text #: ../src/cookbook/custom-hydrator-type-casters.md msgid "All ID value objects extend an abstract `UuidValue` class. The example uses [ramsey/uuid](https://github.com/ramsey/uuid) to validate and generate UUIDs:" -msgstr "" +msgstr "Todos os value objects de ID estendem uma classe abstrata `UuidValue`. O exemplo usa [ramsey/uuid](https://github.com/ramsey/uuid) para validar e gerar UUIDs:" #. type: Fenced code block (shell) #: ../src/cookbook/custom-hydrator-type-casters.md #, no-wrap msgid "composer require ramsey/uuid\n" -msgstr "" +msgstr "composer require ramsey/uuid\n" #. type: Fenced code block (php) #: ../src/cookbook/custom-hydrator-type-casters.md @@ -407,11 +491,50 @@ msgid "" " }\n" "}\n" msgstr "" +"value = Uuid::fromString($value)->toString();\n" +" }\n" +"\n" +" public static function generate(): static\n" +" {\n" +" return new static(Uuid::uuid7()->toString());\n" +" }\n" +"\n" +" public function equals(self $other): bool\n" +" {\n" +" return $other instanceof static && $other->value === $this->value;\n" +" }\n" +"\n" +" public function __toString(): string\n" +" {\n" +" return $this->value;\n" +" }\n" +"}\n" #. type: Plain text #: ../src/cookbook/custom-hydrator-type-casters.md msgid "The constructor is final, so `new static()` is safe and creates every child class from a string the same way. A concrete ID is just an empty child class:" -msgstr "" +msgstr "O construtor é final, então `new static()` é seguro e cria todas as classes filhas a partir de uma string da mesma forma. Um ID concreto é apenas uma classe filha vazia:" #. type: Fenced code block (php) #: ../src/cookbook/custom-hydrator-type-casters.md @@ -429,17 +552,28 @@ msgid "" "{\n" "}\n" msgstr "" +"findUuidValueClass($context->getReflectionType());\n" +" if ($class === null) {\n" +" return Result::fail();\n" +" }\n" +"\n" +" if ($value instanceof $class) {\n" +" return Result::success($value);\n" +" }\n" +"\n" +" if (!is_string($value) || !Uuid::isValid($value)) {\n" +" return Result::fail();\n" +" }\n" +"\n" +" return Result::success(new $class($value));\n" +" }\n" +"\n" +" /**\n" +" * Retorna a classe filha de `UuidValue` a partir do tipo declarado, ou `null` se não houver nenhuma ou houver várias\n" +" * delas, como em `UserId|PostId`.\n" +" *\n" +" * @return class-string|null\n" +" */\n" +" private function findUuidValueClass(?ReflectionType $type): ?string\n" +" {\n" +" $types = match (true) {\n" +" $type instanceof ReflectionNamedType => [$type],\n" +" $type instanceof ReflectionUnionType => $type->getTypes(),\n" +" default => [],\n" +" };\n" +"\n" +" $classes = [];\n" +" foreach ($types as $subType) {\n" +" if (\n" +" $subType instanceof ReflectionNamedType\n" +" && !$subType->isBuiltin()\n" +" && is_subclass_of($subType->getName(), UuidValue::class)\n" +" ) {\n" +" $classes[] = $subType->getName();\n" +" }\n" +" }\n" +"\n" +" return count($classes) === 1 ? $classes[0] : null;\n" +" }\n" +"}\n" #. type: Plain text #: ../src/cookbook/custom-hydrator-type-casters.md msgid "The caster follows the [rules for writing a type caster](#anatomy-of-a-type-caster). It chooses the class to create from the declared type. All IDs share the same UUID format, so a string alone can't tell whether it's a user ID or a post ID. A single caster therefore serves all `UuidValue` child classes, and adding a new ID class doesn't require changes to the caster. For the same reason, the caster fails for a type with several ID classes, such as `UserId|PostId`. There's no way to choose the right one." -msgstr "" +msgstr "O caster segue as [regras para escrever um type caster](#anatomia-de-um-type-caster). Ele escolhe a classe a ser criada a partir do tipo declarado. Todos os IDs compartilham o mesmo formato UUID, então uma string sozinha não diz se é um ID de usuário ou de post. Por isso, um único caster atende todas as classes filhas de `UuidValue`, e adicionar uma nova classe de ID não exige mudanças no caster. Pelo mesmo motivo, o caster falha para um tipo com várias classes de ID, como `UserId|PostId`. Não há como escolher a correta." #. type: Plain text #: ../src/cookbook/custom-hydrator-type-casters.md msgid "Register `UuidValueTypeCaster` as shown in the [Registering a type caster](#registering-a-type-caster) section, including the [form model configuration](#registering-for-form-models) if you use Yii Form Model." -msgstr "" +msgstr "Registre o `UuidValueTypeCaster` como mostrado na seção [Registrando um type caster](#registrando-um-type-caster), incluindo a [configuração para form models](#registrando-para-form-models) se você usa o Yii Form Model." #. type: Title ### #: ../src/cookbook/custom-hydrator-type-casters.md #, no-wrap msgid "Using the value objects" -msgstr "" +msgstr "Usando os value objects" #. type: Plain text #: ../src/cookbook/custom-hydrator-type-casters.md msgid "Now any class that's populated by the hydrator can declare ID value objects directly." -msgstr "" +msgstr "Agora qualquer classe preenchida pelo hydrator pode declarar value objects de ID diretamente." #. type: Title #### #: ../src/cookbook/custom-hydrator-type-casters.md #, no-wrap msgid "Hydrator" -msgstr "" +msgstr "Hydrator" #. type: Plain text #: ../src/cookbook/custom-hydrator-type-casters.md msgid "The same string becomes a different value object depending on the type of the property:" -msgstr "" +msgstr "A mesma string se torna um value object diferente dependendo do tipo da propriedade:" #. type: Fenced code block (php) #: ../src/cookbook/custom-hydrator-type-casters.md @@ -568,17 +768,35 @@ msgid "" "// $filter->authorId is UserId, $filter->postId is PostId.\n" "// $filter->authorId->equals($filter->postId) returns false.\n" msgstr "" +"use App\\Post\\PostId;\n" +"use App\\User\\UserId;\n" +"use Yiisoft\\Hydrator\\HydratorInterface;\n" +"\n" +"final class CommentFilter\n" +"{\n" +" public ?UserId $authorId = null;\n" +" public ?PostId $postId = null;\n" +"}\n" +"\n" +"/** @var HydratorInterface $hydrator */\n" +"$filter = $hydrator->create(CommentFilter::class, [\n" +" 'authorId' => '0192f2a4-7a4b-7c3e-9a1b-3f5c8d2e6a10',\n" +" 'postId' => '0192f2a4-7a4b-7c3e-9a1b-3f5c8d2e6a10',\n" +"]);\n" +"\n" +"// $filter->authorId é UserId, $filter->postId é PostId.\n" +"// $filter->authorId->equals($filter->postId) retorna false.\n" #. type: Title #### #: ../src/cookbook/custom-hydrator-type-casters.md #, no-wrap msgid "Request input" -msgstr "" +msgstr "Entrada da requisição" #. type: Plain text #: ../src/cookbook/custom-hydrator-type-casters.md msgid "The [Yii Input HTTP](https://github.com/yiisoft/input-http) package uses the hydrator to fill request input objects, so the same type caster works for query parameters, request body, and route arguments. The `RouteArgument` attribute comes from [Yii Router](https://github.com/yiisoft/router). Extend `AbstractInput` to get the input validated after hydration:" -msgstr "" +msgstr "O pacote [Yii Input HTTP](https://github.com/yiisoft/input-http) usa o hydrator para preencher objetos de entrada da requisição, então o mesmo type caster funciona para parâmetros da query string, corpo da requisição e argumentos da rota. O atributo `RouteArgument` vem do [Yii Router](https://github.com/yiisoft/router). Estenda `AbstractInput` para que a entrada seja validada após a hidratação:" #. type: Fenced code block (php) #: ../src/cookbook/custom-hydrator-type-casters.md @@ -608,6 +826,29 @@ msgid "" " public ?UserId $authorId = null;\n" "}\n" msgstr "" +"getValidationResult()->isValid()) {\n" +" // Retorne uma resposta de erro.\n" +" }\n" +"\n" +" // $input->id é PostId, $input->authorId é UserId.\n" +" // ...\n" +" }\n" +"}\n" #. type: Title #### #: ../src/cookbook/custom-hydrator-type-casters.md #, no-wrap msgid "Form model" -msgstr "" +msgstr "Form model" #. type: Plain text #: ../src/cookbook/custom-hydrator-type-casters.md msgid "`FormHydrator` from [Yii Form Model](https://github.com/yiisoft/form-model) populates form models. Once you [register the caster for form models](#registering-for-form-models), you can declare form properties as value objects too:" -msgstr "" +msgstr "O `FormHydrator` do [Yii Form Model](https://github.com/yiisoft/form-model) preenche form models. Depois que você [registra o caster para form models](#registrando-para-form-models), também pode declarar propriedades de formulário como value objects:" #. type: Fenced code block (php) #: ../src/cookbook/custom-hydrator-type-casters.md @@ -665,6 +920,26 @@ msgid "" " public ?UserId $authorId = null;\n" "}\n" msgstr "" +"formHydrator->populateFromPostAndValidate($form, $request)) {\n" +" // $form->authorId é UserId.\n" +" // ...\n" +" }\n" +"\n" +" // ...\n" +" }\n" +"}\n" #. type: Title ### #: ../src/cookbook/custom-hydrator-type-casters.md #, no-wrap msgid "Null and invalid values" -msgstr "" +msgstr "Valores nulos e inválidos" #. type: Plain text #: ../src/cookbook/custom-hydrator-type-casters.md msgid "Here is what happens with a property declared as `?UserId` for different input values:" -msgstr "" +msgstr "Veja o que acontece com uma propriedade declarada como `?UserId` para diferentes valores de entrada:" #. type: Plain text #: ../src/cookbook/custom-hydrator-type-casters.md @@ -715,59 +1012,64 @@ msgid "" "| `null` | `PhpNativeTypeCaster` | `null` |\n" "| `'not-a-uuid'` | none, all casters fail | default value, `null` in example |\n" msgstr "" +"| Valor de entrada | Tratado por | Valor da propriedade |\n" +"|------------------------------------------|------------------------|----------------------------------|\n" +"| `'0192f2a4-7a4b-7c3e-9a1b-3f5c8d2e6a10'` | `UuidValueTypeCaster` | instância de `UserId` |\n" +"| `null` | `PhpNativeTypeCaster` | `null` |\n" +"| `'not-a-uuid'` | nenhum, todos falham | valor padrão, `null` no exemplo |\n" #. type: Plain text #: ../src/cookbook/custom-hydrator-type-casters.md msgid "The last row is the important one: the hydrator doesn't report the malformed value. With the `Required` rule, validation catches it with the \"cannot be blank\" error. See the [request input](#request-input) and [form model](#form-model) examples. But if the property is optional, an invalid UUID is silently turned into `null` and is indistinguishable from a missing value. If that's not acceptable, keep the raw value for validation: declare the property as `string`, validate its format, and convert it to the value object after validation." -msgstr "" +msgstr "A última linha é a importante: o hydrator não reporta o valor malformado. Com a regra `Required`, a validação o detecta com o erro \"cannot be blank\". Veja os exemplos de [entrada da requisição](#entrada-da-requisicao) e [form model](#form-model). Mas, se a propriedade for opcional, um UUID inválido é silenciosamente transformado em `null` e fica indistinguível de um valor ausente. Se isso não for aceitável, mantenha o valor bruto para validação: declare a propriedade como `string`, valide seu formato e converta-a para o value object após a validação." #. type: Title ## #: ../src/cookbook/custom-hydrator-type-casters.md #, no-wrap msgid "When to use a type caster" -msgstr "" +msgstr "Quando usar um type caster" #. type: Plain text #: ../src/cookbook/custom-hydrator-type-casters.md msgid "A type caster fits well when the conversion:" -msgstr "" +msgstr "Um type caster é uma boa escolha quando a conversão:" #. type: Bullet: '- ' #: ../src/cookbook/custom-hydrator-type-casters.md msgid "depends only on the value and the declared type." -msgstr "" +msgstr "depende apenas do valor e do tipo declarado." #. type: Bullet: '- ' #: ../src/cookbook/custom-hydrator-type-casters.md msgid "is the same everywhere in the application." -msgstr "" +msgstr "é a mesma em toda a aplicação." #. type: Bullet: '- ' #: ../src/cookbook/custom-hydrator-type-casters.md msgid "doesn't need I/O, such as database queries or HTTP calls." -msgstr "" +msgstr "não precisa de I/O, como consultas ao banco de dados ou chamadas HTTP." #. type: Plain text #: ../src/cookbook/custom-hydrator-type-casters.md msgid "Value objects for IDs, emails, and money amounts match all three. Keep the conversion in a dedicated mapper or a domain factory instead when it:" -msgstr "" +msgstr "Value objects para IDs, e-mails e valores monetários atendem aos três critérios. Mantenha a conversão em um mapper dedicado ou em uma factory de domínio quando ela:" #. type: Bullet: '- ' #: ../src/cookbook/custom-hydrator-type-casters.md msgid "needs a database lookup, for example, turning an ID into a loaded entity." -msgstr "" +msgstr "precisa consultar o banco de dados, por exemplo, transformar um ID em uma entidade carregada." #. type: Bullet: '- ' #: ../src/cookbook/custom-hydrator-type-casters.md msgid "depends on context, such as the current user." -msgstr "" +msgstr "depende de contexto, como o usuário atual." #. type: Bullet: '- ' #: ../src/cookbook/custom-hydrator-type-casters.md msgid "combines several input fields into one object." -msgstr "" +msgstr "combina vários campos de entrada em um único objeto." #. type: Bullet: '- ' #: ../src/cookbook/custom-hydrator-type-casters.md msgid "differs between use cases." -msgstr "" +msgstr "difere entre casos de uso." diff --git a/_translations/po/pt-BR/cookbook_custom-migration-template.md.po b/_translations/po/pt-BR/cookbook_custom-migration-template.md.po index d2bfc038..c5f32e99 100644 --- a/_translations/po/pt-BR/cookbook_custom-migration-template.md.po +++ b/_translations/po/pt-BR/cookbook_custom-migration-template.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-06-05 22:11+0000\n" "PO-Revision-Date: 2026-06-05 22:11+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,28 +19,28 @@ msgstr "" #: ../src/cookbook/custom-migration-template.md #, no-wrap msgid "Using a custom migration template" -msgstr "" +msgstr "Usando um template de migration personalizado" #. type: Plain text #: ../src/cookbook/custom-migration-template.md msgid "The `migrate:create` command from `yiisoft/db-migration` generates migration classes from PHP view templates. Use a custom template when your project wants a standard header, strict class shape, comments, helper calls, or team-specific placeholders in every new migration." -msgstr "" +msgstr "O comando `migrate:create` do `yiisoft/db-migration` gera classes de migration a partir de templates PHP de view. Use um template personalizado quando seu projeto quiser um cabeçalho padrão, um formato de classe rígido, comentários, chamadas a helpers ou placeholders específicos da equipe em toda nova migration." #. type: Plain text #: ../src/cookbook/custom-migration-template.md msgid "This recipe assumes migrations are already configured as described in the [Database migrations](../guide/databases/db-migrations.md) guide." -msgstr "" +msgstr "Esta receita assume que as migrations já estão configuradas como descrito no guia [Migrations de banco de dados](../guide/databases/db-migrations.md)." #. type: Title ## #: ../src/cookbook/custom-migration-template.md #, no-wrap msgid "Create a template" -msgstr "" +msgstr "Crie um template" #. type: Plain text #: ../src/cookbook/custom-migration-template.md msgid "Create `resources/migration-templates/migration.php`:" -msgstr "" +msgstr "Crie `resources/migration-templates/migration.php`:" #. type: Fenced code block (php) #: ../src/cookbook/custom-migration-template.md @@ -82,22 +82,57 @@ msgid "" " }\n" "}\n" msgstr "" +"\n" +"\n" +"use Yiisoft\\Db\\Migration\\MigrationBuilder;\n" +"use Yiisoft\\Db\\Migration\\RevertibleMigrationInterface;\n" +"\n" +"final class implements RevertibleMigrationInterface\n" +"{\n" +" public function up(MigrationBuilder $b): void\n" +" {\n" +" // Add forward migration code.\n" +" }\n" +"\n" +" public function down(MigrationBuilder $b): void\n" +" {\n" +" // Add rollback migration code.\n" +" }\n" +"}\n" #. type: Plain text #: ../src/cookbook/custom-migration-template.md msgid "The template is a PHP file that prints the generated migration. For the default `create` command, the most useful variables are `$className` and `$namespace`." -msgstr "" +msgstr "O template é um arquivo PHP que imprime a migration gerada. Para o comando `create` padrão, as variáveis mais úteis são `$className` e `$namespace`." #. type: Title ## #: ../src/cookbook/custom-migration-template.md #, no-wrap msgid "Configure the generator" -msgstr "" +msgstr "Configure o gerador" #. type: Plain text #: ../src/cookbook/custom-migration-template.md msgid "Create `config/common/di/migration-generator.php`:" -msgstr "" +msgstr "Crie `config/common/di/migration-generator.php`:" #. type: Fenced code block (php) #: ../src/cookbook/custom-migration-template.md @@ -118,83 +153,93 @@ msgid "" " ],\n" "];\n" msgstr "" +" [\n" +" 'setTemplate()' => [\n" +" 'create',\n" +" dirname(__DIR__, 3) . '/resources/migration-templates/migration.php',\n" +" ],\n" +" ],\n" +"];\n" #. type: Plain text #: ../src/cookbook/custom-migration-template.md msgid "The `create` key changes the template used by:" -msgstr "" +msgstr "A chave `create` muda o template usado por:" #. type: Fenced code block (shell) #: ../src/cookbook/custom-migration-template.md #, no-wrap msgid "./yii migrate:create audit_log\n" -msgstr "" +msgstr "./yii migrate:create audit_log\n" #. type: Plain text #: ../src/cookbook/custom-migration-template.md msgid "The command asks for confirmation and then writes a migration using your template." -msgstr "" +msgstr "O comando pede confirmação e então grava uma migration usando o seu template." #. type: Plain text #: ../src/cookbook/custom-migration-template.md msgid "If the new DI file is not picked up, rebuild the config merge plan:" -msgstr "" +msgstr "Se o novo arquivo de DI não for carregado, reconstrua o merge plan da configuração:" #. type: Fenced code block (sh) -#: ../src/cookbook/custom-migration-template.md -#: ../src/cookbook/using-yii-in-third-party-apps.md -#: ../src/guide/structure/designing-packages.md -#: ../src/guide/structure/module.md ../src/guide/structure/package.md -#: ../src/guide/tutorial/i18n.md +#: ../src/cookbook/custom-migration-template.md ../src/cookbook/using-yii-in-third-party-apps.md ../src/guide/structure/designing-packages.md ../src/guide/structure/module.md ../src/guide/structure/package.md ../src/guide/tutorial/i18n.md #, no-wrap msgid "composer yii-config-rebuild\n" -msgstr "" +msgstr "composer yii-config-rebuild\n" #. type: Title ## #: ../src/cookbook/custom-migration-template.md #, no-wrap msgid "Configure multiple templates" -msgstr "" +msgstr "Configure vários templates" #. type: Plain text #: ../src/cookbook/custom-migration-template.md msgid "`yiisoft/db-migration` supports these template keys:" -msgstr "" +msgstr "O `yiisoft/db-migration` suporta estas chaves de template:" #. type: Bullet: '- ' #: ../src/cookbook/custom-migration-template.md msgid "`create`" -msgstr "" +msgstr "`create`" #. type: Bullet: '- ' #: ../src/cookbook/custom-migration-template.md msgid "`table`" -msgstr "" +msgstr "`table`" #. type: Bullet: '- ' #: ../src/cookbook/custom-migration-template.md msgid "`dropTable`" -msgstr "" +msgstr "`dropTable`" #. type: Bullet: '- ' #: ../src/cookbook/custom-migration-template.md msgid "`addColumn`" -msgstr "" +msgstr "`addColumn`" #. type: Bullet: '- ' #: ../src/cookbook/custom-migration-template.md msgid "`dropColumn`" -msgstr "" +msgstr "`dropColumn`" #. type: Bullet: '- ' #: ../src/cookbook/custom-migration-template.md msgid "`junction`" -msgstr "" +msgstr "`junction`" #. type: Plain text #: ../src/cookbook/custom-migration-template.md msgid "To replace multiple templates at once, use `setTemplates()`:" -msgstr "" +msgstr "Para substituir vários templates de uma vez, use `setTemplates()`:" #. type: Fenced code block (php) #: ../src/cookbook/custom-migration-template.md @@ -215,24 +260,38 @@ msgid "" " ],\n" "];\n" msgstr "" +"use Yiisoft\\Db\\Migration\\Service\\Generate\\CreateService;\n" +"\n" +"return [\n" +" CreateService::class => [\n" +" 'setTemplates()' => [[\n" +" 'create' => dirname(__DIR__, 3) . '/resources/migration-templates/migration.php',\n" +" 'table' => dirname(__DIR__, 3) . '/resources/migration-templates/create-table.php',\n" +" 'dropTable' => dirname(__DIR__, 3) . '/resources/migration-templates/drop-table.php',\n" +" 'addColumn' => dirname(__DIR__, 3) . '/resources/migration-templates/add-column.php',\n" +" 'dropColumn' => dirname(__DIR__, 3) . '/resources/migration-templates/drop-column.php',\n" +" 'junction' => dirname(__DIR__, 3) . '/resources/migration-templates/create-junction.php',\n" +" ]],\n" +" ],\n" +"];\n" #. type: Plain text #: ../src/cookbook/custom-migration-template.md msgid "For table-oriented templates, copy the corresponding file from `vendor/yiisoft/db-migration/resources/views/` and adjust it. Those templates receive additional variables such as `$table`, `$columns`, `$foreignKeys`, and `$tableComment`." -msgstr "" +msgstr "Para os templates voltados a tabelas, copie o arquivo correspondente de `vendor/yiisoft/db-migration/resources/views/` e ajuste-o. Esses templates recebem variáveis adicionais, como `$table`, `$columns`, `$foreignKeys` e `$tableComment`." #. type: Title ## #: ../src/cookbook/custom-migration-template.md #, no-wrap msgid "Keep templates maintainable" -msgstr "" +msgstr "Mantenha os templates fáceis de manter" #. type: Plain text #: ../src/cookbook/custom-migration-template.md msgid "Keep generated migrations independent from current application services. A migration may run years later, after service APIs have changed. Put stable schema operations in the generated class and leave business logic in console commands or application services." -msgstr "" +msgstr "Mantenha as migrations geradas independentes dos serviços atuais da aplicação. Uma migration pode rodar anos depois, quando as APIs dos serviços já mudaram. Coloque operações de schema estáveis na classe gerada e deixe a lógica de negócio em comandos de console ou serviços da aplicação." #. type: Plain text #: ../src/cookbook/custom-migration-template.md msgid "Do not edit templates under `vendor/`. Copy them into your project and configure `CreateService` to use the copies." -msgstr "" +msgstr "Não edite templates dentro de `vendor/`. Copie-os para o seu projeto e configure o `CreateService` para usar as cópias." diff --git a/_translations/po/pt-BR/cookbook_deployment_angie-docker-proxy.md.po b/_translations/po/pt-BR/cookbook_deployment_angie-docker-proxy.md.po index 421f3aa9..b19a8be5 100644 --- a/_translations/po/pt-BR/cookbook_deployment_angie-docker-proxy.md.po +++ b/_translations/po/pt-BR/cookbook_deployment_angie-docker-proxy.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-09-25 14:35+0000\n" "PO-Revision-Date: 2026-09-25 14:35+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,27 +19,27 @@ msgstr "" #: ../src/cookbook/deployment/angie-docker-proxy.md #, no-wrap msgid "Deploying Yii applications with Angie Docker Proxy" -msgstr "" +msgstr "Fazendo deploy de aplicações Yii com o Angie Docker Proxy" #. type: Plain text #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "[Angie Docker Proxy](https://hub.docker.com/r/angiesoftware/proxy) is a small reverse proxy for Docker Compose projects. It runs in a separate container alongside the applications, reads the Docker API through the Docker socket, discovers containers using the `VIRTUAL_HOST` and `VIRTUAL_PORT` environment variables, generates the Angie configuration, and automatically obtains TLS certificates using ACME." -msgstr "" +msgstr "O [Angie Docker Proxy](https://hub.docker.com/r/angiesoftware/proxy) é um pequeno proxy reverso para projetos Docker Compose. Ele roda em um container separado, ao lado das aplicações, lê a API do Docker pelo socket do Docker, descobre containers pelas variáveis de ambiente `VIRTUAL_HOST` e `VIRTUAL_PORT`, gera a configuração do Angie e obtém certificados TLS automaticamente via ACME." #. type: Plain text #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "This approach is useful when you need to run several web applications on one server and enable HTTPS for them without manually editing the reverse proxy configuration for each domain." -msgstr "" +msgstr "Essa abordagem é útil quando você precisa rodar várias aplicações web em um servidor e habilitar HTTPS para elas sem editar manualmente a configuração do proxy reverso para cada domínio." #. type: Plain text #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "In this example, we'll connect a containerized Yii application to Angie Docker Proxy and configure automatic HTTPS." -msgstr "" +msgstr "Neste exemplo, vamos conectar uma aplicação Yii em container ao Angie Docker Proxy e configurar HTTPS automático." #. type: Plain text #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "This guide assumes that your Yii application is already packaged as a Docker image and accepts HTTP requests on port 80. Building and configuring the application image is outside the scope of this guide." -msgstr "" +msgstr "Este guia assume que sua aplicação Yii já está empacotada como imagem Docker e aceita requisições HTTP na porta 80. Construir e configurar a imagem da aplicação está fora do escopo deste guia." #. type: Fenced code block (mermaid) #: ../src/cookbook/deployment/angie-docker-proxy.md @@ -56,57 +56,63 @@ msgid "" " D\n" " end\n" msgstr "" +"graph LR\n" +" A[Internet] --> B[Proxy reverso: Angie]\n" +" B --> C[Aplicação Yii]\n" +" B --> D[Outra aplicação]\n" +"\n" +" subgraph Docker Compose Project\n" +" B\n" +" C\n" +" D\n" +" end\n" #. type: Title ## -#: ../src/cookbook/deployment/angie-docker-proxy.md -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md -#: ../src/cookbook/preface.md +#: ../src/cookbook/deployment/angie-docker-proxy.md ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md ../src/cookbook/preface.md #, no-wrap msgid "Prerequisites" -msgstr "" +msgstr "Pré-requisitos" #. type: Bullet: '- ' #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "A server with a fresh Linux distribution." -msgstr "" +msgstr "Um servidor com uma distribuição Linux recém-instalada." #. type: Bullet: '- ' #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "A domain name pointing to your server's IP address." -msgstr "" +msgstr "Um nome de domínio apontando para o IP do seu servidor." #. type: Bullet: '- ' #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "Docker and Docker Compose." -msgstr "" +msgstr "Docker e Docker Compose." #. type: Bullet: '- ' #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "Open TCP ports `80` and `443`." -msgstr "" +msgstr "Portas TCP `80` e `443` abertas." #. type: Bullet: '- ' #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "SSH access to your server." -msgstr "" +msgstr "Acesso SSH ao seu servidor." #. type: Bullet: '- ' #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "Basic knowledge of Docker and command-line tools." -msgstr "" +msgstr "Conhecimento básico de Docker e de ferramentas de linha de comando." #. type: Title ## -#: ../src/cookbook/deployment/angie-docker-proxy.md -#: ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md +#: ../src/cookbook/deployment/angie-docker-proxy.md ../src/guide/intro/upgrade-from-v1.md ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "Project structure" -msgstr "" +msgstr "Estrutura do projeto" #. type: Plain text #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "The example requires a single Docker Compose configuration:" -msgstr "" +msgstr "O exemplo precisa de uma única configuração do Docker Compose:" #. type: Fenced code block (text) #: ../src/cookbook/deployment/angie-docker-proxy.md @@ -115,32 +121,34 @@ msgid "" "yii-angie-demo/\n" "└── docker-compose.yml\n" msgstr "" +"yii-angie-demo/\n" +"└── docker-compose.yml\n" #. type: Title ## #: ../src/cookbook/deployment/angie-docker-proxy.md #, no-wrap msgid "Configuring Docker Compose" -msgstr "" +msgstr "Configurando o Docker Compose" #. type: Plain text #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "Create `docker-compose.yml` with the following configuration. Replace:" -msgstr "" +msgstr "Crie o `docker-compose.yml` com a configuração a seguir. Substitua:" #. type: Bullet: '- ' #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "`admin@example.com` with your email address;" -msgstr "" +msgstr "`admin@example.com` pelo seu endereço de e-mail;" #. type: Bullet: '- ' #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "`registry.example.com/yii-app:1.0.0` with your application image;" -msgstr "" +msgstr "`registry.example.com/yii-app:1.0.0` pela imagem da sua aplicação;" #. type: Bullet: '- ' #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "`example-demo.example.com` with the domain pointing to your server." -msgstr "" +msgstr "`example-demo.example.com` pelo domínio que aponta para o seu servidor." #. type: Fenced code block (yaml) #: ../src/cookbook/deployment/angie-docker-proxy.md @@ -179,49 +187,81 @@ msgid "" "volumes:\n" " angie_acme:\n" msgstr "" +"services:\n" +" angie-proxy:\n" +" image: angiesoftware/proxy:latest\n" +" environment:\n" +" - ANGIE_ACME_EMAIL=admin@example.com\n" +" - ANGIE_ACME_URL=https://acme-v02.api.letsencrypt.org/directory\n" +" - ANGIE_RESOLVER=1.1.1.1 8.8.8.8\n" +" - ANGIE_RESOLVER_VALID=300s\n" +" - ANGIE_PROXY_NETWORK=proxy\n" +" ports:\n" +" - \"80:80\"\n" +" - \"443:443\"\n" +" volumes:\n" +" - /var/run/docker.sock:/tmp/docker.sock:ro\n" +" - angie_acme:/var/lib/angie/acme\n" +" networks:\n" +" - proxy\n" +"\n" +" yii-app:\n" +" image: registry.example.com/yii-app:1.0.0\n" +" environment:\n" +" - VIRTUAL_HOST=example-demo.example.com\n" +" - VIRTUAL_PORT=80\n" +" networks:\n" +" - proxy\n" +"\n" +"networks:\n" +" proxy:\n" +" name: proxy\n" +"\n" +"volumes:\n" +" angie_acme:\n" #. type: Plain text #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "`VIRTUAL_HOST` is the application's public domain." -msgstr "" +msgstr "`VIRTUAL_HOST` é o domínio público da aplicação." #. type: Plain text #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "`VIRTUAL_PORT` is the container's internal port to which Angie should proxy requests." -msgstr "" +msgstr "`VIRTUAL_PORT` é a porta interna do container para a qual o Angie deve encaminhar as requisições." #. type: Plain text #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "Angie Docker Proxy automatically discovers `VIRTUAL_HOST` and `VIRTUAL_PORT` from the environment variables and issues certificates using the Angie ACME module and Let's Encrypt." -msgstr "" +msgstr "O Angie Docker Proxy descobre `VIRTUAL_HOST` e `VIRTUAL_PORT` automaticamente pelas variáveis de ambiente e emite certificados usando o módulo ACME do Angie e o Let's Encrypt." #. type: Title ## #: ../src/cookbook/deployment/angie-docker-proxy.md #, no-wrap msgid "Starting the services" -msgstr "" +msgstr "Subindo os serviços" #. type: Plain text #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "Start the proxy and application containers:" -msgstr "" +msgstr "Suba os containers do proxy e da aplicação:" #. type: Fenced code block (bash) #: ../src/cookbook/deployment/angie-docker-proxy.md #, no-wrap msgid "docker compose up -d\n" -msgstr "" +msgstr "docker compose up -d\n" #. type: Title ## #: ../src/cookbook/deployment/angie-docker-proxy.md #, no-wrap msgid "Adding another application" -msgstr "" +msgstr "Adicionando outra aplicação" #. type: Plain text #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "To expose another application, add it to `services` in `docker-compose.yml` and attach it to the `proxy` network:" -msgstr "" +msgstr "Para expor outra aplicação, adicione-a em `services` no `docker-compose.yml` e conecte-a à rede `proxy`:" #. type: Fenced code block (yaml) #: ../src/cookbook/deployment/angie-docker-proxy.md @@ -236,65 +276,73 @@ msgid "" " networks:\n" " - proxy\n" msgstr "" +"services:\n" +" second-app:\n" +" image: traefik/whoami\n" +" environment:\n" +" - VIRTUAL_HOST=example-demo2.example.com\n" +" - VIRTUAL_PORT=80\n" +" networks:\n" +" - proxy\n" #. type: Plain text #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "Apply the changes:" -msgstr "" +msgstr "Aplique as alterações:" #. type: Title ## #: ../src/cookbook/deployment/angie-docker-proxy.md #, no-wrap msgid "How it works" -msgstr "" +msgstr "Como funciona" #. type: Plain text #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "Angie Docker Proxy monitors the Docker API and discovers containers configured with `VIRTUAL_HOST` and `VIRTUAL_PORT`. It generates the Angie configuration, obtains TLS certificates using ACME, and forwards incoming requests to the corresponding containers through the shared Docker network." -msgstr "" +msgstr "O Angie Docker Proxy monitora a API do Docker e descobre os containers configurados com `VIRTUAL_HOST` e `VIRTUAL_PORT`. Ele gera a configuração do Angie, obtém certificados TLS via ACME e encaminha as requisições recebidas para os containers correspondentes pela rede Docker compartilhada." #. type: Plain text #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "When containers are added, removed, or updated, the proxy regenerates its configuration and performs a graceful reload. Existing connections continue to be handled while the updated configuration is applied." -msgstr "" +msgstr "Quando containers são adicionados, removidos ou atualizados, o proxy gera a configuração de novo e faz um reload gracioso. As conexões existentes continuam sendo atendidas enquanto a configuração atualizada é aplicada." #. type: Plain text #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "For configuration options and implementation details, see the [Angie Docker Proxy documentation](https://hub.docker.com/r/angiesoftware/proxy)." -msgstr "" +msgstr "Para opções de configuração e detalhes de implementação, veja a [documentação do Angie Docker Proxy](https://hub.docker.com/r/angiesoftware/proxy)." #. type: Title ## #: ../src/cookbook/deployment/angie-docker-proxy.md #, no-wrap msgid "Verification" -msgstr "" +msgstr "Verificação" #. type: Plain text #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "Check the containers:" -msgstr "" +msgstr "Verifique os containers:" #. type: Fenced code block (bash) #: ../src/cookbook/deployment/angie-docker-proxy.md #, no-wrap msgid "docker compose ps\n" -msgstr "" +msgstr "docker compose ps\n" #. type: Plain text #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "Check the HTTP redirect:" -msgstr "" +msgstr "Verifique o redirecionamento HTTP:" #. type: Fenced code block (bash) #: ../src/cookbook/deployment/angie-docker-proxy.md #, no-wrap msgid "curl -I http://example-demo.example.com/\n" -msgstr "" +msgstr "curl -I http://example-demo.example.com/\n" #. type: Plain text #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "Expected result:" -msgstr "" +msgstr "Resultado esperado:" #. type: Fenced code block (text) #: ../src/cookbook/deployment/angie-docker-proxy.md @@ -303,17 +351,19 @@ msgid "" "HTTP/1.1 301 Moved Permanently\n" "Location: https://example-demo.example.com/\n" msgstr "" +"HTTP/1.1 301 Moved Permanently\n" +"Location: https://example-demo.example.com/\n" #. type: Plain text #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "Check HTTPS:" -msgstr "" +msgstr "Verifique o HTTPS:" #. type: Fenced code block (bash) #: ../src/cookbook/deployment/angie-docker-proxy.md #, no-wrap msgid "curl -I https://example-demo.example.com/\n" -msgstr "" +msgstr "curl -I https://example-demo.example.com/\n" #. type: Fenced code block (text) #: ../src/cookbook/deployment/angie-docker-proxy.md @@ -322,11 +372,13 @@ msgid "" "HTTP/1.1 200 OK\n" "Server: Angie/...\n" msgstr "" +"HTTP/1.1 200 OK\n" +"Server: Angie/...\n" #. type: Plain text #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "Check the certificate:" -msgstr "" +msgstr "Verifique o certificado:" #. type: Fenced code block (bash) #: ../src/cookbook/deployment/angie-docker-proxy.md @@ -337,96 +389,100 @@ msgid "" " -servername example-demo.example.com 2>/dev/null \\\n" " | openssl x509 -noout -issuer -subject -dates\n" msgstr "" +"echo | openssl s_client \\\n" +" -connect example-demo.example.com:443 \\\n" +" -servername example-demo.example.com 2>/dev/null \\\n" +" | openssl x509 -noout -issuer -subject -dates\n" #. type: Plain text #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "Expected issuer:" -msgstr "" +msgstr "Emissor esperado:" #. type: Fenced code block (text) #: ../src/cookbook/deployment/angie-docker-proxy.md #, no-wrap msgid "Let's Encrypt\n" -msgstr "" +msgstr "Let's Encrypt\n" #. type: Title ## #: ../src/cookbook/deployment/angie-docker-proxy.md #, no-wrap msgid "Logs" -msgstr "" +msgstr "Logs" #. type: Plain text #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "Proxy logs:" -msgstr "" +msgstr "Logs do proxy:" #. type: Fenced code block (bash) #: ../src/cookbook/deployment/angie-docker-proxy.md #, no-wrap msgid "docker compose logs -f angie-proxy\n" -msgstr "" +msgstr "docker compose logs -f angie-proxy\n" #. type: Title ## #: ../src/cookbook/deployment/angie-docker-proxy.md #, no-wrap msgid "Stopping the services" -msgstr "" +msgstr "Parando os serviços" #. type: Plain text #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "Stop the services:" -msgstr "" +msgstr "Pare os serviços:" #. type: Fenced code block (bash) #: ../src/cookbook/deployment/angie-docker-proxy.md #, no-wrap msgid "docker compose down\n" -msgstr "" +msgstr "docker compose down\n" #. type: Plain text #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "Stop the services and remove the certificates:" -msgstr "" +msgstr "Pare os serviços e remova os certificados:" #. type: Fenced code block (bash) #: ../src/cookbook/deployment/angie-docker-proxy.md #, no-wrap msgid "docker compose down -v\n" -msgstr "" +msgstr "docker compose down -v\n" #. type: Title ## #: ../src/cookbook/deployment/angie-docker-proxy.md #, no-wrap msgid "Limitations" -msgstr "" +msgstr "Limitações" #. type: Plain text #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "This setup is intended for Docker Compose. Kubernetes doesn't expose workloads through the Docker API and requires an Ingress or Gateway API controller. Docker Swarm also uses the Docker API, but Swarm deployment isn't covered in this guide." -msgstr "" +msgstr "Esta configuração é feita para o Docker Compose. O Kubernetes não expõe workloads pela API do Docker e exige um controller de Ingress ou de Gateway API. O Docker Swarm também usa a API do Docker, mas o deploy no Swarm não é coberto neste guia." #. type: Title ## #: ../src/cookbook/deployment/angie-docker-proxy.md #, no-wrap msgid "For more information" -msgstr "" +msgstr "Para mais informações" #. type: Bullet: '- ' #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "[Angie Docker Proxy documentation](https://hub.docker.com/r/angiesoftware/proxy)" -msgstr "" +msgstr "[Documentação do Angie Docker Proxy](https://hub.docker.com/r/angiesoftware/proxy)" #. type: Bullet: '- ' #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "[Yii Application Template](https://github.com/yiisoft/app)" -msgstr "" +msgstr "[Template de aplicação do Yii](https://github.com/yiisoft/app)" #. type: Bullet: '- ' #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "[Docker in Yii Application Templates](https://yiisoft.github.io/docs/guide/tutorial/docker.html)" -msgstr "" +msgstr "[Docker nos templates de aplicação do Yii](https://yiisoft.github.io/docs/guide/tutorial/docker.html)" #. type: Bullet: '- ' #: ../src/cookbook/deployment/angie-docker-proxy.md msgid "[Docker Compose documentation](https://docs.docker.com/compose/)" -msgstr "" +msgstr "[Documentação do Docker Compose](https://docs.docker.com/compose/)" diff --git a/_translations/po/pt-BR/cookbook_deployment_autoscaling.md.po b/_translations/po/pt-BR/cookbook_deployment_autoscaling.md.po index a9fc896b..4a3eb94b 100644 --- a/_translations/po/pt-BR/cookbook_deployment_autoscaling.md.po +++ b/_translations/po/pt-BR/cookbook_deployment_autoscaling.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-06-02 22:17+0000\n" "PO-Revision-Date: 2026-06-02 22:17+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,69 +19,69 @@ msgstr "" #: ../src/cookbook/deployment/autoscaling.md #, no-wrap msgid "Configuring an application for autoscaling" -msgstr "" +msgstr "Configurando uma aplicação para autoscaling" #. type: Plain text #: ../src/cookbook/deployment/autoscaling.md msgid "Autoscaling works when any application instance can handle any request and can be added or removed without special local state. In Yii applications this mostly means keeping runtime state outside the container or VM, making health checks cheap, and running migrations and workers separately from web replicas." -msgstr "" +msgstr "O autoscaling funciona quando qualquer instância da aplicação consegue atender qualquer requisição e pode ser adicionada ou removida sem estado local especial. Em aplicações Yii, isso significa principalmente manter o estado de runtime fora do container ou da VM, deixar os health checks baratos e rodar migrations e workers separados das réplicas web." #. type: Title ## #: ../src/cookbook/deployment/autoscaling.md #, no-wrap msgid "Keep web instances stateless" -msgstr "" +msgstr "Mantenha as instâncias web sem estado" #. type: Plain text #: ../src/cookbook/deployment/autoscaling.md msgid "Do not store user-visible state on the local filesystem of a web instance. Local files disappear when an instance is replaced and are not visible to other replicas." -msgstr "" +msgstr "Não guarde estado visível ao usuário no sistema de arquivos local de uma instância web. Arquivos locais somem quando uma instância é substituída e não ficam visíveis para as outras réplicas." #. type: Plain text #: ../src/cookbook/deployment/autoscaling.md msgid "Move these resources to shared services:" -msgstr "" +msgstr "Mova estes recursos para serviços compartilhados:" #. type: Bullet: '- ' #: ../src/cookbook/deployment/autoscaling.md msgid "Sessions: use a shared session handler when users can move between replicas. See [Sessions](../../guide/runtime/sessions.md) and prefer closing sessions early." -msgstr "" +msgstr "Sessões: use um handler de sessão compartilhado quando os usuários puderem alternar entre réplicas. Veja [Sessões](../../guide/runtime/sessions.md) e prefira fechar as sessões cedo." #. type: Bullet: '- ' #: ../src/cookbook/deployment/autoscaling.md msgid "Cache: use Redis, Memcached, database, or another shared PSR-16 cache backend for data that must be consistent across replicas. See [Data caching](../../guide/caching/data.md)." -msgstr "" +msgstr "Cache: use Redis, Memcached, banco de dados ou outro backend de cache PSR-16 compartilhado para dados que precisam ser consistentes entre as réplicas. Veja [Cache de dados](../../guide/caching/data.md)." #. type: Bullet: '- ' #: ../src/cookbook/deployment/autoscaling.md msgid "Uploads: store files in object storage, a shared volume, or a service dedicated to file storage. Local `runtime` or `public/uploads` directories are safe only for temporary files." -msgstr "" +msgstr "Uploads: guarde arquivos em object storage, em um volume compartilhado ou em um serviço dedicado ao armazenamento de arquivos. Os diretórios locais `runtime` ou `public/uploads` só são seguros para arquivos temporários." #. type: Bullet: '- ' #: ../src/cookbook/deployment/autoscaling.md msgid "Generated assets: build them into the image or publish them to shared storage/CDN during deployment." -msgstr "" +msgstr "Assets gerados: inclua-os na imagem ou publique-os em um armazenamento compartilhado/CDN durante o deploy." #. type: Bullet: '- ' #: ../src/cookbook/deployment/autoscaling.md msgid "Logs: write to stdout/stderr or a central log target. Do not depend on files inside a short-lived instance." -msgstr "" +msgstr "Logs: escreva em stdout/stderr ou em um destino de log central. Não dependa de arquivos dentro de uma instância de vida curta." #. type: Plain text #: ../src/cookbook/deployment/autoscaling.md msgid "Sticky sessions can reduce immediate pressure, but they are not a substitute for shared state. A replacement instance or deployment rollout still breaks local session and upload storage." -msgstr "" +msgstr "Sticky sessions podem aliviar a pressão imediata, mas não substituem o estado compartilhado. Uma instância substituta ou o rollout de um deploy ainda quebram o armazenamento local de sessões e de uploads." #. type: Title ## #: ../src/cookbook/deployment/autoscaling.md #, no-wrap msgid "Add health endpoints" -msgstr "" +msgstr "Adicione endpoints de saúde" #. type: Plain text #: ../src/cookbook/deployment/autoscaling.md msgid "Use a cheap liveness endpoint for the load balancer or orchestrator:" -msgstr "" +msgstr "Use um endpoint de liveness barato para o load balancer ou o orquestrador:" #. type: Fenced code block (php) #: ../src/cookbook/deployment/autoscaling.md @@ -110,11 +110,33 @@ msgid "" " }\n" "}\n" msgstr "" +"responseFactory->createResponse(Status::NO_CONTENT);\n" +" }\n" +"}\n" #. type: Plain text #: ../src/cookbook/deployment/autoscaling.md msgid "Register it in `config/common/routes.php`:" -msgstr "" +msgstr "Registre-o em `config/common/routes.php`:" #. type: Fenced code block (php) #: ../src/cookbook/deployment/autoscaling.md @@ -130,100 +152,109 @@ msgid "" " ->name('healthz'),\n" "];\n" msgstr "" +"use App\\Web\\Health\\HealthCheckAction;\n" +"use Yiisoft\\Router\\Route;\n" +"\n" +"return [\n" +" // ...\n" +" Route::get('/healthz')\n" +" ->action(HealthCheckAction::class)\n" +" ->name('healthz'),\n" +"];\n" #. type: Plain text #: ../src/cookbook/deployment/autoscaling.md msgid "Keep this endpoint independent from the database and external APIs. It should answer whether the PHP process can accept requests, not whether every dependency is healthy." -msgstr "" +msgstr "Mantenha esse endpoint independente do banco de dados e de APIs externas. Ele deve responder se o processo PHP consegue aceitar requisições, não se todas as dependências estão saudáveis." #. type: Plain text #: ../src/cookbook/deployment/autoscaling.md msgid "If your platform supports readiness checks, add a separate endpoint such as `/readyz` for dependencies that must be available before routing traffic to a new instance. Keep it bounded with short timeouts. A slow readiness check can make a traffic spike worse." -msgstr "" +msgstr "Se a sua plataforma suporta readiness checks, adicione um endpoint separado, como `/readyz`, para as dependências que precisam estar disponíveis antes de direcionar tráfego para uma nova instância. Limite-o com timeouts curtos. Um readiness check lento pode piorar um pico de tráfego." #. type: Title ## #: ../src/cookbook/deployment/autoscaling.md #, no-wrap msgid "Configure runtime paths" -msgstr "" +msgstr "Configure os caminhos de runtime" #. type: Plain text #: ../src/cookbook/deployment/autoscaling.md msgid "The `runtime` directory should contain disposable process-local files only: logs before shipping, cache files that can be rebuilt, temporary upload chunks, locks scoped to one instance, and debug artifacts." -msgstr "" +msgstr "O diretório `runtime` deve conter apenas arquivos descartáveis e locais ao processo: logs antes de serem enviados, arquivos de cache que podem ser recriados, partes temporárias de upload, locks restritos a uma instância e artefatos de debug." #. type: Plain text #: ../src/cookbook/deployment/autoscaling.md msgid "For autoscaled deployments:" -msgstr "" +msgstr "Para deploys com autoscaling:" #. type: Bullet: '- ' #: ../src/cookbook/deployment/autoscaling.md msgid "mount `runtime` as an instance-local writable volume or create it during image startup;" -msgstr "" +msgstr "monte `runtime` como um volume gravável local à instância ou crie-o na inicialização da imagem;" #. type: Bullet: '- ' #: ../src/cookbook/deployment/autoscaling.md msgid "do not store permanent uploaded files in `runtime`;" -msgstr "" +msgstr "não guarde arquivos enviados permanentes em `runtime`;" #. type: Bullet: '- ' #: ../src/cookbook/deployment/autoscaling.md msgid "do not use local file locks for jobs that must be unique across all replicas;" -msgstr "" +msgstr "não use locks de arquivo locais para jobs que precisam ser únicos entre todas as réplicas;" #. type: Bullet: '- ' #: ../src/cookbook/deployment/autoscaling.md msgid "clear or ignore local runtime cache during rollouts." -msgstr "" +msgstr "limpe ou ignore o cache local de runtime durante os rollouts." #. type: Plain text #: ../src/cookbook/deployment/autoscaling.md msgid "When a command or worker must be unique globally, use a database lock, Redis lock, queue semantics, or run it as a single scheduled job outside the web autoscaling group." -msgstr "" +msgstr "Quando um comando ou worker precisa ser único globalmente, use um lock no banco de dados, um lock no Redis, a semântica da fila, ou rode-o como um único job agendado fora do grupo de autoscaling web." #. type: Title ## #: ../src/cookbook/deployment/autoscaling.md #, no-wrap msgid "Run migrations once" -msgstr "" +msgstr "Rode as migrations uma única vez" #. type: Plain text #: ../src/cookbook/deployment/autoscaling.md msgid "Do not run `./yii migrate` from every web instance during startup. Multiple replicas starting at the same time can compete for locks, slow down boot, or partially deploy incompatible schema." -msgstr "" +msgstr "Não rode `./yii migrate` em cada instância web durante a inicialização. Várias réplicas subindo ao mesmo tempo podem disputar locks, deixar o boot lento ou aplicar parcialmente um schema incompatível." #. type: Plain text #: ../src/cookbook/deployment/autoscaling.md msgid "Run migrations from one deployment job or a dedicated console container before or during rollout:" -msgstr "" +msgstr "Rode as migrations a partir de um único job de deploy ou de um container de console dedicado, antes ou durante o rollout:" #. type: Fenced code block (shell) #: ../src/cookbook/deployment/autoscaling.md #, no-wrap msgid "APP_ENV=prod php ./yii migrate --no-interaction\n" -msgstr "" +msgstr "APP_ENV=prod php ./yii migrate --no-interaction\n" #. type: Plain text #: ../src/cookbook/deployment/autoscaling.md msgid "For zero-downtime deployments, use an expand-and-contract migration flow. See [Applying migrations during rolling updates](rolling-update-migrations.md)." -msgstr "" +msgstr "Para deploys sem downtime, use um fluxo de migrations do tipo expand-and-contract. Veja [Aplicando migrations durante rolling updates](rolling-update-migrations.md)." #. type: Title ## #: ../src/cookbook/deployment/autoscaling.md #, no-wrap msgid "Separate web, workers, and scheduled jobs" -msgstr "" +msgstr "Separe web, workers e jobs agendados" #. type: Plain text #: ../src/cookbook/deployment/autoscaling.md msgid "Scale web replicas for request traffic. Scale queue workers for queue depth or processing latency. Run scheduled jobs from one scheduler, not from every web replica." -msgstr "" +msgstr "Escale as réplicas web conforme o tráfego de requisições. Escale os workers de fila conforme o tamanho da fila ou a latência de processamento. Rode os jobs agendados a partir de um único agendador, não de cada réplica web." #. type: Plain text #: ../src/cookbook/deployment/autoscaling.md msgid "Use the same application image when practical, but different entry points:" -msgstr "" +msgstr "Use a mesma imagem da aplicação quando for prático, mas com pontos de entrada diferentes:" #. type: Fenced code block (shell) #: ../src/cookbook/deployment/autoscaling.md @@ -232,105 +263,107 @@ msgid "" "php ./yii queue:listen\n" "php ./yii app:send-digests --no-interaction\n" msgstr "" +"php ./yii queue:listen\n" +"php ./yii app:send-digests --no-interaction\n" #. type: Plain text #: ../src/cookbook/deployment/autoscaling.md msgid "Make workers and scheduled commands idempotent. A deployment may stop a worker after it started processing a message, and the queue may deliver it again." -msgstr "" +msgstr "Torne workers e comandos agendados idempotentes. Um deploy pode parar um worker depois que ele começou a processar uma mensagem, e a fila pode entregá-la de novo." #. type: Title ## #: ../src/cookbook/deployment/autoscaling.md #, no-wrap msgid "Use environment-specific configuration" -msgstr "" +msgstr "Use configuração específica por ambiente" #. type: Plain text #: ../src/cookbook/deployment/autoscaling.md msgid "Keep secrets and per-environment values out of the image:" -msgstr "" +msgstr "Mantenha segredos e valores de cada ambiente fora da imagem:" #. type: Bullet: '- ' #: ../src/cookbook/deployment/autoscaling.md msgid "database DSN, username, and password;" -msgstr "" +msgstr "DSN, usuário e senha do banco de dados;" #. type: Bullet: '- ' #: ../src/cookbook/deployment/autoscaling.md msgid "cache/session backend addresses;" -msgstr "" +msgstr "endereços dos backends de cache/sessão;" #. type: Bullet: '- ' #: ../src/cookbook/deployment/autoscaling.md msgid "cookie validation keys and encryption keys;" -msgstr "" +msgstr "chaves de validação de cookies e chaves de criptografia;" #. type: Bullet: '- ' #: ../src/cookbook/deployment/autoscaling.md msgid "mail, queue, and object-storage credentials;" -msgstr "" +msgstr "credenciais de e-mail, fila e object storage;" #. type: Bullet: '- ' #: ../src/cookbook/deployment/autoscaling.md msgid "public base URL and trusted proxy settings." -msgstr "" +msgstr "URL base pública e configurações de proxies confiáveis." #. type: Plain text #: ../src/cookbook/deployment/autoscaling.md msgid "Load them through environment variables or environment-specific Yii config files. Every replica of the same release should receive the same configuration values, except for platform-provided instance metadata." -msgstr "" +msgstr "Carregue-os por variáveis de ambiente ou por arquivos de configuração do Yii específicos de cada ambiente. Todas as réplicas da mesma release devem receber os mesmos valores de configuração, exceto os metadados de instância fornecidos pela plataforma." #. type: Title ## #: ../src/cookbook/deployment/autoscaling.md #, no-wrap msgid "Capacity checklist" -msgstr "" +msgstr "Checklist de capacidade" #. type: Plain text #: ../src/cookbook/deployment/autoscaling.md msgid "Before enabling autoscaling, verify that:" -msgstr "" +msgstr "Antes de habilitar o autoscaling, verifique que:" #. type: Bullet: '- ' #: ../src/cookbook/deployment/autoscaling.md msgid "a request can be served correctly after the previous request went to another replica;" -msgstr "" +msgstr "uma requisição é atendida corretamente depois que a requisição anterior foi para outra réplica;" #. type: Bullet: '- ' #: ../src/cookbook/deployment/autoscaling.md msgid "login and flash messages work without sticky sessions;" -msgstr "" +msgstr "login e mensagens flash funcionam sem sticky sessions;" #. type: Bullet: '- ' #: ../src/cookbook/deployment/autoscaling.md msgid "uploaded files remain available after the handling instance is removed;" -msgstr "" +msgstr "arquivos enviados continuam disponíveis depois que a instância que os recebeu é removida;" #. type: Bullet: '- ' #: ../src/cookbook/deployment/autoscaling.md msgid "cache misses on one instance do not corrupt or hide data on another instance;" -msgstr "" +msgstr "cache misses em uma instância não corrompem nem escondem dados em outra instância;" #. type: Bullet: '- ' #: ../src/cookbook/deployment/autoscaling.md msgid "migrations are run by exactly one deployment step;" -msgstr "" +msgstr "as migrations são executadas por exatamente uma etapa do deploy;" #. type: Bullet: '- ' #: ../src/cookbook/deployment/autoscaling.md msgid "background workers and scheduled commands are not multiplied accidentally;" -msgstr "" +msgstr "workers em segundo plano e comandos agendados não são multiplicados por acidente;" #. type: Bullet: '- ' #: ../src/cookbook/deployment/autoscaling.md msgid "health checks are fast and do not overload the database;" -msgstr "" +msgstr "os health checks são rápidos e não sobrecarregam o banco de dados;" #. type: Bullet: '- ' #: ../src/cookbook/deployment/autoscaling.md msgid "logs and metrics identify the application version and instance;" -msgstr "" +msgstr "logs e métricas identificam a versão da aplicação e a instância;" #. type: Bullet: '- ' #: ../src/cookbook/deployment/autoscaling.md msgid "shutdown is graceful enough for your web server and queue worker timeouts." -msgstr "" +msgstr "o desligamento é gracioso o bastante para os timeouts do seu servidor web e dos workers de fila." diff --git a/_translations/po/pt-BR/cookbook_deployment_docker-swarm-caddy.md.po b/_translations/po/pt-BR/cookbook_deployment_docker-swarm-caddy.md.po index 532440e6..5e99a4a0 100644 --- a/_translations/po/pt-BR/cookbook_deployment_docker-swarm-caddy.md.po +++ b/_translations/po/pt-BR/cookbook_deployment_docker-swarm-caddy.md.po @@ -8,41 +8,35 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-09-25 14:35+0000\n" "PO-Revision-Date: 2026-09-25 14:35+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/cookbook/configuring-xdebug.md -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md -#: ../src/guide/views/asset.md +#: ../src/cookbook/configuring-xdebug.md ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md ../src/guide/views/asset.md #, no-wrap msgid "Troubleshooting" -msgstr "" +msgstr "Solução de problemas" #. type: Title ## -#: ../src/cookbook/deployment/angie-docker-proxy.md -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md -#: ../src/cookbook/preface.md +#: ../src/cookbook/deployment/angie-docker-proxy.md ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md ../src/cookbook/preface.md #, no-wrap msgid "Prerequisites" -msgstr "" +msgstr "Pré-requisitos" #. type: Title # #: ../src/cookbook/deployment/docker-swarm-caddy.md #, no-wrap msgid "Deploying Yii applications to Docker Swarm and Caddy" -msgstr "" +msgstr "Fazendo deploy de aplicações Yii no Docker Swarm com Caddy" #. type: Plain text #: ../src/cookbook/deployment/docker-swarm-caddy.md msgid "This guide walks you through deploying a Yii application to [Docker Swarm](https://docs.docker.com/engine/swarm/) starting from a blank server, using [Caddy](https://caddyserver.com/) as a reverse proxy and deploying from a container registry ([Forgejo](https://forgejo.org/) or [Gitea](https://about.gitea.com/))." -msgstr "" +msgstr "Este guia mostra como fazer o deploy de uma aplicação Yii no [Docker Swarm](https://docs.docker.com/engine/swarm/) a partir de um servidor vazio, usando o [Caddy](https://caddyserver.com/) como proxy reverso e fazendo o deploy a partir de um registro de containers ([Forgejo](https://forgejo.org/) ou [Gitea](https://about.gitea.com/))." #. type: Fenced code block (mermaid) #: ../src/cookbook/deployment/docker-swarm-caddy.md @@ -59,108 +53,104 @@ msgid "" " D\n" " end\n" msgstr "" +"graph LR\n" +" A[Internet] --> B[Proxy reverso: Caddy]\n" +" B --> C[app1.example.com]\n" +" B --> D[app2.example.com]\n" +" \n" +" subgraph Docker Swarm Cluster\n" +" B\n" +" C\n" +" D\n" +" end\n" #. type: Bullet: '- ' -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "A server with a fresh installation of a Linux distribution (Ubuntu 22.04 LTS or later recommended)" -msgstr "" +msgstr "Um servidor com uma distribuição Linux recém-instalada (recomendado Ubuntu 22.04 LTS ou mais recente)" #. type: Bullet: '- ' -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "A domain name pointing to your server's IP address" -msgstr "" +msgstr "Um nome de domínio apontando para o IP do seu servidor" #. type: Bullet: '- ' -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "SSH access to your server" -msgstr "" +msgstr "Acesso SSH ao seu servidor" #. type: Bullet: '- ' -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Basic knowledge of Docker and command-line tools" -msgstr "" +msgstr "Conhecimento básico de Docker e de ferramentas de linha de comando" #. type: Title ## -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Server preparation" -msgstr "" +msgstr "Preparando o servidor" #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Install Docker" -msgstr "" +msgstr "Instale o Docker" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "For installation instructions, see the [official Docker documentation](https://docs.docker.com/engine/install/ubuntu/)." -msgstr "" +msgstr "Para as instruções de instalação, veja a [documentação oficial do Docker](https://docs.docker.com/engine/install/ubuntu/)." #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Initialize Docker Swarm" -msgstr "" +msgstr "Inicialize o Docker Swarm" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Initialize your server as a Docker Swarm manager:" -msgstr "" +msgstr "Inicialize o seu servidor como manager do Docker Swarm:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "docker swarm init --advertise-addr \n" -msgstr "" +msgstr "docker swarm init --advertise-addr \n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Replace `` with your server's public IP address.\n" -msgstr "" +msgstr "Substitua `` pelo IP público do seu servidor.\n" #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Set up the reverse proxy network" -msgstr "" +msgstr "Configure a rede do proxy reverso" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Create a dedicated overlay network for reverse proxy to communicate with your services:" -msgstr "" +msgstr "Crie uma rede overlay dedicada para o proxy reverso se comunicar com os seus serviços:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "docker network create --driver=overlay reverse_proxy_public\n" -msgstr "" +msgstr "docker network create --driver=overlay reverse_proxy_public\n" #. type: Title ## #: ../src/cookbook/deployment/docker-swarm-caddy.md #, no-wrap msgid "Setting up Caddy as reverse proxy" -msgstr "" +msgstr "Configurando o Caddy como proxy reverso" #. type: Plain text #: ../src/cookbook/deployment/docker-swarm-caddy.md msgid "To deploy Caddy as reverse proxy create a file `caddy-stack.yml`:" -msgstr "" +msgstr "Para fazer o deploy do Caddy como proxy reverso, crie um arquivo `caddy-stack.yml`:" #. type: Fenced code block (yaml) #: ../src/cookbook/deployment/docker-swarm-caddy.md @@ -185,22 +175,40 @@ msgid "" " reverse_proxy_public:\n" " external: true\n" msgstr "" +"services:\n" +" caddy:\n" +" image: lucaslorentz/caddy-docker-proxy:ci-alpine\n" +" ports:\n" +" - \"80:80\"\n" +" - \"443:443\"\n" +" volumes:\n" +" - /var/run/docker.sock:/var/run/docker.sock\n" +" - caddy_data:/data\n" +" networks:\n" +" - reverse_proxy_public\n" +"\n" +"volumes:\n" +" caddy_data:\n" +"\n" +"networks:\n" +" reverse_proxy_public:\n" +" external: true\n" #. type: Plain text #: ../src/cookbook/deployment/docker-swarm-caddy.md msgid "Deploy Caddy:" -msgstr "" +msgstr "Faça o deploy do Caddy:" #. type: Fenced code block (bash) #: ../src/cookbook/deployment/docker-swarm-caddy.md #, no-wrap msgid "docker stack deploy -c caddy-stack.yml caddy\n" -msgstr "" +msgstr "docker stack deploy -c caddy-stack.yml caddy\n" #. type: Plain text #: ../src/cookbook/deployment/docker-swarm-caddy.md msgid "Caddy automatically discovers services with Caddy labels and sets up HTTPS using Let's Encrypt. Yii3 application templates are using Caddy labels by default:" -msgstr "" +msgstr "O Caddy descobre automaticamente os serviços com labels do Caddy e configura HTTPS usando o Let's Encrypt. Os templates de aplicação do Yii3 usam labels do Caddy por padrão:" #. type: Fenced code block (yaml) #: ../src/cookbook/deployment/docker-swarm-caddy.md @@ -211,6 +219,10 @@ msgid "" " - caddy: ${PROD_HOST:-app.example.com}\n" " - caddy.reverse_proxy: \"{{upstreams 80}}\"\n" msgstr "" +"deploy:\n" +" labels:\n" +" - caddy: ${PROD_HOST:-app.example.com}\n" +" - caddy.reverse_proxy: \"{{upstreams 80}}\"\n" #. type: Plain text #: ../src/cookbook/deployment/docker-swarm-caddy.md @@ -220,32 +232,31 @@ msgid "" "> Make sure your domain DNS records are configured and pointing to your server before deploying services with\n" "> Caddy labels, as Let's Encrypt requires domain validation.\n" msgstr "" +"> [!IMPORTANT]\n" +"> Garanta que os registros DNS do seu domínio estejam configurados e apontando para o seu servidor antes de fazer o deploy de serviços com\n" +"> labels do Caddy, porque o Let's Encrypt exige a validação do domínio.\n" #. type: Title ## -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Setting up a container registry" -msgstr "" +msgstr "Configurando um registro de containers" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "You need a container registry to store your Docker images. Choose one of the following options." -msgstr "" +msgstr "Você precisa de um registro de containers para guardar as suas imagens Docker. Escolha uma das opções a seguir." #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Option 1: Using Forgejo" -msgstr "" +msgstr "Opção 1: usando o Forgejo" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "To deploy Forgejo create a file `forgejo-stack.yml`:" -msgstr "" +msgstr "Para fazer o deploy do Forgejo, crie um arquivo `forgejo-stack.yml`:" #. type: Fenced code block (yaml) #: ../src/cookbook/deployment/docker-swarm-caddy.md @@ -272,43 +283,58 @@ msgid "" " reverse_proxy_public:\n" " external: true\n" msgstr "" +"services:\n" +" forgejo:\n" +" image: codeberg.org/forgejo/forgejo:1.21\n" +" ports:\n" +" - \"3000:3000\"\n" +" volumes:\n" +" - forgejo_data:/data\n" +" networks:\n" +" - reverse_proxy_public\n" +" deploy:\n" +" labels:\n" +" - \"caddy=git.example.com\"\n" +" - \"caddy.reverse_proxy={{upstreams 3000}}\"\n" +"\n" +"volumes:\n" +" forgejo_data:\n" +"\n" +"networks:\n" +" reverse_proxy_public:\n" +" external: true\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Deploy Forgejo:" -msgstr "" +msgstr "Faça o deploy do Forgejo:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "docker stack deploy -c forgejo-stack.yml forgejo\n" -msgstr "" +msgstr "docker stack deploy -c forgejo-stack.yml forgejo\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Replace `git.example.com` with your desired subdomain." -msgstr "" +msgstr "Substitua `git.example.com` pelo subdomínio desejado." #. type: Plain text #: ../src/cookbook/deployment/docker-swarm-caddy.md msgid "After deployment, access Forgejo at `https://git.example.com` and complete the initial setup. Make sure to enable the container registry in the settings." -msgstr "" +msgstr "Depois do deploy, acesse o Forgejo em `https://git.example.com` e conclua a configuração inicial. Não esqueça de habilitar o registro de containers nas configurações." #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Option 2: Using Gitea" -msgstr "" +msgstr "Opção 2: usando o Gitea" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "To deploy Gitea create a file `gitea-stack.yml`:" -msgstr "" +msgstr "Para fazer o deploy do Gitea, crie um arquivo `gitea-stack.yml`:" #. type: Fenced code block (yaml) #: ../src/cookbook/deployment/docker-swarm-caddy.md @@ -335,49 +361,62 @@ msgid "" " reverse_proxy_public:\n" " external: true\n" msgstr "" +"services:\n" +" gitea:\n" +" image: gitea/gitea:latest\n" +" ports:\n" +" - \"3000:3000\"\n" +" volumes:\n" +" - gitea_data:/data\n" +" networks:\n" +" - reverse_proxy_public\n" +" deploy:\n" +" labels:\n" +" - \"caddy=git.example.com\"\n" +" - \"caddy.reverse_proxy={{upstreams 3000}}\"\n" +"\n" +"volumes:\n" +" gitea_data:\n" +"\n" +"networks:\n" +" reverse_proxy_public:\n" +" external: true\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Deploy Gitea:" -msgstr "" +msgstr "Faça o deploy do Gitea:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "docker stack deploy -c gitea-stack.yml gitea\n" -msgstr "" +msgstr "docker stack deploy -c gitea-stack.yml gitea\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "After deployment, access Gitea at `https://git.example.com` and complete the initial setup. Make sure to enable the container registry in the settings." -msgstr "" +msgstr "Depois do deploy, acesse o Gitea em `https://git.example.com` e conclua a configuração inicial. Não esqueça de habilitar o registro de containers nas configurações." #. type: Title ## -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Configuring your Yii application" -msgstr "" +msgstr "Configurando a sua aplicação Yii" #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Update the Makefile configuration" -msgstr "" +msgstr "Atualize a configuração do Makefile" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "The [Yii application template](https://github.com/yiisoft/app) includes a Makefile with deployment commands. Update the `docker/.env` file in your project:" -msgstr "" +msgstr "O [template de aplicação do Yii](https://github.com/yiisoft/app) inclui um Makefile com comandos de deploy. Atualize o arquivo `docker/.env` do seu projeto:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "" "STACK_NAME=myapp\n" @@ -392,29 +431,36 @@ msgid "" "IMAGE=git.example.com/username/myapp\n" "IMAGE_TAG=latest\n" msgstr "" +"STACK_NAME=myapp\n" +"\n" +"#\n" +"# Produção\n" +"#\n" +"\n" +"PROD_HOST=app.example.com\n" +"PROD_SSH=\"ssh://user@your-server-ip\"\n" +"\n" +"IMAGE=git.example.com/username/myapp\n" +"IMAGE_TAG=latest\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Replace the values: - `STACK_NAME`: A unique name for your application stack - `PROD_HOST`: The domain name where your app will be accessible - `PROD_SSH`: SSH connection string to your server (format: `ssh://user@host`) - `IMAGE`: Full path to your container image in the registry - `IMAGE_TAG`: Image tag, typically `latest` or a version number" -msgstr "" +msgstr "Substitua os valores: - `STACK_NAME`: um nome único para a stack da sua aplicação - `PROD_HOST`: o nome de domínio em que a aplicação vai ficar acessível - `PROD_SSH`: a string de conexão SSH com o seu servidor (formato: `ssh://user@host`) - `IMAGE`: o caminho completo da imagem do container no registro - `IMAGE_TAG`: a tag da imagem, normalmente `latest` ou um número de versão" #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Configure the production environment" -msgstr "" +msgstr "Configure o ambiente de produção" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Update `docker/prod/.env` with your production environment variables:" -msgstr "" +msgstr "Atualize o `docker/prod/.env` com as variáveis de ambiente de produção:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "" "APP_ENV=prod\n" @@ -429,27 +475,38 @@ msgid "" "\n" "# Add other environment-specific variables\n" msgstr "" +"APP_ENV=prod\n" +"YII_DEBUG=false\n" +"YII_ENV=prod\n" +"\n" +"# Configuração do banco de dados\n" +"DB_HOST=db\n" +"DB_NAME=myapp\n" +"DB_USER=myapp\n" +"DB_PASSWORD=secure_password_here\n" +"\n" +"# Adicione outras variáveis específicas do ambiente\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "" "> [!WARNING]\n" "> Never commit sensitive credentials to version control. Use `docker/prod/override.env` for sensitive values and add it to `.gitignore`.\n" msgstr "" +"> [!WARNING]\n" +"> Nunca faça commit de credenciais sensíveis no controle de versão. Use `docker/prod/override.env` para valores sensíveis e adicione-o ao `.gitignore`.\n" #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Review the production Docker Compose configuration" -msgstr "" +msgstr "Revise a configuração do Docker Compose de produção" #. type: Plain text #: ../src/cookbook/deployment/docker-swarm-caddy.md msgid "The default `docker/prod/compose.yml` includes:" -msgstr "" +msgstr "O `docker/prod/compose.yml` padrão inclui:" #. type: Fenced code block (yaml) #: ../src/cookbook/deployment/docker-swarm-caddy.md @@ -490,10 +547,43 @@ msgid "" " caddy: ${PROD_HOST:-app.example.com}\n" " caddy.reverse_proxy: \"{{upstreams 80}}\"\n" msgstr "" +"services:\n" +" app:\n" +" image: ${IMAGE}:${IMAGE_TAG}\n" +" networks:\n" +" - reverse_proxy_public\n" +" volumes:\n" +" - runtime:/app/runtime\n" +" - caddy_data:/data\n" +" - caddy_config:/config\n" +" env_file:\n" +" - path: ./prod/.env\n" +" - path: ./prod/override.env\n" +" required: false\\\n" +" environment:\n" +" CADDY_EXTRA_CONFIG: 'auto_https off'\n" +" deploy:\n" +" replicas: 2\n" +" update_config:\n" +" delay: 10s\n" +" parallelism: 1\n" +" order: start-first\n" +" failure_action: rollback\n" +" monitor: 10s\n" +" rollback_config:\n" +" parallelism: 0\n" +" order: stop-first\n" +" restart_policy:\n" +" condition: on-failure\n" +" delay: 5s\n" +" max_attempts: 3\n" +" window: 120s\n" +" labels:\n" +" caddy: ${PROD_HOST:-app.example.com}\n" +" caddy.reverse_proxy: \"{{upstreams 80}}\"\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "" "This configuration:\n" @@ -503,16 +593,20 @@ msgid "" "- Disables obtaining of HTTPs certificates on the container itself\n" " since proxy communicates with the container via HTTP. That is `auto_https off`.\n" msgstr "" +"Essa configuração:\n" +"- Roda 2 réplicas para alta disponibilidade\n" +"- Usa uma estratégia de rolling update com rollback automático em caso de falha\n" +"- Configura `labels` para HTTPS automático no proxy reverso\n" +"- Desabilita a obtenção de certificados HTTPS no próprio container,\n" +" já que o proxy se comunica com o container via HTTP. Isso é o `auto_https off`.\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "If you need a database, add it to the stack:" -msgstr "" +msgstr "Se você precisa de um banco de dados, adicione-o à stack:" #. type: Fenced code block (yaml) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "" "services:\n" @@ -545,148 +639,155 @@ msgid "" " db_password:\n" " external: true\n" msgstr "" +"services:\n" +" app:\n" +" # ... configuração existente ...\n" +" \n" +" db:\n" +" image: postgres:18-alpine\n" +" environment:\n" +" POSTGRES_DB: myapp\n" +" POSTGRES_USER: myapp\n" +" POSTGRES_PASSWORD_FILE: /run/secrets/db_password\n" +" POSTGRES_INITDB_ARGS: \"--locale-provider=icu --icu-locale=und --encoding=UTF8\"\n" +" volumes:\n" +" - db_data:/var/lib/postgresql\n" +" networks:\n" +" - reverse_proxy_public\n" +" deploy:\n" +" placement:\n" +" constraints:\n" +" - node.role == manager\n" +" secrets:\n" +" - db_password\n" +"\n" +"volumes:\n" +" runtime:\n" +" db_data:\n" +"\n" +"secrets:\n" +" db_password:\n" +" external: true\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Create the database password secret on the server:" -msgstr "" +msgstr "Crie o secret com a senha do banco de dados no servidor:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "echo \"your_secure_password\" | docker secret create db_password -\n" -msgstr "" +msgstr "echo \"your_secure_password\" | docker secret create db_password -\n" #. type: Title ## -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Building and pushing the image" -msgstr "" +msgstr "Construindo e enviando a imagem" #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Set up Docker login on your local machine" -msgstr "" +msgstr "Configure o login do Docker na sua máquina local" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Configure Docker to authenticate with your container registry:" -msgstr "" +msgstr "Configure o Docker para se autenticar no seu registro de containers:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "docker login git.example.com\n" -msgstr "" +msgstr "docker login git.example.com\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Enter your username and password when prompted." -msgstr "" +msgstr "Informe o seu usuário e a sua senha quando solicitado." #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Build the production image" -msgstr "" +msgstr "Construa a imagem de produção" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Use the Makefile to build your production image:" -msgstr "" +msgstr "Use o Makefile para construir a imagem de produção:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "make prod-build\n" -msgstr "" +msgstr "make prod-build\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "This runs the command defined in the Makefile:" -msgstr "" +msgstr "Isso executa o comando definido no Makefile:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "docker build --file docker/Dockerfile --target prod --pull -t ${IMAGE}:${IMAGE_TAG} .\n" -msgstr "" +msgstr "docker build --file docker/Dockerfile --target prod --pull -t ${IMAGE}:${IMAGE_TAG} .\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "The Dockerfile uses a multi-stage build: 1. Installs Composer dependencies in a builder stage 2. Creates a minimal production image with only the necessary files 3. Runs as a non-root user (`www-data`)" -msgstr "" +msgstr "O Dockerfile usa um build multi-stage: 1. Instala as dependências do Composer em um estágio de build 2. Cria uma imagem de produção mínima, só com os arquivos necessários 3. Roda como um usuário não root (`www-data`)" #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Push the image to the registry" -msgstr "" +msgstr "Envie a imagem para o registro" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Push your built image to the container registry:" -msgstr "" +msgstr "Envie a imagem construída para o registro de containers:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "make prod-push\n" -msgstr "" +msgstr "make prod-push\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "This executes:" -msgstr "" +msgstr "Isso executa:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "docker push ${IMAGE}:${IMAGE_TAG}\n" -msgstr "" +msgstr "docker push ${IMAGE}:${IMAGE_TAG}\n" #. type: Title ## -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Deploying to Docker Swarm" -msgstr "" +msgstr "Fazendo deploy no Docker Swarm" #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Configure SSH access" -msgstr "" +msgstr "Configure o acesso SSH" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Set up SSH key-based authentication to your server:" -msgstr "" +msgstr "Configure a autenticação por chave SSH no seu servidor:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "" "# Generate SSH key (if you don't have one)\n" @@ -703,125 +804,122 @@ msgid "" " IdentityFile ~/.ssh/id_ed25519\n" "EOF\n" msgstr "" +"# Gera uma chave SSH (se você ainda não tiver uma)\n" +"ssh-keygen -t ed25519 -C \"your_email@example.com\"\n" +"\n" +"# Copia a chave para o seu servidor\n" +"ssh-copy-id user@your-server-ip\n" +"\n" +"# Adiciona o host SSH à sua configuração SSH (~/.ssh/config)\n" +"cat >> ~/.ssh/config << EOF\n" +"Host docker-web\n" +" HostName your-server-ip\n" +" User user\n" +" IdentityFile ~/.ssh/id_ed25519\n" +"EOF\n" #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Set up Docker context" -msgstr "" +msgstr "Configure o contexto do Docker" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Create a Docker context for remote deployment:" -msgstr "" +msgstr "Crie um contexto do Docker para o deploy remoto:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "docker context create swarm-prod --docker \"host=ssh://docker-web\"\n" -msgstr "" +msgstr "docker context create swarm-prod --docker \"host=ssh://docker-web\"\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Alternatively, configure the `DOCKER_HOST` environment variable:" -msgstr "" +msgstr "Como alternativa, configure a variável de ambiente `DOCKER_HOST`:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "export DOCKER_HOST=ssh://docker-web\n" -msgstr "" +msgstr "export DOCKER_HOST=ssh://docker-web\n" #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Deploy the application" -msgstr "" +msgstr "Faça o deploy da aplicação" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Deploy your application stack to Docker Swarm:" -msgstr "" +msgstr "Faça o deploy da stack da sua aplicação no Docker Swarm:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "make prod-deploy\n" -msgstr "" +msgstr "make prod-deploy\n" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "docker -H ${PROD_SSH} stack deploy --prune --detach=false --with-registry-auth -c docker/compose.yml -c docker/prod/compose.yml ${STACK_NAME}\n" -msgstr "" +msgstr "docker -H ${PROD_SSH} stack deploy --prune --detach=false --with-registry-auth -c docker/compose.yml -c docker/prod/compose.yml ${STACK_NAME}\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "The `--with-registry-auth` flag ensures the Swarm nodes can pull images from your private registry." -msgstr "" +msgstr "A flag `--with-registry-auth` garante que os nós do Swarm consigam baixar imagens do seu registro privado." #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Verify the deployment" -msgstr "" +msgstr "Verifique o deploy" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Check the status of your services:" -msgstr "" +msgstr "Verifique o status dos seus serviços:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "" "docker -H ssh://docker-web service ls\n" "docker -H ssh://docker-web service ps ${STACK_NAME}_app\n" msgstr "" +"docker -H ssh://docker-web service ls\n" +"docker -H ssh://docker-web service ps ${STACK_NAME}_app\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "View logs:" -msgstr "" +msgstr "Veja os logs:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "docker -H ssh://docker-web service logs ${STACK_NAME}_app\n" -msgstr "" +msgstr "docker -H ssh://docker-web service logs ${STACK_NAME}_app\n" #. type: Title ## -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Monitoring and maintenance" -msgstr "" +msgstr "Monitoramento e manutenção" #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "View service logs" -msgstr "" +msgstr "Veja os logs do serviço" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "" "# View all logs\n" @@ -833,49 +931,50 @@ msgid "" "# View logs with timestamps\n" "docker -H ssh://docker-web service logs -t ${STACK_NAME}_app\n" msgstr "" +"# Mostra todos os logs\n" +"docker -H ssh://docker-web service logs -f ${STACK_NAME}_app\n" +"\n" +"# Mostra as últimas 100 linhas de log\n" +"docker -H ssh://docker-web service logs --tail 100 ${STACK_NAME}_app\n" +"\n" +"# Mostra os logs com timestamps\n" +"docker -H ssh://docker-web service logs -t ${STACK_NAME}_app\n" #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Scale the application" -msgstr "" +msgstr "Escale a aplicação" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Adjust the number of replicas:" -msgstr "" +msgstr "Ajuste o número de réplicas:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "docker -H ssh://docker-web service scale ${STACK_NAME}_app=3\n" -msgstr "" +msgstr "docker -H ssh://docker-web service scale ${STACK_NAME}_app=3\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Or update the `replicas` value in `docker/prod/compose.yml` and redeploy." -msgstr "" +msgstr "Ou atualize o valor de `replicas` em `docker/prod/compose.yml` e faça o deploy de novo." #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Resource limits" -msgstr "" +msgstr "Limites de recursos" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Add resource limits to prevent containers from consuming all server resources. Update `docker/prod/compose.yml`:" -msgstr "" +msgstr "Adicione limites de recursos para evitar que os containers consumam todos os recursos do servidor. Atualize o `docker/prod/compose.yml`:" #. type: Fenced code block (yaml) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "" "services:\n" @@ -890,47 +989,54 @@ msgid "" " cpus: '0.25'\n" " memory: 256M\n" msgstr "" +"services:\n" +" app:\n" +" # ... configuração existente ...\n" +" deploy:\n" +" resources:\n" +" limits:\n" +" cpus: '0.5'\n" +" memory: 512M\n" +" reservations:\n" +" cpus: '0.25'\n" +" memory: 256M\n" #. type: Title ## -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md -#: ../src/cookbook/disabling-csrf-protection.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md ../src/cookbook/disabling-csrf-protection.md #, no-wrap msgid "Security considerations" -msgstr "" +msgstr "Considerações de segurança" #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Use Docker secrets for sensitive data" -msgstr "" +msgstr "Use Docker secrets para dados sensíveis" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Instead of environment variables, use Docker secrets for sensitive information:" -msgstr "" +msgstr "Em vez de variáveis de ambiente, use Docker secrets para informações sensíveis:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "" "# Create secrets\n" "echo \"database_password\" | docker secret create db_password -\n" "echo \"api_key\" | docker secret create api_key -\n" msgstr "" +"# Cria os secrets\n" +"echo \"database_password\" | docker secret create db_password -\n" +"echo \"api_key\" | docker secret create api_key -\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Update `docker/prod/compose.yml`:" -msgstr "" +msgstr "Atualize o `docker/prod/compose.yml`:" #. type: Fenced code block (yaml) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "" "services:\n" @@ -945,29 +1051,36 @@ msgid "" " api_key:\n" " external: true\n" msgstr "" +"services:\n" +" app:\n" +" secrets:\n" +" - db_password\n" +" - api_key\n" +"\n" +"secrets:\n" +" db_password:\n" +" external: true\n" +" api_key:\n" +" external: true\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Access secrets in your application at `/run/secrets/secret_name`." -msgstr "" +msgstr "Acesse os secrets na sua aplicação em `/run/secrets/secret_name`." #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Set up a firewall" -msgstr "" +msgstr "Configure um firewall" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Configure UFW (Uncomplicated Firewall) on your server:" -msgstr "" +msgstr "Configure o UFW (Uncomplicated Firewall) no seu servidor:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "" "# Allow SSH\n" @@ -986,23 +1099,35 @@ msgid "" "# Enable the firewall\n" "sudo ufw enable\n" msgstr "" +"# Libera SSH\n" +"sudo ufw allow 22/tcp\n" +"\n" +"# Libera HTTP e HTTPS\n" +"sudo ufw allow 80/tcp\n" +"sudo ufw allow 443/tcp\n" +"\n" +"# Libera as portas do Docker Swarm (se você pretende adicionar mais nós)\n" +"sudo ufw allow 2377/tcp\n" +"sudo ufw allow 7946/tcp\n" +"sudo ufw allow 7946/udp\n" +"sudo ufw allow 4789/udp\n" +"\n" +"# Habilita o firewall\n" +"sudo ufw enable\n" #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Keep the system updated" -msgstr "" +msgstr "Mantenha o sistema atualizado" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Regularly update your server and Docker:" -msgstr "" +msgstr "Atualize regularmente o seu servidor e o Docker:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "" "# Update system packages\n" @@ -1011,63 +1136,62 @@ msgid "" "# Update Docker images\n" "docker -H ssh://docker-web service update --image ${IMAGE}:${IMAGE_TAG} ${STACK_NAME}_app\n" msgstr "" +"# Atualiza os pacotes do sistema\n" +"sudo apt-get update && sudo apt-get upgrade -y\n" +"\n" +"# Atualiza as imagens Docker\n" +"docker -H ssh://docker-web service update --image ${IMAGE}:${IMAGE_TAG} ${STACK_NAME}_app\n" #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Service won't start" -msgstr "" +msgstr "O serviço não sobe" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Check service events and logs:" -msgstr "" +msgstr "Verifique os eventos e os logs do serviço:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "" "docker -H ssh://docker-web service ps ${STACK_NAME}_app --no-trunc\n" "docker -H ssh://docker-web service logs ${STACK_NAME}_app\n" msgstr "" +"docker -H ssh://docker-web service ps ${STACK_NAME}_app --no-trunc\n" +"docker -H ssh://docker-web service logs ${STACK_NAME}_app\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Common issues: - **Image pull errors**: Verify registry authentication with `docker -H ssh://docker-web login` - **Port conflicts**: Ensure no other services are using ports 80/443 - **Resource constraints**: Check available resources with `docker -H ssh://docker-web node ls`" -msgstr "" +msgstr "Problemas comuns: - **Erros ao baixar a imagem**: verifique a autenticação no registro com `docker -H ssh://docker-web login` - **Conflitos de porta**: garanta que nenhum outro serviço esteja usando as portas 80/443 - **Limitação de recursos**: verifique os recursos disponíveis com `docker -H ssh://docker-web node ls`" #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "SSL certificate issues" -msgstr "" +msgstr "Problemas com certificados SSL" #. type: Plain text #: ../src/cookbook/deployment/docker-swarm-caddy.md msgid "If Caddy can't obtain certificates: - Verify DNS is pointing to your server - Check that ports 80 and 443 are accessible from the internet - Ensure the email in the Let's Encrypt configuration is valid - Check logs: `docker -H ssh://docker-web service logs caddy`" -msgstr "" +msgstr "Se o Caddy não consegue obter os certificados: - Verifique se o DNS aponta para o seu servidor - Verifique se as portas 80 e 443 estão acessíveis pela internet - Garanta que o e-mail na configuração do Let's Encrypt é válido - Verifique os logs: `docker -H ssh://docker-web service logs caddy`" #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Container registry connection issues" -msgstr "" +msgstr "Problemas de conexão com o registro de containers" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Test registry connectivity:" -msgstr "" +msgstr "Teste a conectividade com o registro:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "" "# From your local machine\n" @@ -1076,11 +1200,14 @@ msgid "" "# From the server\n" "docker -H ssh://docker-web pull git.example.com/username/myapp:latest\n" msgstr "" +"# Na sua máquina local\n" +"docker pull git.example.com/username/myapp:latest\n" +"\n" +"# No servidor\n" +"docker -H ssh://docker-web pull git.example.com/username/myapp:latest\n" #. type: Title ## -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md -#: ../src/guide/start/forms.md ../src/guide/start/hello.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md ../src/guide/start/forms.md ../src/guide/start/hello.md #, no-wrap msgid "Summary" msgstr "Resumo" @@ -1088,15 +1215,14 @@ msgstr "Resumo" #. type: Plain text #: ../src/cookbook/deployment/docker-swarm-caddy.md msgid "You've successfully deployed a Yii application to Docker Swarm with: - A container registry (Forgejo or Gitea) - Automatic HTTPS via Caddy - Zero-downtime deployments with rolling updates - High availability with multiple replicas" -msgstr "" +msgstr "Você fez o deploy de uma aplicação Yii no Docker Swarm com: - Um registro de containers (Forgejo ou Gitea) - HTTPS automático via Caddy - Deploys sem downtime com rolling updates - Alta disponibilidade com várias réplicas" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "The Makefile commands simplify the deployment workflow: - `make prod-build` - Build the production image - `make prod-push` - Push to the registry - `make prod-deploy` - Deploy to Docker Swarm" -msgstr "" +msgstr "Os comandos do Makefile simplificam o fluxo de deploy: - `make prod-build` - Constrói a imagem de produção - `make prod-push` - Envia para o registro - `make prod-deploy` - Faz o deploy no Docker Swarm" #. type: Plain text #: ../src/cookbook/deployment/docker-swarm-caddy.md msgid "For more information, see: - [Yii Application Template](https://github.com/yiisoft/app) - [Docker Swarm Documentation](https://docs.docker.com/engine/swarm/) - [Caddy Docker Proxy](https://github.com/lucaslorentz/caddy-docker-proxy)" -msgstr "" +msgstr "Para mais informações, veja: - [Template de aplicação do Yii](https://github.com/yiisoft/app) - [Documentação do Docker Swarm](https://docs.docker.com/engine/swarm/) - [Caddy Docker Proxy](https://github.com/lucaslorentz/caddy-docker-proxy)" diff --git a/_translations/po/pt-BR/cookbook_deployment_docker-swarm-traefik.md.po b/_translations/po/pt-BR/cookbook_deployment_docker-swarm-traefik.md.po index 167d424d..efc3c0bc 100644 --- a/_translations/po/pt-BR/cookbook_deployment_docker-swarm-traefik.md.po +++ b/_translations/po/pt-BR/cookbook_deployment_docker-swarm-traefik.md.po @@ -8,221 +8,186 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-05-07 14:37+0000\n" "PO-Revision-Date: 2026-05-07 14:37+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/cookbook/configuring-xdebug.md -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md -#: ../src/guide/views/asset.md +#: ../src/cookbook/configuring-xdebug.md ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md ../src/guide/views/asset.md #, no-wrap msgid "Troubleshooting" -msgstr "" +msgstr "Solução de problemas" #. type: Title ## -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md -#: ../src/cookbook/preface.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md ../src/cookbook/preface.md #, no-wrap msgid "Prerequisites" -msgstr "" +msgstr "Pré-requisitos" #. type: Bullet: '- ' -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "A server with a fresh installation of a Linux distribution (Ubuntu 22.04 LTS or later recommended)" -msgstr "" +msgstr "Um servidor com uma distribuição Linux recém-instalada (recomendado Ubuntu 22.04 LTS ou mais recente)" #. type: Bullet: '- ' -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "A domain name pointing to your server's IP address" -msgstr "" +msgstr "Um nome de domínio apontando para o IP do seu servidor" #. type: Bullet: '- ' -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "SSH access to your server" -msgstr "" +msgstr "Acesso SSH ao seu servidor" #. type: Bullet: '- ' -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Basic knowledge of Docker and command-line tools" -msgstr "" +msgstr "Conhecimento básico de Docker e de ferramentas de linha de comando" #. type: Title ## -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Server preparation" -msgstr "" +msgstr "Preparando o servidor" #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Install Docker" -msgstr "" +msgstr "Instale o Docker" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "For installation instructions, see the [official Docker documentation](https://docs.docker.com/engine/install/ubuntu/)." -msgstr "" +msgstr "Para as instruções de instalação, veja a [documentação oficial do Docker](https://docs.docker.com/engine/install/ubuntu/)." #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Initialize Docker Swarm" -msgstr "" +msgstr "Inicialize o Docker Swarm" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Initialize your server as a Docker Swarm manager:" -msgstr "" +msgstr "Inicialize o seu servidor como manager do Docker Swarm:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "docker swarm init --advertise-addr \n" -msgstr "" +msgstr "docker swarm init --advertise-addr \n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Replace `` with your server's public IP address.\n" -msgstr "" +msgstr "Substitua `` pelo IP público do seu servidor.\n" #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Set up the reverse proxy network" -msgstr "" +msgstr "Configure a rede do proxy reverso" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Create a dedicated overlay network for reverse proxy to communicate with your services:" -msgstr "" +msgstr "Crie uma rede overlay dedicada para o proxy reverso se comunicar com os seus serviços:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "docker network create --driver=overlay reverse_proxy_public\n" -msgstr "" +msgstr "docker network create --driver=overlay reverse_proxy_public\n" #. type: Title ## -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Setting up a container registry" -msgstr "" +msgstr "Configurando um registro de containers" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "You need a container registry to store your Docker images. Choose one of the following options." -msgstr "" +msgstr "Você precisa de um registro de containers para guardar as suas imagens Docker. Escolha uma das opções a seguir." #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Option 1: Using Forgejo" -msgstr "" +msgstr "Opção 1: usando o Forgejo" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "To deploy Forgejo create a file `forgejo-stack.yml`:" -msgstr "" +msgstr "Para fazer o deploy do Forgejo, crie um arquivo `forgejo-stack.yml`:" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Deploy Forgejo:" -msgstr "" +msgstr "Faça o deploy do Forgejo:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "docker stack deploy -c forgejo-stack.yml forgejo\n" -msgstr "" +msgstr "docker stack deploy -c forgejo-stack.yml forgejo\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Replace `git.example.com` with your desired subdomain." -msgstr "" +msgstr "Substitua `git.example.com` pelo subdomínio desejado." #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Option 2: Using Gitea" -msgstr "" +msgstr "Opção 2: usando o Gitea" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "To deploy Gitea create a file `gitea-stack.yml`:" -msgstr "" +msgstr "Para fazer o deploy do Gitea, crie um arquivo `gitea-stack.yml`:" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Deploy Gitea:" -msgstr "" +msgstr "Faça o deploy do Gitea:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "docker stack deploy -c gitea-stack.yml gitea\n" -msgstr "" +msgstr "docker stack deploy -c gitea-stack.yml gitea\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "After deployment, access Gitea at `https://git.example.com` and complete the initial setup. Make sure to enable the container registry in the settings." -msgstr "" +msgstr "Depois do deploy, acesse o Gitea em `https://git.example.com` e conclua a configuração inicial. Não esqueça de habilitar o registro de containers nas configurações." #. type: Title ## -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Configuring your Yii application" -msgstr "" +msgstr "Configurando a sua aplicação Yii" #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Update the Makefile configuration" -msgstr "" +msgstr "Atualize a configuração do Makefile" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "The [Yii application template](https://github.com/yiisoft/app) includes a Makefile with deployment commands. Update the `docker/.env` file in your project:" -msgstr "" +msgstr "O [template de aplicação do Yii](https://github.com/yiisoft/app) inclui um Makefile com comandos de deploy. Atualize o arquivo `docker/.env` do seu projeto:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "" "STACK_NAME=myapp\n" @@ -237,29 +202,36 @@ msgid "" "IMAGE=git.example.com/username/myapp\n" "IMAGE_TAG=latest\n" msgstr "" +"STACK_NAME=myapp\n" +"\n" +"#\n" +"# Produção\n" +"#\n" +"\n" +"PROD_HOST=app.example.com\n" +"PROD_SSH=\"ssh://user@your-server-ip\"\n" +"\n" +"IMAGE=git.example.com/username/myapp\n" +"IMAGE_TAG=latest\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Replace the values: - `STACK_NAME`: A unique name for your application stack - `PROD_HOST`: The domain name where your app will be accessible - `PROD_SSH`: SSH connection string to your server (format: `ssh://user@host`) - `IMAGE`: Full path to your container image in the registry - `IMAGE_TAG`: Image tag, typically `latest` or a version number" -msgstr "" +msgstr "Substitua os valores: - `STACK_NAME`: um nome único para a stack da sua aplicação - `PROD_HOST`: o nome de domínio em que a aplicação vai ficar acessível - `PROD_SSH`: a string de conexão SSH com o seu servidor (formato: `ssh://user@host`) - `IMAGE`: o caminho completo da imagem do container no registro - `IMAGE_TAG`: a tag da imagem, normalmente `latest` ou um número de versão" #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Configure the production environment" -msgstr "" +msgstr "Configure o ambiente de produção" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Update `docker/prod/.env` with your production environment variables:" -msgstr "" +msgstr "Atualize o `docker/prod/.env` com as variáveis de ambiente de produção:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "" "APP_ENV=prod\n" @@ -274,26 +246,36 @@ msgid "" "\n" "# Add other environment-specific variables\n" msgstr "" +"APP_ENV=prod\n" +"YII_DEBUG=false\n" +"YII_ENV=prod\n" +"\n" +"# Configuração do banco de dados\n" +"DB_HOST=db\n" +"DB_NAME=myapp\n" +"DB_USER=myapp\n" +"DB_PASSWORD=secure_password_here\n" +"\n" +"# Adicione outras variáveis específicas do ambiente\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "" "> [!WARNING]\n" "> Never commit sensitive credentials to version control. Use `docker/prod/override.env` for sensitive values and add it to `.gitignore`.\n" msgstr "" +"> [!WARNING]\n" +"> Nunca faça commit de credenciais sensíveis no controle de versão. Use `docker/prod/override.env` para valores sensíveis e adicione-o ao `.gitignore`.\n" #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Review the production Docker Compose configuration" -msgstr "" +msgstr "Revise a configuração do Docker Compose de produção" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "" "This configuration:\n" @@ -303,16 +285,20 @@ msgid "" "- Disables obtaining of HTTPs certificates on the container itself\n" " since proxy communicates with the container via HTTP. That is `auto_https off`.\n" msgstr "" +"Essa configuração:\n" +"- Roda 2 réplicas para alta disponibilidade\n" +"- Usa uma estratégia de rolling update com rollback automático em caso de falha\n" +"- Configura `labels` para HTTPS automático no proxy reverso\n" +"- Desabilita a obtenção de certificados HTTPS no próprio container,\n" +" já que o proxy se comunica com o container via HTTP. Isso é o `auto_https off`.\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "If you need a database, add it to the stack:" -msgstr "" +msgstr "Se você precisa de um banco de dados, adicione-o à stack:" #. type: Fenced code block (yaml) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "" "services:\n" @@ -345,148 +331,155 @@ msgid "" " db_password:\n" " external: true\n" msgstr "" +"services:\n" +" app:\n" +" # ... configuração existente ...\n" +" \n" +" db:\n" +" image: postgres:18-alpine\n" +" environment:\n" +" POSTGRES_DB: myapp\n" +" POSTGRES_USER: myapp\n" +" POSTGRES_PASSWORD_FILE: /run/secrets/db_password\n" +" POSTGRES_INITDB_ARGS: \"--locale-provider=icu --icu-locale=und --encoding=UTF8\"\n" +" volumes:\n" +" - db_data:/var/lib/postgresql\n" +" networks:\n" +" - reverse_proxy_public\n" +" deploy:\n" +" placement:\n" +" constraints:\n" +" - node.role == manager\n" +" secrets:\n" +" - db_password\n" +"\n" +"volumes:\n" +" runtime:\n" +" db_data:\n" +"\n" +"secrets:\n" +" db_password:\n" +" external: true\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Create the database password secret on the server:" -msgstr "" +msgstr "Crie o secret com a senha do banco de dados no servidor:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "echo \"your_secure_password\" | docker secret create db_password -\n" -msgstr "" +msgstr "echo \"your_secure_password\" | docker secret create db_password -\n" #. type: Title ## -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Building and pushing the image" -msgstr "" +msgstr "Construindo e enviando a imagem" #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Set up Docker login on your local machine" -msgstr "" +msgstr "Configure o login do Docker na sua máquina local" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Configure Docker to authenticate with your container registry:" -msgstr "" +msgstr "Configure o Docker para se autenticar no seu registro de containers:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "docker login git.example.com\n" -msgstr "" +msgstr "docker login git.example.com\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Enter your username and password when prompted." -msgstr "" +msgstr "Informe o seu usuário e a sua senha quando solicitado." #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Build the production image" -msgstr "" +msgstr "Construa a imagem de produção" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Use the Makefile to build your production image:" -msgstr "" +msgstr "Use o Makefile para construir a imagem de produção:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "make prod-build\n" -msgstr "" +msgstr "make prod-build\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "This runs the command defined in the Makefile:" -msgstr "" +msgstr "Isso executa o comando definido no Makefile:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "docker build --file docker/Dockerfile --target prod --pull -t ${IMAGE}:${IMAGE_TAG} .\n" -msgstr "" +msgstr "docker build --file docker/Dockerfile --target prod --pull -t ${IMAGE}:${IMAGE_TAG} .\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "The Dockerfile uses a multi-stage build: 1. Installs Composer dependencies in a builder stage 2. Creates a minimal production image with only the necessary files 3. Runs as a non-root user (`www-data`)" -msgstr "" +msgstr "O Dockerfile usa um build multi-stage: 1. Instala as dependências do Composer em um estágio de build 2. Cria uma imagem de produção mínima, só com os arquivos necessários 3. Roda como um usuário não root (`www-data`)" #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Push the image to the registry" -msgstr "" +msgstr "Envie a imagem para o registro" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Push your built image to the container registry:" -msgstr "" +msgstr "Envie a imagem construída para o registro de containers:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "make prod-push\n" -msgstr "" +msgstr "make prod-push\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "This executes:" -msgstr "" +msgstr "Isso executa:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "docker push ${IMAGE}:${IMAGE_TAG}\n" -msgstr "" +msgstr "docker push ${IMAGE}:${IMAGE_TAG}\n" #. type: Title ## -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Deploying to Docker Swarm" -msgstr "" +msgstr "Fazendo deploy no Docker Swarm" #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Configure SSH access" -msgstr "" +msgstr "Configure o acesso SSH" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Set up SSH key-based authentication to your server:" -msgstr "" +msgstr "Configure a autenticação por chave SSH no seu servidor:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "" "# Generate SSH key (if you don't have one)\n" @@ -503,125 +496,122 @@ msgid "" " IdentityFile ~/.ssh/id_ed25519\n" "EOF\n" msgstr "" +"# Gera uma chave SSH (se você ainda não tiver uma)\n" +"ssh-keygen -t ed25519 -C \"your_email@example.com\"\n" +"\n" +"# Copia a chave para o seu servidor\n" +"ssh-copy-id user@your-server-ip\n" +"\n" +"# Adiciona o host SSH à sua configuração SSH (~/.ssh/config)\n" +"cat >> ~/.ssh/config << EOF\n" +"Host docker-web\n" +" HostName your-server-ip\n" +" User user\n" +" IdentityFile ~/.ssh/id_ed25519\n" +"EOF\n" #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Set up Docker context" -msgstr "" +msgstr "Configure o contexto do Docker" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Create a Docker context for remote deployment:" -msgstr "" +msgstr "Crie um contexto do Docker para o deploy remoto:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "docker context create swarm-prod --docker \"host=ssh://docker-web\"\n" -msgstr "" +msgstr "docker context create swarm-prod --docker \"host=ssh://docker-web\"\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Alternatively, configure the `DOCKER_HOST` environment variable:" -msgstr "" +msgstr "Como alternativa, configure a variável de ambiente `DOCKER_HOST`:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "export DOCKER_HOST=ssh://docker-web\n" -msgstr "" +msgstr "export DOCKER_HOST=ssh://docker-web\n" #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Deploy the application" -msgstr "" +msgstr "Faça o deploy da aplicação" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Deploy your application stack to Docker Swarm:" -msgstr "" +msgstr "Faça o deploy da stack da sua aplicação no Docker Swarm:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "make prod-deploy\n" -msgstr "" +msgstr "make prod-deploy\n" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "docker -H ${PROD_SSH} stack deploy --prune --detach=false --with-registry-auth -c docker/compose.yml -c docker/prod/compose.yml ${STACK_NAME}\n" -msgstr "" +msgstr "docker -H ${PROD_SSH} stack deploy --prune --detach=false --with-registry-auth -c docker/compose.yml -c docker/prod/compose.yml ${STACK_NAME}\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "The `--with-registry-auth` flag ensures the Swarm nodes can pull images from your private registry." -msgstr "" +msgstr "A flag `--with-registry-auth` garante que os nós do Swarm consigam baixar imagens do seu registro privado." #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Verify the deployment" -msgstr "" +msgstr "Verifique o deploy" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Check the status of your services:" -msgstr "" +msgstr "Verifique o status dos seus serviços:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "" "docker -H ssh://docker-web service ls\n" "docker -H ssh://docker-web service ps ${STACK_NAME}_app\n" msgstr "" +"docker -H ssh://docker-web service ls\n" +"docker -H ssh://docker-web service ps ${STACK_NAME}_app\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "View logs:" -msgstr "" +msgstr "Veja os logs:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "docker -H ssh://docker-web service logs ${STACK_NAME}_app\n" -msgstr "" +msgstr "docker -H ssh://docker-web service logs ${STACK_NAME}_app\n" #. type: Title ## -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Monitoring and maintenance" -msgstr "" +msgstr "Monitoramento e manutenção" #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "View service logs" -msgstr "" +msgstr "Veja os logs do serviço" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "" "# View all logs\n" @@ -633,49 +623,50 @@ msgid "" "# View logs with timestamps\n" "docker -H ssh://docker-web service logs -t ${STACK_NAME}_app\n" msgstr "" +"# Mostra todos os logs\n" +"docker -H ssh://docker-web service logs -f ${STACK_NAME}_app\n" +"\n" +"# Mostra as últimas 100 linhas de log\n" +"docker -H ssh://docker-web service logs --tail 100 ${STACK_NAME}_app\n" +"\n" +"# Mostra os logs com timestamps\n" +"docker -H ssh://docker-web service logs -t ${STACK_NAME}_app\n" #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Scale the application" -msgstr "" +msgstr "Escale a aplicação" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Adjust the number of replicas:" -msgstr "" +msgstr "Ajuste o número de réplicas:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "docker -H ssh://docker-web service scale ${STACK_NAME}_app=3\n" -msgstr "" +msgstr "docker -H ssh://docker-web service scale ${STACK_NAME}_app=3\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Or update the `replicas` value in `docker/prod/compose.yml` and redeploy." -msgstr "" +msgstr "Ou atualize o valor de `replicas` em `docker/prod/compose.yml` e faça o deploy de novo." #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Resource limits" -msgstr "" +msgstr "Limites de recursos" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Add resource limits to prevent containers from consuming all server resources. Update `docker/prod/compose.yml`:" -msgstr "" +msgstr "Adicione limites de recursos para evitar que os containers consumam todos os recursos do servidor. Atualize o `docker/prod/compose.yml`:" #. type: Fenced code block (yaml) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "" "services:\n" @@ -690,47 +681,54 @@ msgid "" " cpus: '0.25'\n" " memory: 256M\n" msgstr "" +"services:\n" +" app:\n" +" # ... configuração existente ...\n" +" deploy:\n" +" resources:\n" +" limits:\n" +" cpus: '0.5'\n" +" memory: 512M\n" +" reservations:\n" +" cpus: '0.25'\n" +" memory: 256M\n" #. type: Title ## -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md -#: ../src/cookbook/disabling-csrf-protection.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md ../src/cookbook/disabling-csrf-protection.md #, no-wrap msgid "Security considerations" -msgstr "" +msgstr "Considerações de segurança" #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Use Docker secrets for sensitive data" -msgstr "" +msgstr "Use Docker secrets para dados sensíveis" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Instead of environment variables, use Docker secrets for sensitive information:" -msgstr "" +msgstr "Em vez de variáveis de ambiente, use Docker secrets para informações sensíveis:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "" "# Create secrets\n" "echo \"database_password\" | docker secret create db_password -\n" "echo \"api_key\" | docker secret create api_key -\n" msgstr "" +"# Cria os secrets\n" +"echo \"database_password\" | docker secret create db_password -\n" +"echo \"api_key\" | docker secret create api_key -\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Update `docker/prod/compose.yml`:" -msgstr "" +msgstr "Atualize o `docker/prod/compose.yml`:" #. type: Fenced code block (yaml) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "" "services:\n" @@ -745,29 +743,36 @@ msgid "" " api_key:\n" " external: true\n" msgstr "" +"services:\n" +" app:\n" +" secrets:\n" +" - db_password\n" +" - api_key\n" +"\n" +"secrets:\n" +" db_password:\n" +" external: true\n" +" api_key:\n" +" external: true\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Access secrets in your application at `/run/secrets/secret_name`." -msgstr "" +msgstr "Acesse os secrets na sua aplicação em `/run/secrets/secret_name`." #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Set up a firewall" -msgstr "" +msgstr "Configure um firewall" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Configure UFW (Uncomplicated Firewall) on your server:" -msgstr "" +msgstr "Configure o UFW (Uncomplicated Firewall) no seu servidor:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "" "# Allow SSH\n" @@ -786,23 +791,35 @@ msgid "" "# Enable the firewall\n" "sudo ufw enable\n" msgstr "" +"# Libera SSH\n" +"sudo ufw allow 22/tcp\n" +"\n" +"# Libera HTTP e HTTPS\n" +"sudo ufw allow 80/tcp\n" +"sudo ufw allow 443/tcp\n" +"\n" +"# Libera as portas do Docker Swarm (se você pretende adicionar mais nós)\n" +"sudo ufw allow 2377/tcp\n" +"sudo ufw allow 7946/tcp\n" +"sudo ufw allow 7946/udp\n" +"sudo ufw allow 4789/udp\n" +"\n" +"# Habilita o firewall\n" +"sudo ufw enable\n" #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Keep the system updated" -msgstr "" +msgstr "Mantenha o sistema atualizado" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Regularly update your server and Docker:" -msgstr "" +msgstr "Atualize regularmente o seu servidor e o Docker:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "" "# Update system packages\n" @@ -811,58 +828,57 @@ msgid "" "# Update Docker images\n" "docker -H ssh://docker-web service update --image ${IMAGE}:${IMAGE_TAG} ${STACK_NAME}_app\n" msgstr "" +"# Atualiza os pacotes do sistema\n" +"sudo apt-get update && sudo apt-get upgrade -y\n" +"\n" +"# Atualiza as imagens Docker\n" +"docker -H ssh://docker-web service update --image ${IMAGE}:${IMAGE_TAG} ${STACK_NAME}_app\n" #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Service won't start" -msgstr "" +msgstr "O serviço não sobe" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Check service events and logs:" -msgstr "" +msgstr "Verifique os eventos e os logs do serviço:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "" "docker -H ssh://docker-web service ps ${STACK_NAME}_app --no-trunc\n" "docker -H ssh://docker-web service logs ${STACK_NAME}_app\n" msgstr "" +"docker -H ssh://docker-web service ps ${STACK_NAME}_app --no-trunc\n" +"docker -H ssh://docker-web service logs ${STACK_NAME}_app\n" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Common issues: - **Image pull errors**: Verify registry authentication with `docker -H ssh://docker-web login` - **Port conflicts**: Ensure no other services are using ports 80/443 - **Resource constraints**: Check available resources with `docker -H ssh://docker-web node ls`" -msgstr "" +msgstr "Problemas comuns: - **Erros ao baixar a imagem**: verifique a autenticação no registro com `docker -H ssh://docker-web login` - **Conflitos de porta**: garanta que nenhum outro serviço esteja usando as portas 80/443 - **Limitação de recursos**: verifique os recursos disponíveis com `docker -H ssh://docker-web node ls`" #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "SSL certificate issues" -msgstr "" +msgstr "Problemas com certificados SSL" #. type: Title ### -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Container registry connection issues" -msgstr "" +msgstr "Problemas de conexão com o registro de containers" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Test registry connectivity:" -msgstr "" +msgstr "Teste a conectividade com o registro:" #. type: Fenced code block (bash) -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "" "# From your local machine\n" @@ -871,30 +887,33 @@ msgid "" "# From the server\n" "docker -H ssh://docker-web pull git.example.com/username/myapp:latest\n" msgstr "" +"# Na sua máquina local\n" +"docker pull git.example.com/username/myapp:latest\n" +"\n" +"# No servidor\n" +"docker -H ssh://docker-web pull git.example.com/username/myapp:latest\n" #. type: Title ## -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Summary" msgstr "Resumo" #. type: Plain text -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md msgid "The Makefile commands simplify the deployment workflow: - `make prod-build` - Build the production image - `make prod-push` - Push to the registry - `make prod-deploy` - Deploy to Docker Swarm" -msgstr "" +msgstr "Os comandos do Makefile simplificam o fluxo de deploy: - `make prod-build` - Constrói a imagem de produção - `make prod-push` - Envia para o registro - `make prod-deploy` - Faz o deploy no Docker Swarm" #. type: Title # #: ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Deploying Yii applications to Docker Swarm and Traefik" -msgstr "" +msgstr "Fazendo deploy de aplicações Yii no Docker Swarm com Traefik" #. type: Plain text #: ../src/cookbook/deployment/docker-swarm-traefik.md msgid "This guide walks you through deploying a Yii application to [Docker Swarm](https://docs.docker.com/engine/swarm/) starting from a blank server, using [Traefik](https://traefik.io/traefik) as a reverse proxy and deploying from a container registry ([Forgejo](https://forgejo.org/) or [Gitea](https://about.gitea.com/))." -msgstr "" +msgstr "Este guia mostra como fazer o deploy de uma aplicação Yii no [Docker Swarm](https://docs.docker.com/engine/swarm/) a partir de um servidor vazio, usando o [Traefik](https://traefik.io/traefik) como proxy reverso e fazendo o deploy a partir de um registro de containers ([Forgejo](https://forgejo.org/) ou [Gitea](https://about.gitea.com/))." #. type: Fenced code block (mermaid) #: ../src/cookbook/deployment/docker-swarm-traefik.md @@ -911,17 +930,27 @@ msgid "" " D\n" " end\n" msgstr "" +"graph LR\n" +" A[Internet] --> B[Proxy reverso: Traefik]\n" +" B --> C[app1.example.com]\n" +" B --> D[app2.example.com]\n" +" \n" +" subgraph Docker Swarm Cluster\n" +" B\n" +" C\n" +" D\n" +" end\n" #. type: Title ## #: ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "Setting up Traefik as reverse proxy" -msgstr "" +msgstr "Configurando o Traefik como proxy reverso" #. type: Plain text #: ../src/cookbook/deployment/docker-swarm-traefik.md msgid "To deploy Traefik as reverse proxy create a file `traefik-stack.yml`:" -msgstr "" +msgstr "Para fazer o deploy do Traefik como proxy reverso, crie um arquivo `traefik-stack.yml`:" #. type: Fenced code block (yaml) #: ../src/cookbook/deployment/docker-swarm-traefik.md @@ -961,17 +990,50 @@ msgid "" " reverse_proxy_public:\n" " external: true\n" msgstr "" +"services:\n" +" traefik:\n" +" image: traefik:v2.10\n" +" command:\n" +" - \"--api.insecure=true\"\n" +" - \"--providers.docker=true\"\n" +" - \"--providers.docker.swarmMode=true\"\n" +" - \"--providers.docker.exposedbydefault=false\"\n" +" - \"--entrypoints.web.address=:80\"\n" +" - \"--entrypoints.websecure.address=:443\"\n" +" - \"--certificatesresolvers.letsencrypt.acme.tlschallenge=true\"\n" +" - \"--certificatesresolvers.letsencrypt.acme.email=admin@example.com\"\n" +" - \"--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json\"\n" +" ports:\n" +" - \"80:80\"\n" +" - \"443:443\"\n" +" - \"8080:8080\"\n" +" volumes:\n" +" - \"/var/run/docker.sock:/var/run/docker.sock:ro\"\n" +" - \"traefik_certificates:/letsencrypt\"\n" +" networks:\n" +" - reverse_proxy_public\n" +" deploy:\n" +" placement:\n" +" constraints:\n" +" - node.role == manager\n" +"\n" +"volumes:\n" +" traefik_certificates:\n" +"\n" +"networks:\n" +" reverse_proxy_public:\n" +" external: true\n" #. type: Plain text #: ../src/cookbook/deployment/docker-swarm-traefik.md msgid "Deploy Traefik:" -msgstr "" +msgstr "Faça o deploy do Traefik:" #. type: Fenced code block (bash) #: ../src/cookbook/deployment/docker-swarm-traefik.md #, no-wrap msgid "docker stack deploy -c traefik-stack.yml traefik\n" -msgstr "" +msgstr "docker stack deploy -c traefik-stack.yml traefik\n" #. type: Fenced code block (yaml) #: ../src/cookbook/deployment/docker-swarm-traefik.md @@ -1001,11 +1063,34 @@ msgid "" " reverse_proxy_public:\n" " external: true\n" msgstr "" +"services:\n" +" forgejo:\n" +" image: codeberg.org/forgejo/forgejo:1.21\n" +" ports:\n" +" - \"3000:3000\"\n" +" volumes:\n" +" - forgejo_data:/data\n" +" networks:\n" +" - reverse_proxy_public\n" +" deploy:\n" +" labels:\n" +" - \"traefik.enable=true\"\n" +" - \"traefik.http.routers.app.rule=Host(`git.example.com`)\"\n" +" - \"traefik.http.routers.app.entrypoints=websecure\"\n" +" - \"traefik.http.routers.app.tls.certresolver=letsencrypt\"\n" +" - \"traefik.http.services.app.loadbalancer.server.port=3000\" \n" +"\n" +"volumes:\n" +" forgejo_data:\n" +"\n" +"networks:\n" +" reverse_proxy_public:\n" +" external: true\n" #. type: Plain text #: ../src/cookbook/deployment/docker-swarm-traefik.md msgid "After deployment, access Forgejo at `https://git.example.com` and complete the initial setup. Make sure to enable the container registry in the settings." -msgstr "" +msgstr "Depois do deploy, acesse o Forgejo em `https://git.example.com` e conclua a configuração inicial. Não esqueça de habilitar o registro de containers nas configurações." #. type: Fenced code block (yaml) #: ../src/cookbook/deployment/docker-swarm-traefik.md @@ -1035,11 +1120,34 @@ msgid "" " reverse_proxy_public:\n" " external: true\n" msgstr "" +"services:\n" +" gitea:\n" +" image: gitea/gitea:latest\n" +" ports:\n" +" - \"3000:3000\"\n" +" volumes:\n" +" - gitea_data:/data\n" +" networks:\n" +" - reverse_proxy_public\n" +" deploy:\n" +" labels:\n" +" - \"traefik.enable=true\"\n" +" - \"traefik.http.routers.app.rule=Host(`git.example.com`)\"\n" +" - \"traefik.http.routers.app.entrypoints=websecure\"\n" +" - \"traefik.http.routers.app.tls.certresolver=letsencrypt\"\n" +" - \"traefik.http.services.app.loadbalancer.server.port=3000\" \n" +"\n" +"volumes:\n" +" gitea_data:\n" +"\n" +"networks:\n" +" reverse_proxy_public:\n" +" external: true\n" #. type: Plain text #: ../src/cookbook/deployment/docker-swarm-traefik.md msgid "When using Traefik, you'll need to modify the Yii application's `docker/prod/compose.yml` to use Traefik labels instead of Caddy labels:" -msgstr "" +msgstr "Ao usar o Traefik, você precisa alterar o `docker/prod/compose.yml` da aplicação Yii para usar labels do Traefik em vez de labels do Caddy:" #. type: Fenced code block (yaml) #: ../src/cookbook/deployment/docker-swarm-traefik.md @@ -1083,18 +1191,55 @@ msgid "" " - \"traefik.http.routers.app.tls.certresolver=letsencrypt\"\n" " - \"traefik.http.services.app.loadbalancer.server.port=80\"\n" msgstr "" +"services:\n" +" app:\n" +" image: ${IMAGE}:${IMAGE_TAG}\n" +" networks:\n" +" - reverse_proxy_public\n" +" volumes:\n" +" - runtime:/app/runtime\n" +" - caddy_data:/data\n" +" - caddy_config:/config\n" +" env_file:\n" +" - path: ./prod/.env\n" +" - path: ./prod/override.env\n" +" required: false\\\n" +" environment:\n" +" CADDY_EXTRA_CONFIG: 'auto_https off'\n" +" deploy:\n" +" replicas: 2\n" +" update_config:\n" +" delay: 10s\n" +" parallelism: 1\n" +" order: start-first\n" +" failure_action: rollback\n" +" monitor: 10s\n" +" rollback_config:\n" +" parallelism: 0\n" +" order: stop-first\n" +" restart_policy:\n" +" condition: on-failure\n" +" delay: 5s\n" +" max_attempts: 3\n" +" window: 120s\n" +" labels:\n" +" - \"traefik.enable=true\"\n" +" - \"traefik.http.routers.app.rule=Host(`${PROD_HOST:-app.example.com}`)\"\n" +" - \"traefik.http.routers.app.entrypoints=websecure\"\n" +" - \"traefik.http.routers.app.tls.certresolver=letsencrypt\"\n" +" - \"traefik.http.services.app.loadbalancer.server.port=80\"\n" #. type: Plain text #: ../src/cookbook/deployment/docker-swarm-traefik.md msgid "If Traefik can't obtain certificates: - Verify DNS is pointing to your server - Check that ports 80 and 443 are accessible from the internet - Ensure the email in the Let's Encrypt configuration is valid - Check logs: `docker -H ssh://docker-web service logs traefik_traefik`" -msgstr "" +msgstr "Se o Traefik não consegue obter os certificados: - Verifique se o DNS aponta para o seu servidor - Verifique se as portas 80 e 443 estão acessíveis pela internet - Garanta que o e-mail na configuração do Let's Encrypt é válido - Verifique os logs: `docker -H ssh://docker-web service logs traefik_traefik`" #. type: Plain text #: ../src/cookbook/deployment/docker-swarm-traefik.md msgid "You've successfully deployed a Yii application to Docker Swarm with: - A container registry (Forgejo or Gitea) - Automatic HTTPS via Traefik - Zero-downtime deployments with rolling updates - High availability with multiple replicas" -msgstr "" +msgstr "Você fez o deploy de uma aplicação Yii no Docker Swarm com: - Um registro de containers (Forgejo ou Gitea) - HTTPS automático via Traefik - Deploys sem downtime com rolling updates - Alta disponibilidade com várias réplicas" #. type: Plain text #: ../src/cookbook/deployment/docker-swarm-traefik.md msgid "For more information, see: - [Yii Application Template](https://github.com/yiisoft/app) - [Docker Swarm Documentation](https://docs.docker.com/engine/swarm/) - [Traefik Documentation](https://doc.traefik.io/traefik/)" -msgstr "" +msgstr "Para mais informações, veja: - [Template de aplicação do Yii](https://github.com/yiisoft/app) - [Documentação do Docker Swarm](https://docs.docker.com/engine/swarm/) - [Documentação do Traefik](https://doc.traefik.io/traefik/)" diff --git a/_translations/po/pt-BR/cookbook_deployment_docker-swarm.md.po b/_translations/po/pt-BR/cookbook_deployment_docker-swarm.md.po index 8f4c87a7..128b97f8 100644 --- a/_translations/po/pt-BR/cookbook_deployment_docker-swarm.md.po +++ b/_translations/po/pt-BR/cookbook_deployment_docker-swarm.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-01-02 23:54+0000\n" "PO-Revision-Date: 2026-01-02 23:54+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,14 +19,14 @@ msgstr "" #: ../src/cookbook/deployment/docker-swarm.md #, no-wrap msgid "Deploying Yii applications to Docker Swarm" -msgstr "" +msgstr "Fazendo deploy de aplicações Yii no Docker Swarm" #. type: Bullet: '- ' #: ../src/cookbook/deployment/docker-swarm.md msgid "[Using Caddy](docker-swarm-caddy.md)" -msgstr "" +msgstr "[Usando Caddy](docker-swarm-caddy.md)" #. type: Bullet: '- ' #: ../src/cookbook/deployment/docker-swarm.md msgid "[Using Traefik](docker-swarm-traefik.md)" -msgstr "" +msgstr "[Usando Traefik](docker-swarm-traefik.md)" diff --git a/_translations/po/pt-BR/cookbook_deployment_rolling-update-migrations.md.po b/_translations/po/pt-BR/cookbook_deployment_rolling-update-migrations.md.po index 21f8bf78..a3b7446c 100644 --- a/_translations/po/pt-BR/cookbook_deployment_rolling-update-migrations.md.po +++ b/_translations/po/pt-BR/cookbook_deployment_rolling-update-migrations.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-05-30 09:18+0000\n" "PO-Revision-Date: 2026-05-30 09:18+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,136 +19,136 @@ msgstr "" #: ../src/cookbook/deployment/rolling-update-migrations.md #, no-wrap msgid "Applying migrations during rolling updates" -msgstr "" +msgstr "Aplicando migrations durante rolling updates" #. type: Plain text #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Rolling updates keep old and new application instances running at the same time. This makes database changes more delicate than in a single-server deployment: both application versions must work with the same database while the deployment is in progress." -msgstr "" +msgstr "Rolling updates mantêm instâncias antigas e novas da aplicação rodando ao mesmo tempo. Isso torna as mudanças no banco de dados mais delicadas do que em um deploy em um único servidor: as duas versões da aplicação precisam funcionar com o mesmo banco de dados enquanto o deploy está em andamento." #. type: Plain text #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "The safe rule is:" -msgstr "" +msgstr "A regra segura é:" #. type: Bullet: '1. ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Apply database changes that are compatible with the current production code." -msgstr "" +msgstr "Aplique mudanças no banco de dados que sejam compatíveis com o código atual de produção." #. type: Bullet: '2. ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Deploy code that starts using these database changes." -msgstr "" +msgstr "Faça o deploy do código que passa a usar essas mudanças no banco de dados." #. type: Bullet: '3. ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Remove obsolete database structures only after every old application instance is gone." -msgstr "" +msgstr "Remova estruturas obsoletas do banco de dados só depois que todas as instâncias antigas da aplicação tiverem saído." #. type: Plain text #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "This is often called the expand and contract pattern. First expand the schema so both versions can use it. Then move the application code. Finally contract the schema in a later deployment." -msgstr "" +msgstr "Isso costuma ser chamado de padrão expand and contract. Primeiro expanda o schema para que as duas versões possam usá-lo. Depois atualize o código da aplicação. Por fim, contraia o schema em um deploy posterior." #. type: Title ## #: ../src/cookbook/deployment/rolling-update-migrations.md #, no-wrap msgid "Why this matters" -msgstr "" +msgstr "Por que isso importa" #. type: Plain text #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "During a rolling update, requests may be served by different versions of the application:" -msgstr "" +msgstr "Durante um rolling update, as requisições podem ser atendidas por versões diferentes da aplicação:" #. type: Bullet: '- ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "old code that does not know about the new schema;" -msgstr "" +msgstr "código antigo, que não conhece o novo schema;" #. type: Bullet: '- ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "new code that expects the new schema;" -msgstr "" +msgstr "código novo, que espera o novo schema;" #. type: Bullet: '- ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "background workers that may lag behind web instances;" -msgstr "" +msgstr "workers em segundo plano, que podem ficar atrás das instâncias web;" #. type: Bullet: '- ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "scheduled commands that may run during deployment." -msgstr "" +msgstr "comandos agendados, que podem rodar durante o deploy." #. type: Plain text #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "If a migration drops or renames a column before all old instances stop using it, old code fails. If code that requires a new column is deployed before the column exists, new code fails. The migration plan must keep every intermediate state valid." -msgstr "" +msgstr "Se uma migration remove ou renomeia uma coluna antes que todas as instâncias antigas parem de usá-la, o código antigo falha. Se o código que exige uma coluna nova vai para produção antes de a coluna existir, o código novo falha. O plano de migrations precisa manter válido cada estado intermediário." #. type: Title ## #: ../src/cookbook/deployment/rolling-update-migrations.md #, no-wrap msgid "Deployment flow" -msgstr "" +msgstr "Fluxo de deploy" #. type: Plain text #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Use this flow for changes that must not interrupt production traffic:" -msgstr "" +msgstr "Use este fluxo para mudanças que não podem interromper o tráfego de produção:" #. type: Bullet: '1. ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Create a migration that only adds compatible schema." -msgstr "" +msgstr "Crie uma migration que apenas adiciona schema compatível." #. type: Bullet: '2. ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Apply this migration to production while the current application version is still running." -msgstr "" +msgstr "Aplique essa migration em produção enquanto a versão atual da aplicação ainda está rodando." #. type: Bullet: '3. ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Deploy the new application version with a rolling update." -msgstr "" +msgstr "Faça o deploy da nova versão da aplicação com um rolling update." #. type: Bullet: '4. ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Verify that all instances and workers run the new version." -msgstr "" +msgstr "Verifique se todas as instâncias e workers rodam a nova versão." #. type: Bullet: '5. ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "In a later release, apply cleanup migrations that remove old columns, indexes, tables, or compatibility code." -msgstr "" +msgstr "Em uma release posterior, aplique as migrations de limpeza que removem colunas, índices, tabelas ou código de compatibilidade antigos." #. type: Plain text #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "For Yii applications, run migrations with the same command you use in regular deployments, for example:" -msgstr "" +msgstr "Em aplicações Yii, rode as migrations com o mesmo comando que você usa nos deploys normais, por exemplo:" #. type: Fenced code block (shell) #: ../src/cookbook/deployment/rolling-update-migrations.md #, no-wrap msgid "./yii migrate\n" -msgstr "" +msgstr "./yii migrate\n" #. type: Plain text #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Run migrations from a single deployment job or one dedicated console container. Do not let every rolling application instance run migrations on startup." -msgstr "" +msgstr "Rode as migrations a partir de um único job de deploy ou de um container de console dedicado. Não deixe cada instância do rolling update rodar migrations na inicialização." #. type: Title ## #: ../src/cookbook/deployment/rolling-update-migrations.md #, no-wrap msgid "Adding a column" -msgstr "" +msgstr "Adicionando uma coluna" #. type: Plain text #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Adding a nullable column is usually compatible with old code:" -msgstr "" +msgstr "Adicionar uma coluna que aceita nulo normalmente é compatível com o código antigo:" #. type: Fenced code block (php) #: ../src/cookbook/deployment/rolling-update-migrations.md @@ -161,330 +161,336 @@ msgid "" " $b->addColumn('user', 'display_name', $cb::string());\n" "}\n" msgstr "" +"public function up(MigrationBuilder $b): void\n" +"{\n" +" $cb = $b->columnBuilder();\n" +"\n" +" $b->addColumn('user', 'display_name', $cb::string());\n" +"}\n" #. type: Plain text #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Then deploy code that writes and reads `display_name`." -msgstr "" +msgstr "Depois, faça o deploy do código que grava e lê `display_name`." #. type: Plain text #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "If the column must eventually be required:" -msgstr "" +msgstr "Se a coluna precisar ser obrigatória no futuro:" #. type: Bullet: '1. ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Add it as nullable." -msgstr "" +msgstr "Adicione-a como coluna que aceita nulo." #. type: Bullet: '2. ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Deploy code that writes it for new and updated rows." -msgstr "" +msgstr "Faça o deploy do código que a preenche em linhas novas e atualizadas." #. type: Bullet: '3. ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Backfill existing rows in batches." -msgstr "" +msgstr "Preencha as linhas existentes em lotes." #. type: Bullet: '4. ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Add a `NOT NULL` constraint in a later migration." -msgstr "" +msgstr "Adicione uma restrição `NOT NULL` em uma migration posterior." #. type: Plain text #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Do not add a `NOT NULL` column without a database default while old code still inserts rows without that column." -msgstr "" +msgstr "Não adicione uma coluna `NOT NULL` sem um valor padrão no banco de dados enquanto o código antigo ainda insere linhas sem essa coluna." #. type: Title ## #: ../src/cookbook/deployment/rolling-update-migrations.md #, no-wrap msgid "Renaming a column" -msgstr "" +msgstr "Renomeando uma coluna" #. type: Plain text #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Renaming is not compatible because old code uses the old name and new code uses the new name. Use a multi-release change instead:" -msgstr "" +msgstr "Renomear não é compatível, porque o código antigo usa o nome antigo e o código novo usa o nome novo. Em vez disso, faça a mudança ao longo de várias releases:" #. type: Bullet: '1. ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Add the new column." -msgstr "" +msgstr "Adicione a nova coluna." #. type: Bullet: '2. ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Backfill it from the old column." -msgstr "" +msgstr "Preencha-a a partir da coluna antiga." #. type: Bullet: '3. ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Deploy code that writes both columns and reads the new column with a fallback to the old one." -msgstr "" +msgstr "Faça o deploy do código que grava nas duas colunas e lê a nova coluna, com fallback para a antiga." #. type: Bullet: '4. ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Wait until all old code is gone." -msgstr "" +msgstr "Espere até que todo o código antigo tenha saído." #. type: Bullet: '5. ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Deploy code that uses only the new column." -msgstr "" +msgstr "Faça o deploy do código que usa só a nova coluna." #. type: Bullet: '6. ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Drop the old column in a later cleanup migration." -msgstr "" +msgstr "Remova a coluna antiga em uma migration de limpeza posterior." #. type: Plain text #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "The same approach works for moving data to a different table." -msgstr "" +msgstr "A mesma abordagem funciona para mover dados para outra tabela." #. type: Title ## #: ../src/cookbook/deployment/rolling-update-migrations.md #, no-wrap msgid "Changing a column type" -msgstr "" +msgstr "Mudando o tipo de uma coluna" #. type: Plain text #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Changing a column type in place may lock the table or break either the old or new code. Prefer a new column:" -msgstr "" +msgstr "Mudar o tipo de uma coluna no lugar pode travar a tabela ou quebrar o código antigo ou o novo. Prefira uma coluna nova:" #. type: Bullet: '1. ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Add a column with the target type." -msgstr "" +msgstr "Adicione uma coluna com o tipo desejado." #. type: Bullet: '2. ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Backfill it in batches." -msgstr "" +msgstr "Preencha-a em lotes." #. type: Bullet: '3. ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Deploy code that writes both columns." -msgstr "" +msgstr "Faça o deploy do código que grava nas duas colunas." #. type: Bullet: '4. ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Deploy code that reads the new column." -msgstr "" +msgstr "Faça o deploy do código que lê a nova coluna." #. type: Bullet: '5. ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Drop the old column after all code uses the new one." -msgstr "" +msgstr "Remova a coluna antiga depois que todo o código usar a nova." #. type: Plain text #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "For small tables, an in-place type change may be acceptable. For production tables with traffic, verify locking behavior on the exact database engine and version before applying it." -msgstr "" +msgstr "Em tabelas pequenas, mudar o tipo no lugar pode ser aceitável. Em tabelas de produção com tráfego, verifique o comportamento de locks no motor e na versão exatos do banco de dados antes de aplicar a mudança." #. type: Title ## #: ../src/cookbook/deployment/rolling-update-migrations.md #, no-wrap msgid "Dropping columns and tables" -msgstr "" +msgstr "Removendo colunas e tabelas" #. type: Plain text #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Dropping is a cleanup step, not the first step:" -msgstr "" +msgstr "Remover é uma etapa de limpeza, não a primeira etapa:" #. type: Bullet: '1. ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Deploy code that no longer reads or writes the column or table." -msgstr "" +msgstr "Faça o deploy do código que não lê nem grava mais a coluna ou a tabela." #. type: Bullet: '2. ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Confirm that old application instances, workers, and scheduled commands are stopped." -msgstr "" +msgstr "Confirme que as instâncias antigas da aplicação, os workers e os comandos agendados pararam." #. type: Bullet: '3. ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Confirm that no external reporting or maintenance scripts depend on it." -msgstr "" +msgstr "Confirme que nenhum relatório externo ou script de manutenção depende dela." #. type: Bullet: '4. ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Drop it in a separate migration." -msgstr "" +msgstr "Remova-a em uma migration separada." #. type: Plain text #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "This makes rollback safer. If you need to roll back application code before cleanup, the old schema is still available." -msgstr "" +msgstr "Isso torna o rollback mais seguro. Se você precisar fazer rollback do código da aplicação antes da limpeza, o schema antigo ainda está disponível." #. type: Title ## #: ../src/cookbook/deployment/rolling-update-migrations.md #, no-wrap msgid "Adding indexes and constraints" -msgstr "" +msgstr "Adicionando índices e restrições" #. type: Plain text #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Indexes and constraints may be logically compatible but operationally risky because they can lock tables." -msgstr "" +msgstr "Índices e restrições podem ser logicamente compatíveis, mas arriscados na operação, porque podem travar tabelas." #. type: Plain text #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "For indexes:" -msgstr "" +msgstr "Para índices:" #. type: Bullet: '- ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "use online index creation when the database supports it;" -msgstr "" +msgstr "use criação de índice online quando o banco de dados suportar;" #. type: Bullet: '- ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "for PostgreSQL, consider `CREATE INDEX CONCURRENTLY` from a migration or command that is not wrapped in a transaction;" -msgstr "" +msgstr "no PostgreSQL, considere `CREATE INDEX CONCURRENTLY` em uma migration ou comando que não esteja dentro de uma transação;" #. type: Bullet: '- ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "for MySQL and MariaDB, check whether the operation can use online DDL for your table and engine." -msgstr "" +msgstr "no MySQL e no MariaDB, verifique se a operação pode usar online DDL para a sua tabela e o seu motor." #. type: Plain text #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "For constraints:" -msgstr "" +msgstr "Para restrições:" #. type: Bullet: '- ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "clean invalid data before adding the constraint;" -msgstr "" +msgstr "limpe os dados inválidos antes de adicionar a restrição;" #. type: Bullet: '- ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "add the constraint only after deployed code preserves it;" -msgstr "" +msgstr "adicione a restrição só depois que o código em produção a respeitar;" #. type: Bullet: '- ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "for PostgreSQL, consider adding foreign keys and check constraints as `NOT VALID`, then validating them separately." -msgstr "" +msgstr "no PostgreSQL, considere adicionar chaves estrangeiras e check constraints como `NOT VALID` e validá-las separadamente depois." #. type: Plain text #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Keep long-running index creation and validation separate from unrelated schema changes so it is easier to monitor and retry them." -msgstr "" +msgstr "Mantenha a criação de índices e as validações demoradas separadas de mudanças de schema não relacionadas, para facilitar o monitoramento e novas tentativas." #. type: Title ## #: ../src/cookbook/deployment/rolling-update-migrations.md #, no-wrap msgid "Data migrations" -msgstr "" +msgstr "Migrations de dados" #. type: Plain text #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Data migrations that touch many rows should be safe to run while the application is live:" -msgstr "" +msgstr "Migrations de dados que mexem em muitas linhas precisam ser seguras para rodar com a aplicação no ar:" #. type: Bullet: '- ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "make them idempotent so rerunning them does not corrupt data;" -msgstr "" +msgstr "torne-as idempotentes, para que rodar de novo não corrompa os dados;" #. type: Bullet: '- ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "process rows in small batches;" -msgstr "" +msgstr "processe as linhas em lotes pequenos;" #. type: Bullet: '- ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "avoid depending on current application service or entity logic because that logic changes over time;" -msgstr "" +msgstr "evite depender da lógica atual de serviços ou entidades da aplicação, porque essa lógica muda com o tempo;" #. type: Bullet: '- ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "prefer forward-compatible values that both old and new code can handle;" -msgstr "" +msgstr "prefira valores compatíveis com o futuro, que tanto o código antigo quanto o novo consigam tratar;" #. type: Bullet: '- ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "store progress when a backfill is too large for a single migration run." -msgstr "" +msgstr "guarde o progresso quando um preenchimento for grande demais para uma única execução de migration." #. type: Plain text #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "For very large backfills, use a console command or background job after the schema migration. The schema migration should prepare the database; the background process should move the data gradually." -msgstr "" +msgstr "Para preenchimentos muito grandes, use um comando de console ou um job em segundo plano depois da migration de schema. A migration de schema deve preparar o banco de dados; o processo em segundo plano deve mover os dados aos poucos." #. type: Title ## #: ../src/cookbook/deployment/rolling-update-migrations.md #, no-wrap msgid "Reverting" -msgstr "" +msgstr "Revertendo" #. type: Plain text #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "In production rolling deployments, reverting a destructive migration is often harder than deploying a corrective migration. Treat `down()` methods for destructive operations as a local-development convenience, not as the main production rollback plan." -msgstr "" +msgstr "Em deploys com rolling update em produção, reverter uma migration destrutiva costuma ser mais difícil do que fazer o deploy de uma migration corretiva. Trate os métodos `down()` de operações destrutivas como uma conveniência para o desenvolvimento local, não como o principal plano de rollback em produção." #. type: Plain text #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "A practical rollback plan is:" -msgstr "" +msgstr "Um plano de rollback prático é:" #. type: Bullet: '- ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "before cleanup, roll back code only because old schema is still present;" -msgstr "" +msgstr "antes da limpeza, faça rollback apenas do código, porque o schema antigo ainda existe;" #. type: Bullet: '- ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "after cleanup, deploy a new forward migration that restores the required structure or compatibility;" -msgstr "" +msgstr "depois da limpeza, faça o deploy de uma nova migration que restaure a estrutura ou a compatibilidade necessária;" #. type: Bullet: '- ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "restore from backup only when data was actually lost and no forward repair is possible." -msgstr "" +msgstr "restaure um backup só quando dados foram realmente perdidos e nenhum reparo por uma nova migration é possível." #. type: Title ## #: ../src/cookbook/deployment/rolling-update-migrations.md #, no-wrap msgid "Checklist" -msgstr "" +msgstr "Checklist" #. type: Plain text #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "Before applying a production migration, verify that:" -msgstr "" +msgstr "Antes de aplicar uma migration em produção, verifique que:" #. type: Bullet: '- ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "the current production code works after the migration;" -msgstr "" +msgstr "o código atual de produção funciona depois da migration;" #. type: Bullet: '- ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "the new code works before and after all instances are updated;" -msgstr "" +msgstr "o código novo funciona antes e depois de todas as instâncias serem atualizadas;" #. type: Bullet: '- ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "old workers and scheduled commands are covered;" -msgstr "" +msgstr "workers antigos e comandos agendados foram considerados;" #. type: Bullet: '- ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "inserts and updates keep required columns valid in every deployment phase;" -msgstr "" +msgstr "inserts e updates mantêm as colunas obrigatórias válidas em todas as fases do deploy;" #. type: Bullet: '- ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "long-running schema operations will not block production traffic unexpectedly;" -msgstr "" +msgstr "operações de schema demoradas não vão bloquear o tráfego de produção de forma inesperada;" #. type: Bullet: '- ' #: ../src/cookbook/deployment/rolling-update-migrations.md msgid "cleanup happens in a separate release after the rollout is complete." -msgstr "" +msgstr "a limpeza acontece em uma release separada, depois que o rollout terminou." diff --git a/_translations/po/pt-BR/cookbook_disabling-csrf-protection.md.po b/_translations/po/pt-BR/cookbook_disabling-csrf-protection.md.po index b695a18d..61943478 100644 --- a/_translations/po/pt-BR/cookbook_disabling-csrf-protection.md.po +++ b/_translations/po/pt-BR/cookbook_disabling-csrf-protection.md.po @@ -8,110 +8,108 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-06-29 17:10+0000\n" "PO-Revision-Date: 2026-06-29 17:10+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md -#: ../src/cookbook/disabling-csrf-protection.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md ../src/cookbook/disabling-csrf-protection.md #, no-wrap msgid "Security considerations" -msgstr "" +msgstr "Considerações de segurança" #. type: Title # #: ../src/cookbook/disabling-csrf-protection.md #, no-wrap msgid "Disabling CSRF protection" -msgstr "" +msgstr "Desativando a proteção CSRF" #. type: Title ## #: ../src/cookbook/disabling-csrf-protection.md #, no-wrap msgid "What is CSRF protection?" -msgstr "" +msgstr "O que é a proteção CSRF?" #. type: Plain text #: ../src/cookbook/disabling-csrf-protection.md msgid "Cross-Site Request Forgery (CSRF) protection is a security mechanism that prevents malicious websites from making unauthorized requests on behalf of authenticated users. Yii3 includes built-in CSRF protection through the `Yiisoft\\Yii\\Web\\Middleware\\CsrfTokenMiddleware` middleware." -msgstr "" +msgstr "A proteção contra Cross-Site Request Forgery (CSRF) é um mecanismo de segurança que impede sites maliciosos de fazer requisições não autorizadas em nome de usuários autenticados. O Yii3 inclui proteção CSRF nativa por meio do middleware `Yiisoft\\Yii\\Web\\Middleware\\CsrfTokenMiddleware`." #. type: Plain text #: ../src/cookbook/disabling-csrf-protection.md msgid "For a comprehensive understanding of CSRF attacks and protection mechanisms, see the [Security best practices](../guide/security/best-practices.md#avoiding-csrf) section in the main guide." -msgstr "" +msgstr "Para entender a fundo os ataques CSRF e os mecanismos de proteção, veja a seção [Boas práticas de segurança](../guide/security/best-practices.md#evitando-csrf) do guia principal." #. type: Title ## #: ../src/cookbook/disabling-csrf-protection.md #, no-wrap msgid "When to disable CSRF protection" -msgstr "" +msgstr "Quando desativar a proteção CSRF" #. type: Plain text #: ../src/cookbook/disabling-csrf-protection.md msgid "While CSRF protection should generally remain enabled for web applications, there are specific scenarios where you might need to disable it:" -msgstr "" +msgstr "Embora a proteção CSRF deva, em geral, continuar ativada em aplicações web, há cenários específicos em que você pode precisar desativá-la:" #. type: Title ### #: ../src/cookbook/disabling-csrf-protection.md #, no-wrap msgid "When external systems cannot provide CSRF tokens" -msgstr "" +msgstr "Quando sistemas externos não conseguem fornecer tokens CSRF" #. type: Plain text #: ../src/cookbook/disabling-csrf-protection.md msgid "When building APIs or handling automated requests from external systems, CSRF protection can interfere with legitimate requests since these systems cannot provide valid CSRF tokens:" -msgstr "" +msgstr "Ao construir APIs ou tratar requisições automatizadas de sistemas externos, a proteção CSRF pode atrapalhar requisições legítimas, já que esses sistemas não conseguem fornecer tokens CSRF válidos:" #. type: Bullet: '- ' #: ../src/cookbook/disabling-csrf-protection.md msgid "**Third-party integrations**: External services cannot provide valid CSRF tokens" -msgstr "" +msgstr "**Integrações de terceiros**: serviços externos não conseguem fornecer tokens CSRF válidos" #. type: Bullet: '- ' #: ../src/cookbook/disabling-csrf-protection.md msgid "**Mobile applications**: Native mobile apps typically don't use cookies or sessions in the same way as web browsers" -msgstr "" +msgstr "**Aplicativos móveis**: apps móveis nativos normalmente não usam cookies ou sessões da mesma forma que os navegadores" #. type: Bullet: '- ' #: ../src/cookbook/disabling-csrf-protection.md msgid "**Server-to-server communication**: API endpoints designed for machine-to-machine communication" -msgstr "" +msgstr "**Comunicação entre servidores**: endpoints de API projetados para comunicação máquina a máquina" #. type: Bullet: '- ' #: ../src/cookbook/disabling-csrf-protection.md msgid "**Payment processors**: PayPal, Stripe, and other payment systems send webhook notifications" -msgstr "" +msgstr "**Processadores de pagamento**: PayPal, Stripe e outros sistemas de pagamento enviam notificações por webhook" #. type: Bullet: '- ' #: ../src/cookbook/disabling-csrf-protection.md msgid "**Version control systems**: GitHub, GitLab webhooks for CI/CD pipelines" -msgstr "" +msgstr "**Sistemas de controle de versão**: webhooks do GitHub e do GitLab para pipelines de CI/CD" #. type: Bullet: '- ' #: ../src/cookbook/disabling-csrf-protection.md msgid "**Social media platforms**: Twitter, Facebook webhook notifications" -msgstr "" +msgstr "**Redes sociais**: notificações por webhook do Twitter e do Facebook" #. type: Bullet: '- ' #: ../src/cookbook/disabling-csrf-protection.md msgid "**Communication services**: Slack, Discord bot integrations" -msgstr "" +msgstr "**Serviços de comunicação**: integrações com bots do Slack e do Discord" #. type: Title ## #: ../src/cookbook/disabling-csrf-protection.md #, no-wrap msgid "How to disable CSRF protection" -msgstr "" +msgstr "Como desativar a proteção CSRF" #. type: Plain text #: ../src/cookbook/disabling-csrf-protection.md msgid "First, you need to remove CSRF middleware from your main application middleware list in `config/web/di/application.php`:" -msgstr "" +msgstr "Primeiro, remova o middleware de CSRF da lista principal de middlewares da aplicação em `config/web/di/application.php`:" #. type: Fenced code block (php) #: ../src/cookbook/disabling-csrf-protection.md @@ -128,11 +126,21 @@ msgid "" " SessionMiddleware::class,\n" " CsrfTokenMiddleware::class, // <- Remove this line \n" msgstr "" +"return [\n" +" Application::class => [\n" +" '__construct()' => [\n" +" 'dispatcher' => DynamicReference::to([\n" +" 'class' => MiddlewareDispatcher::class,\n" +" 'withMiddlewares()' => [\n" +" [\n" +" ErrorCatcher::class,\n" +" SessionMiddleware::class,\n" +" CsrfTokenMiddleware::class, // <- Remova esta linha \n" #. type: Plain text #: ../src/cookbook/disabling-csrf-protection.md msgid "Now, if you need to leave CSRF on for specific routes or route groups, you can do so by adding the `CsrfTokenMiddleware` middleware to the router configuration in `config/common/routes.php`. For a group that would be the following:" -msgstr "" +msgstr "Agora, se você precisar manter o CSRF ativo para rotas ou grupos de rotas específicos, adicione o middleware `CsrfTokenMiddleware` na configuração do router em `config/common/routes.php`. Para um grupo, fica assim:" #. type: Fenced code block (php) #: ../src/cookbook/disabling-csrf-protection.md @@ -143,11 +151,15 @@ msgid "" " ->middleware(CsrfTokenMiddleware::class)\n" " ->routes(\n" msgstr "" +"return [\n" +" Group::create()\n" +" ->middleware(CsrfTokenMiddleware::class)\n" +" ->routes(\n" #. type: Plain text #: ../src/cookbook/disabling-csrf-protection.md msgid "For a single route, you can add the middleware directly to the route:" -msgstr "" +msgstr "Para uma única rota, você pode adicionar o middleware diretamente nela:" #. type: Fenced code block (php) #: ../src/cookbook/disabling-csrf-protection.md @@ -158,79 +170,83 @@ msgid "" " ->name('echo/say')\n" " ->middleware(CsrfTokenMiddleware::class)\n" msgstr "" +"Route::methods([Method::GET, Method::POST], '/say[/{test}]')\n" +" ->action(\\App\\Controller\\Echo\\Action::class)\n" +" ->name('echo/say')\n" +" ->middleware(CsrfTokenMiddleware::class)\n" #. type: Plain text #: ../src/cookbook/disabling-csrf-protection.md msgid "When disabling CSRF protection, keep these security considerations in mind:" -msgstr "" +msgstr "Ao desativar a proteção CSRF, tenha em mente estas considerações de segurança:" #. type: Title ### #: ../src/cookbook/disabling-csrf-protection.md #, no-wrap msgid "Alternative authentication methods" -msgstr "" +msgstr "Métodos alternativos de autenticação" #. type: Plain text #: ../src/cookbook/disabling-csrf-protection.md msgid "For API endpoints, implement proper authentication mechanisms:" -msgstr "" +msgstr "Para endpoints de API, implemente mecanismos de autenticação adequados:" #. type: Bullet: '- ' #: ../src/cookbook/disabling-csrf-protection.md msgid "**API keys**: Require API keys for authentication" -msgstr "" +msgstr "**Chaves de API**: exija chaves de API para autenticação" #. type: Bullet: '- ' #: ../src/cookbook/disabling-csrf-protection.md msgid "**Bearer tokens**: Use JWT or similar token-based authentication" -msgstr "" +msgstr "**Bearer tokens**: use JWT ou autenticação similar baseada em token" #. type: Bullet: '- ' #: ../src/cookbook/disabling-csrf-protection.md msgid "**OAuth 2.0**: Implement OAuth 2.0 for third-party access" -msgstr "" +msgstr "**OAuth 2.0**: implemente OAuth 2.0 para acesso de terceiros" #. type: Bullet: '- ' #: ../src/cookbook/disabling-csrf-protection.md msgid "**IP whitelisting**: Restrict access to known IP addresses for webhooks" -msgstr "" +msgstr "**Lista de IPs permitidos**: restrinja o acesso de webhooks a endereços IP conhecidos" #. type: Title ### #: ../src/cookbook/disabling-csrf-protection.md #, no-wrap msgid "Request validation" -msgstr "" +msgstr "Validação da requisição" #. type: Plain text #: ../src/cookbook/disabling-csrf-protection.md msgid "Implement additional validation for requests without CSRF protection:" -msgstr "" +msgstr "Implemente validação adicional para requisições sem proteção CSRF:" #. type: Bullet: '- ' #: ../src/cookbook/disabling-csrf-protection.md msgid "**Signature verification**: Verify webhook signatures (e.g., GitHub's X-Hub-Signature)" -msgstr "" +msgstr "**Verificação de assinatura**: verifique assinaturas de webhooks (por exemplo, o X-Hub-Signature do GitHub)" #. type: Bullet: '- ' #: ../src/cookbook/disabling-csrf-protection.md msgid "**Timestamp validation**: Check request timestamps to prevent replay attacks" -msgstr "" +msgstr "**Validação de timestamp**: confira o timestamp das requisições para evitar ataques de replay" #. type: Bullet: '- ' #: ../src/cookbook/disabling-csrf-protection.md msgid "**Rate limiting**: Implement rate limiting to prevent abuse" -msgstr "" +msgstr "**Rate limiting**: implemente limite de requisições para evitar abuso" #. type: Bullet: '- ' #: ../src/cookbook/disabling-csrf-protection.md msgid "**Input validation**: Strictly validate all input parameters" -msgstr "" +msgstr "**Validação de entrada**: valide rigorosamente todos os parâmetros de entrada" #. type: Title ### #: ../src/cookbook/disabling-csrf-protection.md #, no-wrap msgid "Example: Webhook signature verification" -msgstr "" +msgstr "Exemplo: verificação de assinatura de webhook" #. type: Fenced code block (php) #: ../src/cookbook/disabling-csrf-protection.md @@ -261,50 +277,74 @@ msgid "" " }\n" "}\n" msgstr "" +"getHeaderLine('X-Webhook-Signature');\n" +" $payload = (string) $request->getBody();\n" +" $expectedSignature = hash_hmac('sha256', $payload, $this->webhookSecret);\n" +" \n" +" if (!hash_equals($signature, $expectedSignature)) {\n" +" throw new \\RuntimeException('Invalid webhook signature');\n" +" }\n" +" \n" +" // Processa o payload do webhook\n" +" // ...\n" +" }\n" +"}\n" #. type: Title ## #: ../src/cookbook/disabling-csrf-protection.md #, no-wrap msgid "Best practices" -msgstr "" +msgstr "Boas práticas" #. type: Bullet: '1. ' #: ../src/cookbook/disabling-csrf-protection.md msgid "**Minimize exposure**: Only disable CSRF protection where absolutely necessary" -msgstr "" +msgstr "**Minimize a exposição**: desative a proteção CSRF apenas onde for realmente necessário" #. type: Bullet: '2. ' #: ../src/cookbook/disabling-csrf-protection.md msgid "**Use HTTPS**: Always use HTTPS for API endpoints and webhooks" -msgstr "" +msgstr "**Use HTTPS**: sempre use HTTPS para endpoints de API e webhooks" #. type: Bullet: '3. ' #: ../src/cookbook/disabling-csrf-protection.md msgid "**Monitor logs**: Log all requests to API endpoints for security monitoring" -msgstr "" +msgstr "**Monitore os logs**: registre em log todas as requisições aos endpoints de API para monitoramento de segurança" #. type: Bullet: '4. ' #: ../src/cookbook/disabling-csrf-protection.md msgid "**Regular security audits**: Periodically review your API endpoints and their security measures" -msgstr "" +msgstr "**Auditorias de segurança regulares**: revise periodicamente seus endpoints de API e as medidas de segurança deles" #. type: Bullet: '5. ' #: ../src/cookbook/disabling-csrf-protection.md msgid "**Documentation**: Clearly document which endpoints have CSRF protection disabled and why" -msgstr "" +msgstr "**Documentação**: documente claramente quais endpoints têm a proteção CSRF desativada e por quê" #. type: Title ## #: ../src/cookbook/disabling-csrf-protection.md #, no-wrap msgid "Conclusion" -msgstr "" +msgstr "Conclusão" #. type: Plain text #: ../src/cookbook/disabling-csrf-protection.md msgid "While CSRF protection is crucial for web applications, there are legitimate scenarios where it needs to be disabled, particularly for external APIs and webhooks. When disabling CSRF protection, always implement alternative security measures and follow security best practices to maintain the overall security of your application." -msgstr "" +msgstr "Embora a proteção CSRF seja essencial para aplicações web, há cenários legítimos em que ela precisa ser desativada, principalmente para APIs externas e webhooks. Ao desativá-la, sempre implemente medidas de segurança alternativas e siga as boas práticas de segurança para manter a segurança geral da sua aplicação." #. type: Plain text #: ../src/cookbook/disabling-csrf-protection.md msgid "Remember that disabling CSRF protection increases security risks, so careful consideration and proper implementation of alternative security measures are essential." -msgstr "" +msgstr "Lembre-se de que desativar a proteção CSRF aumenta os riscos de segurança, então é essencial avaliar com cuidado e implementar corretamente as medidas de segurança alternativas." diff --git a/_translations/po/pt-BR/cookbook_making-http-requests.md.po b/_translations/po/pt-BR/cookbook_making-http-requests.md.po index 84bb70e4..04e25044 100644 --- a/_translations/po/pt-BR/cookbook_making-http-requests.md.po +++ b/_translations/po/pt-BR/cookbook_making-http-requests.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-05-06 19:16+0000\n" "PO-Revision-Date: 2026-05-06 19:16+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,55 +19,50 @@ msgstr "" #: ../src/cookbook/making-http-requests.md #, no-wrap msgid "Making HTTP requests" -msgstr "" +msgstr "Fazendo requisições HTTP" #. type: Plain text #: ../src/cookbook/making-http-requests.md msgid "Yii doesn't include its own HTTP client implementation. Use a client that implements [PSR-18](https://www.php-fig.org/psr/psr-18/) and depend on PSR interfaces in your application code." -msgstr "" +msgstr "O Yii não inclui uma implementação própria de cliente HTTP. Use um cliente que implemente a [PSR-18](https://www.php-fig.org/psr/psr-18/) e dependa das interfaces PSR no código da sua aplicação." #. type: Plain text #: ../src/cookbook/making-http-requests.md msgid "This recipe uses [Guzzle](https://docs.guzzlephp.org/) as the HTTP client. Guzzle provides a PSR-18 client and uses PSR-7 messages." -msgstr "" +msgstr "Esta receita usa o [Guzzle](https://docs.guzzlephp.org/) como cliente HTTP. O Guzzle fornece um cliente PSR-18 e usa mensagens PSR-7." #. type: Title ## -#: ../src/cookbook/making-http-requests.md -#: ../src/cookbook/sentry-integration.md -#: ../src/guide/tutorial/using-yii-with-frankenphp.md -#: ../src/guide/tutorial/using-yii-with-roadrunner.md -#: ../src/guide/tutorial/using-yii-with-swoole.md ../src/guide/views/asset.md -#: ../src/guide/views/view.md ../src/guide/views/widget.md +#: ../src/cookbook/making-http-requests.md ../src/cookbook/sentry-integration.md ../src/guide/tutorial/using-yii-with-frankenphp.md ../src/guide/tutorial/using-yii-with-roadrunner.md ../src/guide/tutorial/using-yii-with-swoole.md ../src/guide/views/asset.md ../src/guide/views/view.md ../src/guide/views/widget.md #, no-wrap msgid "Installation" -msgstr "" +msgstr "Instalação" #. type: Plain text #: ../src/cookbook/making-http-requests.md msgid "Install Guzzle:" -msgstr "" +msgstr "Instale o Guzzle:" #. type: Fenced code block (shell) #: ../src/cookbook/making-http-requests.md #, no-wrap msgid "composer require guzzlehttp/guzzle\n" -msgstr "" +msgstr "composer require guzzlehttp/guzzle\n" #. type: Plain text #: ../src/cookbook/making-http-requests.md msgid "The package installs the PSR HTTP interfaces and `guzzlehttp/psr7`, which provides PSR-7 messages and PSR-17 factories." -msgstr "" +msgstr "O pacote instala as interfaces HTTP da PSR e o `guzzlehttp/psr7`, que fornece mensagens PSR-7 e factories PSR-17." #. type: Title ## #: ../src/cookbook/making-http-requests.md #, no-wrap msgid "Configure the container" -msgstr "" +msgstr "Configure o container" #. type: Plain text #: ../src/cookbook/making-http-requests.md msgid "Create `config/common/di/http-client.php`:" -msgstr "" +msgstr "Crie `config/common/di/http-client.php`:" #. type: Fenced code block (php) #: ../src/cookbook/making-http-requests.md @@ -104,22 +99,52 @@ msgid "" " UriFactoryInterface::class => Reference::to(HttpFactory::class),\n" "];\n" msgstr "" +" [\n" +" 'class' => Client::class,\n" +" '__construct()' => [\n" +" 'config' => [\n" +" 'timeout' => 10.0,\n" +" 'connect_timeout' => 3.0,\n" +" ],\n" +" ],\n" +" ],\n" +"\n" +" HttpFactory::class => HttpFactory::class,\n" +" RequestFactoryInterface::class => Reference::to(HttpFactory::class),\n" +" ResponseFactoryInterface::class => Reference::to(HttpFactory::class),\n" +" StreamFactoryInterface::class => Reference::to(HttpFactory::class),\n" +" UriFactoryInterface::class => Reference::to(HttpFactory::class),\n" +"];\n" #. type: Plain text #: ../src/cookbook/making-http-requests.md msgid "Use `ClientInterface` for sending requests and PSR-17 factories for creating requests, streams, and URIs." -msgstr "" +msgstr "Use `ClientInterface` para enviar requisições e as factories PSR-17 para criar requisições, streams e URIs." #. type: Title ## #: ../src/cookbook/making-http-requests.md #, no-wrap msgid "Send a GET request" -msgstr "" +msgstr "Envie uma requisição GET" #. type: Plain text #: ../src/cookbook/making-http-requests.md msgid "Inject `Psr\\Http\\Client\\ClientInterface` and `Psr\\Http\\Message\\RequestFactoryInterface` into the service that talks to the external API:" -msgstr "" +msgstr "Injete `Psr\\Http\\Client\\ClientInterface` e `Psr\\Http\\Message\\RequestFactoryInterface` no serviço que conversa com a API externa:" #. type: Fenced code block (php) #: ../src/cookbook/making-http-requests.md @@ -177,22 +202,73 @@ msgid "" " }\n" "}\n" msgstr "" +"\n" +" */\n" +" public function latest(string $owner, string $repository): array\n" +" {\n" +" $request = $this->requestFactory\n" +" ->createRequest(\n" +" 'GET',\n" +" sprintf(\n" +" 'https://api.github.com/repos/%s/%s/releases/latest',\n" +" rawurlencode($owner),\n" +" rawurlencode($repository),\n" +" ),\n" +" )\n" +" ->withHeader('Accept', 'application/vnd.github+json');\n" +"\n" +" try {\n" +" $response = $this->httpClient->sendRequest($request);\n" +" } catch (ClientExceptionInterface $e) {\n" +" throw new RuntimeException('GitHub request failed.', previous: $e);\n" +" }\n" +"\n" +" if ($response->getStatusCode() !== 200) {\n" +" throw new RuntimeException(sprintf(\n" +" 'GitHub returned HTTP %d.',\n" +" $response->getStatusCode(),\n" +" ));\n" +" }\n" +"\n" +" return json_decode((string) $response->getBody(), true, 512, JSON_THROW_ON_ERROR);\n" +" }\n" +"}\n" #. type: Plain text #: ../src/cookbook/making-http-requests.md msgid "PSR-18 clients throw `ClientExceptionInterface` for request sending errors. HTTP status codes such as `404` and `500` are valid responses, so check the status code in your service." -msgstr "" +msgstr "Clientes PSR-18 lançam `ClientExceptionInterface` para erros no envio da requisição. Códigos de status HTTP como `404` e `500` são respostas válidas, então verifique o código de status no seu serviço." #. type: Title ## #: ../src/cookbook/making-http-requests.md #, no-wrap msgid "Send JSON" -msgstr "" +msgstr "Envie JSON" #. type: Plain text #: ../src/cookbook/making-http-requests.md msgid "Use `StreamFactoryInterface` when you need a request body:" -msgstr "" +msgstr "Use `StreamFactoryInterface` quando precisar de um corpo na requisição:" #. type: Fenced code block (php) #: ../src/cookbook/making-http-requests.md @@ -234,10 +310,44 @@ msgid "" " }\n" "}\n" msgstr "" +" $payload\n" +" */\n" +" public function send(array $payload): void\n" +" {\n" +" $body = $this->streamFactory->createStream(json_encode($payload, JSON_THROW_ON_ERROR));\n" +"\n" +" $request = $this->requestFactory\n" +" ->createRequest('POST', 'https://api.example.com/webhooks')\n" +" ->withHeader('Content-Type', 'application/json')\n" +" ->withHeader('Accept', 'application/json')\n" +" ->withBody($body);\n" +"\n" +" $this->httpClient->sendRequest($request);\n" +" }\n" +"}\n" #. type: Title ### -#: ../src/cookbook/making-http-requests.md ../src/guide/index.md -#: ../src/guide/tutorial/docker.md +#: ../src/cookbook/making-http-requests.md ../src/guide/index.md ../src/guide/tutorial/docker.md #, no-wrap msgid "Testing" msgstr "Testes" @@ -245,7 +355,7 @@ msgstr "Testes" #. type: Plain text #: ../src/cookbook/making-http-requests.md msgid "For unit tests, pass a client configured with Guzzle's `MockHandler`:" -msgstr "" +msgstr "Para testes unitários, passe um cliente configurado com o `MockHandler` do Guzzle:" #. type: Fenced code block (php) #: ../src/cookbook/making-http-requests.md @@ -282,14 +392,44 @@ msgid "" " }\n" "}\n" msgstr "" +" '1.0.0'], JSON_THROW_ON_ERROR)),\n" +" ]);\n" +"\n" +" $client = new Client(['handler' => HandlerStack::create($handler)]);\n" +" $factory = new HttpFactory();\n" +"\n" +" $releaseClient = new ReleaseClient($client, $factory);\n" +"\n" +" $release = $releaseClient->latest('yiisoft', 'docs');\n" +"\n" +" $this->assertSame('1.0.0', $release['tag_name']);\n" +" }\n" +"}\n" #. type: Title ## #: ../src/cookbook/making-http-requests.md #, no-wrap msgid "When to use Guzzle directly" -msgstr "" +msgstr "Quando usar o Guzzle diretamente" #. type: Plain text #: ../src/cookbook/making-http-requests.md msgid "Depend on PSR interfaces for regular application services. Use `GuzzleHttp\\Client` directly in infrastructure code that needs Guzzle-only features such as asynchronous requests, handler stacks, or middleware." -msgstr "" +msgstr "Dependa das interfaces PSR nos serviços comuns da aplicação. Use `GuzzleHttp\\Client` diretamente em código de infraestrutura que precise de recursos exclusivos do Guzzle, como requisições assíncronas, handler stacks ou middleware." diff --git a/_translations/po/pt-BR/cookbook_opening-files-in-phpstorm.md.po b/_translations/po/pt-BR/cookbook_opening-files-in-phpstorm.md.po index 6733e6db..2fb4b200 100644 --- a/_translations/po/pt-BR/cookbook_opening-files-in-phpstorm.md.po +++ b/_translations/po/pt-BR/cookbook_opening-files-in-phpstorm.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-05-06 19:23+0000\n" "PO-Revision-Date: 2026-05-06 19:23+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,18 +19,18 @@ msgstr "" #: ../src/cookbook/opening-files-in-phpstorm.md #, no-wrap msgid "Opening files directly in PhpStorm" -msgstr "" +msgstr "Abrindo arquivos diretamente no PhpStorm" #. type: Plain text #: ../src/cookbook/opening-files-in-phpstorm.md msgid "Yii error pages can show links that open stack trace files in PhpStorm at the failing line. This is useful in local development when the error page runs in a browser and the project is open in the IDE." -msgstr "" +msgstr "As páginas de erro do Yii podem mostrar links que abrem os arquivos do stack trace no PhpStorm, na linha que falhou. Isso é útil no desenvolvimento local, quando a página de erro roda no navegador e o projeto está aberto na IDE." #. type: Title ## #: ../src/cookbook/opening-files-in-phpstorm.md #, no-wrap msgid "Check Toolbox links" -msgstr "" +msgstr "Verifique os links do Toolbox" #. type: Plain text #: ../src/cookbook/opening-files-in-phpstorm.md @@ -40,43 +40,46 @@ msgid "" "right-click a project file in the Project tool window and select **Copy Path/Reference** > **Toolbox URL**.\n" "If the copied URL has `origin`, keep the `origin` parameter and its value in your links.\n" msgstr "" +"O PhpStorm suporta URLs do Toolbox que usam o protocolo `jetbrains://`. Para obter o valor de `project` e o formato do caminho,\n" +"clique com o botão direito em um arquivo do projeto na janela Project e selecione **Copy Path/Reference** > **Toolbox URL**.\n" +"Se a URL copiada tiver `origin`, mantenha o parâmetro `origin` e o valor dele nos seus links.\n" #. type: Plain text #: ../src/cookbook/opening-files-in-phpstorm.md msgid "On Linux, check that Toolbox registered the protocol handler:" -msgstr "" +msgstr "No Linux, verifique se o Toolbox registrou o handler do protocolo:" #. type: Fenced code block (shell) #: ../src/cookbook/opening-files-in-phpstorm.md #, no-wrap msgid "xdg-mime query default x-scheme-handler/jetbrains\n" -msgstr "" +msgstr "xdg-mime query default x-scheme-handler/jetbrains\n" #. type: Plain text #: ../src/cookbook/opening-files-in-phpstorm.md msgid "The command should print a Toolbox or JetBrains daemon desktop file, for example `jetbrainsd.desktop`." -msgstr "" +msgstr "O comando deve imprimir um arquivo desktop do Toolbox ou do daemon da JetBrains, por exemplo `jetbrainsd.desktop`." #. type: Plain text #: ../src/cookbook/opening-files-in-phpstorm.md msgid "PhpStorm should be running with the project open when you click stack trace links." -msgstr "" +msgstr "O PhpStorm deve estar rodando com o projeto aberto quando você clicar nos links do stack trace." #. type: Title ## #: ../src/cookbook/opening-files-in-phpstorm.md #, no-wrap msgid "Configure error trace links" -msgstr "" +msgstr "Configure os links do stack trace" #. type: Plain text #: ../src/cookbook/opening-files-in-phpstorm.md msgid "The Yii application template configures `Yiisoft\\ErrorHandler\\Renderer\\HtmlRenderer` in `config/common/di/error-handler.php`. It reads a `traceLink` parameter and uses it for stack trace file links." -msgstr "" +msgstr "O template de aplicação do Yii configura o `Yiisoft\\ErrorHandler\\Renderer\\HtmlRenderer` em `config/common/di/error-handler.php`. Ele lê um parâmetro `traceLink` e o usa nos links de arquivos do stack trace." #. type: Plain text #: ../src/cookbook/opening-files-in-phpstorm.md msgid "Add the parameter to `config/common/params.php`:" -msgstr "" +msgstr "Adicione o parâmetro em `config/common/params.php`:" #. type: Fenced code block (php) #: ../src/cookbook/opening-files-in-phpstorm.md @@ -91,32 +94,40 @@ msgid "" " // Other parameters.\n" "];\n" msgstr "" +" 'jetbrains://phpstorm/navigate/reference?project=my-app&path={file}:{line}',\n" +" // Outros parâmetros.\n" +"];\n" #. type: Plain text #: ../src/cookbook/opening-files-in-phpstorm.md msgid "Replace `my-app` with the `project` value from the Toolbox URL. If the Toolbox URL uses `origin`, keep `origin` in the link template and use its value." -msgstr "" +msgstr "Substitua `my-app` pelo valor de `project` da URL do Toolbox. Se a URL do Toolbox usar `origin`, mantenha `origin` no template do link e use o valor dele." #. type: Plain text #: ../src/cookbook/opening-files-in-phpstorm.md msgid "After that, open a debug error page and click a file link in the stack trace." -msgstr "" +msgstr "Depois disso, abra uma página de erro em modo debug e clique em um link de arquivo no stack trace." #. type: Title ## #: ../src/cookbook/opening-files-in-phpstorm.md #, no-wrap msgid "Map Docker paths to host paths" -msgstr "" +msgstr "Mapeie os caminhos do Docker para os caminhos do host" #. type: Plain text #: ../src/cookbook/opening-files-in-phpstorm.md msgid "When the application runs in Docker, stack traces usually contain container paths such as `/app/src/...`. PhpStorm needs the matching host path." -msgstr "" +msgstr "Quando a aplicação roda no Docker, os stack traces geralmente contêm caminhos do container, como `/app/src/...`. O PhpStorm precisa do caminho correspondente no host." #. type: Plain text #: ../src/cookbook/opening-files-in-phpstorm.md msgid "Set `APP_HOST_PATH` in `docker/dev/override.env` to the project path on the host machine. Set `APP_IDE_PROJECT` to the `project` value from a Toolbox URL. If the URL uses `origin`, store the `origin` value instead and use `origin` in the final URL template:" -msgstr "" +msgstr "Defina `APP_HOST_PATH` em `docker/dev/override.env` com o caminho do projeto na máquina host. Defina `APP_IDE_PROJECT` com o valor de `project` de uma URL do Toolbox. Se a URL usar `origin`, guarde o valor de `origin` e use `origin` no template final da URL:" #. type: Fenced code block (dotenv) #: ../src/cookbook/opening-files-in-phpstorm.md @@ -125,32 +136,34 @@ msgid "" "APP_HOST_PATH=/home/user/projects/my-app\n" "APP_IDE_PROJECT=my-app\n" msgstr "" +"APP_HOST_PATH=/home/user/projects/my-app\n" +"APP_IDE_PROJECT=my-app\n" #. type: Plain text #: ../src/cookbook/opening-files-in-phpstorm.md msgid "`docker/dev/override.env` is for developer-specific settings and shouldn't be committed. See [Override env files](../guide/tutorial/docker.md#override-env-files) for details." -msgstr "" +msgstr "O `docker/dev/override.env` é para configurações específicas de cada desenvolvedor e não deve ser commitado. Veja [Arquivos env de override](../guide/tutorial/docker.md#arquivos-env-de-override) para mais detalhes." #. type: Plain text #: ../src/cookbook/opening-files-in-phpstorm.md msgid "In the application parameters, expose these environment values as `$params['app']['hostPath']` and `$params['app']['ideProject']`." -msgstr "" +msgstr "Nos parâmetros da aplicação, exponha esses valores de ambiente como `$params['app']['hostPath']` e `$params['app']['ideProject']`." #. type: Plain text #: ../src/cookbook/opening-files-in-phpstorm.md msgid "With the default application template, `/app/src/Web/HomePage/Action.php` will be linked as `/home/user/projects/my-app/src/Web/HomePage/Action.php`." -msgstr "" +msgstr "Com o template de aplicação padrão, `/app/src/Web/HomePage/Action.php` será linkado como `/home/user/projects/my-app/src/Web/HomePage/Action.php`." #. type: Title ## #: ../src/cookbook/opening-files-in-phpstorm.md #, no-wrap msgid "Configure `HtmlRenderer` manually" -msgstr "" +msgstr "Configure o `HtmlRenderer` manualmente" #. type: Plain text #: ../src/cookbook/opening-files-in-phpstorm.md msgid "If your application doesn't have the template's `error-handler.php` configuration, configure `HtmlRenderer` directly:" -msgstr "" +msgstr "Se a sua aplicação não tiver a configuração `error-handler.php` do template, configure o `HtmlRenderer` diretamente:" #. type: Fenced code block (php) #: ../src/cookbook/opening-files-in-phpstorm.md @@ -170,11 +183,24 @@ msgid "" " ],\n" "];\n" msgstr "" +" [\n" +" '__construct()' => [\n" +" 'traceLink' => 'jetbrains://phpstorm/navigate/reference?project=my-app&path={file}:{line}',\n" +" ],\n" +" ],\n" +"];\n" #. type: Plain text #: ../src/cookbook/opening-files-in-phpstorm.md msgid "For Docker, use a closure to map the container path to the host path:" -msgstr "" +msgstr "Para o Docker, use uma closure para mapear o caminho do container para o caminho do host:" #. type: Fenced code block (php) #: ../src/cookbook/opening-files-in-phpstorm.md @@ -208,3 +234,30 @@ msgid "" " ],\n" "];\n" msgstr "" +" [\n" +" '__construct()' => [\n" +" 'traceLink' => static function (string $file, ?int $line) use ($hostPath, $project): string {\n" +" $file = preg_replace('~^/app/~', $hostPath, $file);\n" +" $path = $line === null ? $file : $file . ':' . $line;\n" +"\n" +" return str_replace(\n" +" ['{project}', '{path}'],\n" +" [$project, $path],\n" +" 'jetbrains://phpstorm/navigate/reference?project={project}&path={path}',\n" +" );\n" +" },\n" +" ],\n" +" ],\n" +"];\n" diff --git a/_translations/po/pt-BR/cookbook_organizing-code_domain.md.po b/_translations/po/pt-BR/cookbook_organizing-code_domain.md.po index 56ecbdbb..32987fa4 100644 --- a/_translations/po/pt-BR/cookbook_organizing-code_domain.md.po +++ b/_translations/po/pt-BR/cookbook_organizing-code_domain.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-10-11 10:37+0000\n" "PO-Revision-Date: 2026-10-11 10:37+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,7 +19,7 @@ msgstr "" #: ../src/cookbook/organizing-code/domain.md #, no-wrap msgid "Domain" -msgstr "" +msgstr "Domínio" #. type: Plain text #: ../src/cookbook/organizing-code/domain.md @@ -30,6 +30,10 @@ msgid "" "operates these entities. To focus on the complex part of the problem, domain is, ideally, separated from\n" " the infrastructure part of the system (that's how to save data into a database, how to form HTTP response, etc.).\n" msgstr "" +"O domínio, ou modelo de domínio, é o que torna o projeto único. Com os requisitos e a terminologia do problema a ser resolvido\n" +"em mente (o contexto do problema), você constrói uma abstração composta por entidades, seus relacionamentos e a lógica que\n" +"opera essas entidades. Para focar na parte complexa do problema, o domínio, idealmente, fica separado da\n" +" parte de infraestrutura do sistema (como salvar dados no banco de dados, como montar a resposta HTTP etc.).\n" #. type: Plain text #: ../src/cookbook/organizing-code/domain.md @@ -41,152 +45,149 @@ msgid "" "> The individual concepts of domain design below could be applied separately, so make sure to check these even if your\n" "> project isn't that complicated. \n" msgstr "" +"> [!NOTE]\n" +"> Esse isolamento é adequado para sistemas complexos. Se o domínio do seu projeto é basicamente criar/ler/atualizar/excluir\n" +"> um conjunto de registros sem muita lógica complexa, não faz sentido aplicar uma solução complexa a um problema simples.\n" +"> Os conceitos individuais de design de domínio abaixo podem ser aplicados separadamente, então vale conferi-los mesmo que o seu\n" +"> projeto não seja tão complicado. \n" #. type: Title ## #: ../src/cookbook/organizing-code/domain.md #, no-wrap msgid "Bounded context" -msgstr "" +msgstr "Bounded context" #. type: Plain text #: ../src/cookbook/organizing-code/domain.md msgid "It's nearly impossible to build a model that solves multiple problems that aren't too complicated by itself. Therefore, it's a good practice to divide the domain into several use-cases and have a separate model for each use-case. Such separated models are called \"bounded contexts.\"" -msgstr "" +msgstr "É quase impossível construir um modelo que resolva vários problemas sem que ele mesmo fique complicado demais. Por isso, é uma boa prática dividir o domínio em vários casos de uso e ter um modelo separado para cada um. Esses modelos separados são chamados de \"bounded contexts\"." #. type: Title ## #: ../src/cookbook/organizing-code/domain.md #, no-wrap msgid "Building blocks" -msgstr "" +msgstr "Blocos de construção" #. type: Plain text #: ../src/cookbook/organizing-code/domain.md msgid "There are various building blocks that are typically used when describing domain models. It isn't mandatory to use them all." -msgstr "" +msgstr "Existem vários blocos de construção normalmente usados para descrever modelos de domínio. Não é obrigatório usar todos." #. type: Bullet: '- ' -#: ../src/cookbook/organizing-code/domain.md -#: ../src/cookbook/organizing-code/service.md +#: ../src/cookbook/organizing-code/domain.md ../src/cookbook/organizing-code/service.md #, no-wrap msgid "Entity" -msgstr "" +msgstr "Entidade" #. type: Plain text #: ../src/cookbook/organizing-code/domain.md msgid "Entity is a uniquely identifiable object such as user, product, payment, etc. When comparing them, you're checking ID, not the attribute values. If there are two objects with different attributes but the same ID, they're considered being the same thing." -msgstr "" +msgstr "Entidade é um objeto identificável de forma única, como um usuário, um produto, um pagamento etc. Ao comparar entidades, você verifica o ID, não os valores dos atributos. Se dois objetos têm atributos diferentes, mas o mesmo ID, eles são considerados a mesma coisa." #. type: Title ### #: ../src/cookbook/organizing-code/domain.md #, no-wrap msgid "Value object" -msgstr "" +msgstr "Value object" #. type: Plain text #: ../src/cookbook/organizing-code/domain.md msgid "Value object describes an object by its characteristics. For example, a price that consists of value and currency. When comparing such objects, you're checking actual values. If they match, an object is considered to be the same." -msgstr "" +msgstr "Um value object descreve um objeto por suas características. Por exemplo, um preço composto por valor e moeda. Ao comparar esses objetos, você verifica os valores de fato. Se eles coincidem, os objetos são considerados iguais." #. type: Title ### #: ../src/cookbook/organizing-code/domain.md #, no-wrap msgid "Aggregate" -msgstr "" +msgstr "Agregado" #. type: Plain text #: ../src/cookbook/organizing-code/domain.md msgid "Aggregate is a set of domain objects such as entities and value objects and additional data that could be treated as a single unit. It usually represents a compound object from a domain model such as shop order or HR person dossier." -msgstr "" +msgstr "Agregado é um conjunto de objetos de domínio, como entidades e value objects, e dados adicionais que podem ser tratados como uma única unidade. Ele geralmente representa um objeto composto do modelo de domínio, como um pedido de loja ou o dossiê de uma pessoa no RH." #. type: Plain text #: ../src/cookbook/organizing-code/domain.md msgid "One of the components of an aggregate is called a root. The root identifies an aggregate as a whole and should be used to access it." -msgstr "" +msgstr "Um dos componentes de um agregado é chamado de raiz. A raiz identifica o agregado como um todo e deve ser usada para acessá-lo." #. type: Title ### #: ../src/cookbook/organizing-code/domain.md #, no-wrap msgid "Domain event" -msgstr "" +msgstr "Evento de domínio" #. type: Plain text #: ../src/cookbook/organizing-code/domain.md msgid "An aggregate, while processed, may raise events. For example, when order is confirmed, `OrderConfirmed` event would be risen so other parts of the system may react on these." -msgstr "" +msgstr "Um agregado, ao ser processado, pode disparar eventos. Por exemplo, quando um pedido é confirmado, o evento `OrderConfirmed` é disparado para que outras partes do sistema possam reagir a ele." #. type: Title ### #: ../src/cookbook/organizing-code/domain.md #, no-wrap msgid "Data transfer object" -msgstr "" +msgstr "Data transfer object" #. type: Plain text #: ../src/cookbook/organizing-code/domain.md msgid "Data transfer object or DTO is an object whose only purpose is to hold data as it is. It's commonly used to pass data between different services." -msgstr "" +msgstr "Data transfer object, ou DTO, é um objeto cujo único propósito é guardar dados como estão. Ele é comumente usado para passar dados entre diferentes serviços." #. type: Title ### #: ../src/cookbook/organizing-code/domain.md #, no-wrap msgid "Service" -msgstr "" +msgstr "Serviço" #. type: Plain text #: ../src/cookbook/organizing-code/domain.md msgid "Service is a class that contains a standalone operation within the context of your domain model. See \"[service components](service.md)\"." -msgstr "" +msgstr "Serviço é uma classe que contém uma operação independente dentro do contexto do seu modelo de domínio. Veja \"[componentes de serviço](service.md)\"." #. type: Title ## -#: ../src/cookbook/organizing-code/domain.md -#: ../src/cookbook/organizing-code/service.md ../src/guide/start/databases.md +#: ../src/cookbook/organizing-code/domain.md ../src/cookbook/organizing-code/service.md ../src/guide/start/databases.md #, no-wrap msgid "Repository" -msgstr "" +msgstr "Repositório" #. type: Plain text #: ../src/cookbook/organizing-code/domain.md msgid "The repository task is to abstract away how domain objects are obtained. These are usually separated into two parts: an interface that stays in the domain layer and an implementation that's situated in the infrastructure layer. In such a way, domain doesn't care how data is obtained and saved and may be focused around the complicated business logic instead." -msgstr "" +msgstr "A tarefa do repositório é abstrair como os objetos de domínio são obtidos. Ele geralmente é dividido em duas partes: uma interface, que fica na camada de domínio, e uma implementação, que fica na camada de infraestrutura. Dessa forma, o domínio não se importa com como os dados são obtidos e salvos e pode se concentrar na lógica de negócio complicada." #. type: Plain text #: ../src/cookbook/organizing-code/domain.md msgid "Repository is usually implemented as a service." -msgstr "" +msgstr "O repositório geralmente é implementado como um serviço." #. type: Title ### #: ../src/cookbook/organizing-code/domain.md #, no-wrap msgid "Instantiating building blocks" -msgstr "" +msgstr "Instanciando os blocos de construção" #. type: Plain text #: ../src/cookbook/organizing-code/domain.md msgid "Entity, value object, aggregate, and domain events aren't services and shouldn't be instantiated through DI container. Using `new` is the way to go with these." -msgstr "" +msgstr "Entidades, value objects, agregados e eventos de domínio não são serviços e não devem ser instanciados pelo container de DI. Use `new` para criá-los." #. type: Title ## -#: ../src/cookbook/organizing-code/domain.md -#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md -#: ../src/guide/concept/autoloading.md ../src/guide/concept/di-container.md -#: ../src/guide/security/best-practices.md -#: ../src/guide/tutorial/console-applications.md -#: ../src/internals/004-namespaces.md ../src/internals/007-exceptions.md -#: ../src/internals/008-interfaces.md +#: ../src/cookbook/organizing-code/domain.md ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md ../src/guide/concept/autoloading.md ../src/guide/concept/di-container.md ../src/guide/security/best-practices.md ../src/guide/tutorial/console-applications.md ../src/internals/004-namespaces.md ../src/internals/007-exceptions.md ../src/internals/008-interfaces.md #, no-wrap msgid "References" -msgstr "" +msgstr "Referências" #. type: Bullet: '- ' #: ../src/cookbook/organizing-code/domain.md msgid "[BoundedContext by Martin Fowler](https://martinfowler.com/bliki/BoundedContext.html)" -msgstr "" +msgstr "[BoundedContext, por Martin Fowler](https://martinfowler.com/bliki/BoundedContext.html)" #. type: Bullet: '- ' #: ../src/cookbook/organizing-code/domain.md msgid "[ValueObject by Martin Fowler](https://martinfowler.com/bliki/ValueObject.html)" -msgstr "" +msgstr "[ValueObject, por Martin Fowler](https://martinfowler.com/bliki/ValueObject.html)" #. type: Bullet: '- ' #: ../src/cookbook/organizing-code/domain.md msgid "[Aggregate by Marting Fowler](https://martinfowler.com/bliki/DDD_Aggregate.html)" -msgstr "" +msgstr "[Aggregate, por Martin Fowler](https://martinfowler.com/bliki/DDD_Aggregate.html)" diff --git a/_translations/po/pt-BR/cookbook_organizing-code_service.md.po b/_translations/po/pt-BR/cookbook_organizing-code_service.md.po index d5380918..ea8ccddb 100644 --- a/_translations/po/pt-BR/cookbook_organizing-code_service.md.po +++ b/_translations/po/pt-BR/cookbook_organizing-code_service.md.po @@ -8,37 +8,35 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-10-11 10:37+0000\n" "PO-Revision-Date: 2026-10-11 10:37+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Bullet: '- ' -#: ../src/cookbook/organizing-code/domain.md -#: ../src/cookbook/organizing-code/service.md +#: ../src/cookbook/organizing-code/domain.md ../src/cookbook/organizing-code/service.md #, no-wrap msgid "Entity" -msgstr "" +msgstr "Entidade" #. type: Title ## -#: ../src/cookbook/organizing-code/domain.md -#: ../src/cookbook/organizing-code/service.md ../src/guide/start/databases.md +#: ../src/cookbook/organizing-code/domain.md ../src/cookbook/organizing-code/service.md ../src/guide/start/databases.md #, no-wrap msgid "Repository" -msgstr "" +msgstr "Repositório" #. type: Title # #: ../src/cookbook/organizing-code/service.md #, no-wrap msgid "Service components" -msgstr "" +msgstr "Componentes de serviço" #. type: Plain text #: ../src/cookbook/organizing-code/service.md msgid "Application may get complicated, so it makes sense to extract focused parts of business logic or infrastructure into service components. They're typically injected into other components or action handlers. It's usually done via autowiring:" -msgstr "" +msgstr "A aplicação pode ficar complicada, então faz sentido extrair partes focadas da lógica de negócio ou da infraestrutura para componentes de serviço. Eles normalmente são injetados em outros componentes ou em action handlers. Isso geralmente é feito por autowiring:" #. type: Fenced code block (php) #: ../src/cookbook/organizing-code/service.md @@ -54,11 +52,20 @@ msgid "" " // ...\n" "}\n" msgstr "" +"public function actionIndex(CurrentRoute $route, MyService $myService): ResponseInterface\n" +"{\n" +" $id = $route->getArgument('id');\n" +" \n" +" // ...\n" +" $extraData = $myService->getExtraData($id);\n" +" \n" +" // ...\n" +"}\n" #. type: Plain text #: ../src/cookbook/organizing-code/service.md msgid "Yii3 doesn't technically imply any limitations on how you build services. In general, there's no need to extend from a base class or implement a certain interface:" -msgstr "" +msgstr "Tecnicamente, o Yii3 não impõe nenhuma limitação sobre como você constrói serviços. Em geral, não é preciso estender uma classe base nem implementar uma interface específica:" #. type: Fenced code block (php) #: ../src/cookbook/organizing-code/service.md @@ -78,42 +85,55 @@ msgid "" " }\n" "}\n" msgstr "" +"final readonly class MyService\n" +"{\n" +" public function __construct(\n" +" private ExtraDataStorage $extraDataStorage\n" +" )\n" +" {\n" +" }\n" +"\n" +" public function getExtraData(string $id): array\n" +" {\n" +" return $this->extraDataStorage->get($id);\n" +" }\n" +"}\n" #. type: Plain text #: ../src/cookbook/organizing-code/service.md msgid "Services either perform a task or return data. They're created once, put into a DI container and then could be used multiple times. Because of that, it's a good idea to keep your services stateless that's both service itself and any of its dependencies shouldn't hold state. You can ensure it by using `readonly` PHP keyword at class level." -msgstr "" +msgstr "Serviços executam uma tarefa ou retornam dados. Eles são criados uma vez, colocados em um container de DI e então podem ser usados várias vezes. Por isso, é uma boa ideia manter seus serviços sem estado: nem o próprio serviço nem qualquer uma de suas dependências devem guardar estado. Você pode garantir isso usando a palavra-chave `readonly` do PHP no nível da classe." #. type: Title ## #: ../src/cookbook/organizing-code/service.md #, no-wrap msgid "Service dependencies and configuration" -msgstr "" +msgstr "Dependências e configuração de serviços" #. type: Plain text #: ../src/cookbook/organizing-code/service.md msgid "Services should always define all their dependencies on other services via `__construct()`. It both allows you to use a service right away after it's created and serves as an indicator of a service doing too much if there are too many dependencies." -msgstr "" +msgstr "Serviços devem sempre declarar todas as suas dependências de outros serviços via `__construct()`. Isso permite usar o serviço logo depois de criado e também serve como indicador de que o serviço faz coisas demais, quando há dependências demais." #. type: Bullet: '- ' #: ../src/cookbook/organizing-code/service.md msgid "After the service is created, it shouldn't be re-configured in runtime." -msgstr "" +msgstr "Depois de criado, o serviço não deve ser reconfigurado em tempo de execução." #. type: Bullet: '- ' #: ../src/cookbook/organizing-code/service.md msgid "DI container instance usually **shouldn't** be injected as a dependency. Prefer concrete interfaces." -msgstr "" +msgstr "A instância do container de DI geralmente **não deve** ser injetada como dependência. Prefira interfaces concretas." #. type: Bullet: '- ' #: ../src/cookbook/organizing-code/service.md msgid "In case of complicated or \"heavy\" initialization, try to postpone it until the service method is called." -msgstr "" +msgstr "Em caso de inicialização complicada ou \"pesada\", tente adiá-la até que o método do serviço seja chamado." #. type: Plain text #: ../src/cookbook/organizing-code/service.md msgid "The same is valid for configuration values. They should be provided as a constructor argument. Related values could be grouped together into value objects. For example, database connection usually requires DSN string, username and password. These three could be combined into Dsn class:" -msgstr "" +msgstr "O mesmo vale para valores de configuração. Eles devem ser fornecidos como argumento do construtor. Valores relacionados podem ser agrupados em value objects. Por exemplo, uma conexão com banco de dados geralmente exige a string DSN, o nome de usuário e a senha. Esses três podem ser combinados em uma classe Dsn:" #. type: Fenced code block (php) #: ../src/cookbook/organizing-code/service.md @@ -138,17 +158,35 @@ msgid "" " }\n" "}\n" msgstr "" +"final readonly class Dsn\n" +"{\n" +" public function __construct(\n" +" public string $dsn,\n" +" public string $username,\n" +" public string $password\n" +" )\n" +" {\n" +" if (!$this->isValidDsn($dsn)) {\n" +" throw new \\InvalidArgumentException('DSN provided is not valid.');\n" +" }\n" +" }\n" +" \n" +" private function isValidDsn(string $dsn): bool\n" +" {\n" +" // verifica se o DSN é válido \n" +" }\n" +"}\n" #. type: Title ## #: ../src/cookbook/organizing-code/service.md #, no-wrap msgid "Service methods" -msgstr "" +msgstr "Métodos de serviço" #. type: Plain text #: ../src/cookbook/organizing-code/service.md msgid "Service method usually does something. It could be a simple thing repeated exactly, but usually it depends on the context. For example:" -msgstr "" +msgstr "Um método de serviço geralmente faz alguma coisa. Pode ser algo simples repetido exatamente igual, mas normalmente depende do contexto. Por exemplo:" #. type: Fenced code block (php) #: ../src/cookbook/organizing-code/service.md @@ -168,29 +206,42 @@ msgid "" " }\n" "}\n" msgstr "" +"final readonly class PostPersister\n" +"{\n" +" public function __construct(\n" +" private Storage $db\n" +" )\n" +" {\n" +" }\n" +" \n" +" public function persist(Post $post)\n" +" {\n" +" $this->db->insertOrUpdate('post', $post); \n" +" }\n" +"}\n" #. type: Plain text #: ../src/cookbook/organizing-code/service.md msgid "There's a service that is saving posts into permanent storage such as a database. An object allowing communication with a concrete storage is always the same, so it's injected using constructor while the post saved could vary, so it's passed as a method argument." -msgstr "" +msgstr "Aqui há um serviço que salva posts em um armazenamento permanente, como um banco de dados. O objeto que permite a comunicação com um armazenamento concreto é sempre o mesmo, então é injetado pelo construtor, enquanto o post salvo pode variar, então é passado como argumento do método." #. type: Title ## #: ../src/cookbook/organizing-code/service.md #, no-wrap msgid "Is everything a service?" -msgstr "" +msgstr "Tudo é um serviço?" #. type: Plain text #: ../src/cookbook/organizing-code/service.md msgid "Often it makes sense to choose another class type to place your code into. Check:" -msgstr "" +msgstr "Muitas vezes faz sentido escolher outro tipo de classe para colocar seu código. Confira:" #. type: Bullet: '- ' #: ../src/cookbook/organizing-code/service.md msgid "Widget" -msgstr "" +msgstr "Widget" #. type: Bullet: '- ' #: ../src/cookbook/organizing-code/service.md msgid "[Middleware](middleware.md)" -msgstr "" +msgstr "[Middleware](middleware.md)" diff --git a/_translations/po/pt-BR/cookbook_organizing-code_structuring-by-use-case-with-vertical-slices.md.po b/_translations/po/pt-BR/cookbook_organizing-code_structuring-by-use-case-with-vertical-slices.md.po index 97ef749d..b6ad47ee 100644 --- a/_translations/po/pt-BR/cookbook_organizing-code_structuring-by-use-case-with-vertical-slices.md.po +++ b/_translations/po/pt-BR/cookbook_organizing-code_structuring-by-use-case-with-vertical-slices.md.po @@ -8,60 +8,54 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-10-11 10:37+0000\n" "PO-Revision-Date: 2026-10-11 10:37+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/cookbook/organizing-code/domain.md -#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md -#: ../src/guide/concept/autoloading.md ../src/guide/concept/di-container.md -#: ../src/guide/security/best-practices.md -#: ../src/guide/tutorial/console-applications.md -#: ../src/internals/004-namespaces.md ../src/internals/007-exceptions.md -#: ../src/internals/008-interfaces.md +#: ../src/cookbook/organizing-code/domain.md ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md ../src/guide/concept/autoloading.md ../src/guide/concept/di-container.md ../src/guide/security/best-practices.md ../src/guide/tutorial/console-applications.md ../src/internals/004-namespaces.md ../src/internals/007-exceptions.md ../src/internals/008-interfaces.md #, no-wrap msgid "References" -msgstr "" +msgstr "Referências" #. type: Title # #: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md #, no-wrap msgid "Structuring code by use-case with vertical slices" -msgstr "" +msgstr "Estruturando o código por caso de uso com vertical slices" #. type: Plain text #: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md msgid "When building an application, it's important to organize the code in a way that makes it easy to understand, support, and scale. One popular approach is to structure the code by use-case with vertical slices." -msgstr "" +msgstr "Ao construir uma aplicação, é importante organizar o código de forma que ele seja fácil de entender, manter e escalar. Uma abordagem popular é estruturar o código por caso de uso com vertical slices." #. type: Plain text #: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md msgid "Vertical slices are self-contained pieces of functionality that cover the entire stack, from the user interface to the data access layer. Developer organizes each slice around a specific use case, such as creating a new user or updating a product." -msgstr "" +msgstr "Vertical slices são partes autocontidas de funcionalidade que cobrem toda a stack, da interface do usuário à camada de acesso a dados. O desenvolvedor organiza cada slice em torno de um caso de uso específico, como criar um novo usuário ou atualizar um produto." #. type: Plain text #: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md msgid "When structuring code classically by type (such as models, views, controllers, helpers, etc.), it can be easy to lose sight of the bigger picture and how different pieces of code interact to support specific features or use cases. This can lead to code duplication, tight coupling, and poor maintainability as the application grows." -msgstr "" +msgstr "Ao estruturar o código da forma clássica, por tipo (models, views, controllers, helpers etc.), é fácil perder de vista o quadro geral e como as diferentes partes do código interagem para atender funcionalidades ou casos de uso específicos. Isso pode levar a duplicação de código, acoplamento forte e manutenção difícil à medida que a aplicação cresce." #. type: Plain text #: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md msgid "On the other hand, structuring code by use-case makes developers focus on a specific feature or workflow and understand how different pieces of code work together to support that feature. This approach also helps to keep related code together in a single directory, making it easier to navigate and support. Vertical slicing also encourages the use of domain-driven design concepts, such as entities, repositories, and services, which can help to promote good separation of concerns and modularity." -msgstr "" +msgstr "Por outro lado, estruturar o código por caso de uso faz os desenvolvedores focarem em uma funcionalidade ou fluxo específico e entenderem como as diferentes partes do código trabalham juntas para atendê-lo. Essa abordagem também ajuda a manter o código relacionado junto, em um único diretório, o que facilita a navegação e a manutenção. O vertical slicing também incentiva o uso de conceitos de domain-driven design, como entidades, repositórios e serviços, que ajudam a promover uma boa separação de responsabilidades e modularidade." #. type: Plain text #: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md msgid "Additionally, structuring code by use-case can make it easier to test and debug the application since use-case namespace encapsulates each feature or workflow in its own directory with clear boundaries and well-defined interfaces." -msgstr "" +msgstr "Além disso, estruturar o código por caso de uso pode facilitar os testes e o debug da aplicação, já que o namespace do caso de uso encapsula cada funcionalidade ou fluxo em seu próprio diretório, com limites claros e interfaces bem definidas." #. type: Plain text #: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md msgid "Here's an example directory structure for a PHP application organized using vertical slices:" -msgstr "" +msgstr "Veja um exemplo de estrutura de diretórios de uma aplicação PHP organizada com vertical slices:" #. type: Fenced code block #: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md @@ -102,18 +96,52 @@ msgid "" " │ │ ├── RssAction.php\n" " | | ├── RssBuilder.php\n" msgstr "" +"src/\n" +"└── Blog/\n" +" ├── Model/\n" +" │ ├── Comment.php\n" +" │ ├── CommentRepository.php\n" +" │ ├── Post.php\n" +" │ └── PostRepository.php\n" +" ├── Service/ \n" +" │ └── MarkdownProcessor.php\n" +" ├── UseCase/\n" +" │ ├── CreateComment/\n" +" │ │ ├── CreateCommentAction.php\n" +" │ │ ├── CreateCommentRequest.php\n" +" │ ├── CreatePost/\n" +" │ │ ├── CreatePostAction.php\n" +" │ │ ├── CreatePostRequest.php\n" +" │ ├── DeleteComment/\n" +" │ │ ├── DeleteCommentAction.php\n" +" │ │ ├── DeleteCommentRequest.php\n" +" │ ├── DeletePost/\n" +" │ │ ├── DeletePostAction.php\n" +" │ │ ├── DeletePostRequest.php\n" +" │ ├── ListComments/\n" +" │ │ ├── ListCommentsAction.php\n" +" │ ├── ListPosts/\n" +" │ │ ├── ListPostsAction.php\n" +" │ ├── UpdatePost/\n" +" │ │ ├── UpdatePostAction.php\n" +" │ │ ├── UpdatePostRequest.php\n" +" │ ├── ViewPost/\n" +" │ │ ├── ViewPostAction.php\n" +" │ ├── Rss/\n" +" │ │ ├── RssAction.php\n" +" | | ├── RssBuilder.php\n" #. type: Plain text #: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md msgid "Each vertical slice has its own directory, which has code associated with the use case." -msgstr "" +msgstr "Cada vertical slice tem seu próprio diretório, que contém o código associado ao caso de uso." #. type: Plain text #: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md msgid "The use-case subdirectories and their respective classes are organized by type within each directory, omitting a directory if there's a single class of the type. If code is shared between multiple use-cases, it's moved one level up such as `Model` or `Service`." -msgstr "" +msgstr "Os subdiretórios de caso de uso e suas respectivas classes são organizados por tipo dentro de cada diretório, omitindo o diretório quando há uma única classe daquele tipo. Se um código é compartilhado entre vários casos de uso, ele sobe um nível, como em `Model` ou `Service`." #. type: Bullet: '- ' #: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md msgid "[Application structure overview](../../guide/structure/overview.md)" -msgstr "" +msgstr "[Visão geral da estrutura da aplicação](../../guide/structure/overview.md)" diff --git a/_translations/po/pt-BR/cookbook_preface.md.po b/_translations/po/pt-BR/cookbook_preface.md.po index a761945f..603b8c24 100644 --- a/_translations/po/pt-BR/cookbook_preface.md.po +++ b/_translations/po/pt-BR/cookbook_preface.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2025-12-24 08:02+0000\n" "PO-Revision-Date: 2025-12-24 08:02+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,13 +19,13 @@ msgstr "" #: ../src/en/cookbook/deployment/docker-swarm.md ../src/en/cookbook/preface.md #, no-wrap msgid "Prerequisites" -msgstr "" +msgstr "Pré-requisitos" #. type: Title # #: ../src/en/cookbook/preface.md #, no-wrap msgid "Preface" -msgstr "" +msgstr "Prefácio" #. type: Plain text #: ../src/en/cookbook/preface.md ../src/en/guide/intro/what-is-yii.md @@ -40,41 +40,41 @@ msgstr "O Yii é um framework genérico de programação web. Você pode usá-l #. type: Plain text #: ../src/en/cookbook/preface.md msgid "With comprehensive documentation and an enthusiastic user community, Yii can significantly reduce your development time in the long run." -msgstr "" +msgstr "Com uma documentação abrangente e uma comunidade de usuários entusiasmada, o Yii pode reduzir bastante o seu tempo de desenvolvimento a longo prazo." #. type: Title ## #: ../src/en/cookbook/preface.md #, no-wrap msgid "What's the book about" -msgstr "" +msgstr "Sobre o que é este livro" #. type: Plain text #: ../src/en/cookbook/preface.md msgid "This book is for you if you're familiar with Yii3, building Yii applications, and read the official Yii3 guide. It covers fundamentally important development concepts, application architecture approaches, integrating third party services with Yii3, etc." -msgstr "" +msgstr "Este livro é para você se já conhece o Yii3, constrói aplicações Yii e leu o guia oficial do Yii3. Ele cobre conceitos de desenvolvimento fundamentais, abordagens de arquitetura de aplicações, integração de serviços de terceiros com o Yii3 etc." #. type: Plain text #: ../src/en/cookbook/preface.md msgid "The book consists of individual recipes gathered from Yii experts that you can apply in your applications. These go by topic, but you are free to read them in any order as there is no dependency between them." -msgstr "" +msgstr "O livro é formado por receitas individuais reunidas por especialistas em Yii, que você pode aplicar nas suas aplicações. Elas são organizadas por tema, mas você pode lê-las em qualquer ordem, já que não há dependência entre elas." #. type: Bullet: '- ' #: ../src/en/cookbook/preface.md msgid "You should have Yii3 installed." -msgstr "" +msgstr "Você deve ter o Yii3 instalado." #. type: Bullet: '- ' #: ../src/en/cookbook/preface.md msgid "You should be familiar with the framework basics and the official guide." -msgstr "" +msgstr "Você deve conhecer o básico do framework e o guia oficial." #. type: Title ## #: ../src/en/cookbook/preface.md #, no-wrap msgid "How to participate" -msgstr "" +msgstr "Como participar" #. type: Plain text #: ../src/en/cookbook/preface.md msgid "If you've found any errata, wrong information, want to improve something or have a good recipe, create an issue or make a pull request in [the book GitHub repository](https://github.com/yiisoft/docs)." -msgstr "" +msgstr "Se você encontrou alguma errata ou informação errada, quer melhorar algo ou tem uma boa receita, crie uma issue ou abra um pull request no [repositório do livro no GitHub](https://github.com/yiisoft/docs)." diff --git a/_translations/po/pt-BR/cookbook_sentry-integration.md.po b/_translations/po/pt-BR/cookbook_sentry-integration.md.po index 7d7bed24..6c7e3e18 100644 --- a/_translations/po/pt-BR/cookbook_sentry-integration.md.po +++ b/_translations/po/pt-BR/cookbook_sentry-integration.md.po @@ -8,35 +8,30 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2025-12-24 08:02+0000\n" "PO-Revision-Date: 2025-12-24 08:02+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/en/cookbook/making-http-requests.md -#: ../src/en/cookbook/sentry-integration.md -#: ../src/en/guide/tutorial/using-yii-with-roadrunner.md -#: ../src/en/guide/tutorial/using-yii-with-swoole.md -#: ../src/en/guide/views/asset.md ../src/en/guide/views/view.md -#: ../src/en/guide/views/widget.md +#: ../src/en/cookbook/making-http-requests.md ../src/en/cookbook/sentry-integration.md ../src/en/guide/tutorial/using-yii-with-roadrunner.md ../src/en/guide/tutorial/using-yii-with-swoole.md ../src/en/guide/views/asset.md ../src/en/guide/views/view.md ../src/en/guide/views/widget.md #, no-wrap msgid "Installation" -msgstr "" +msgstr "Instalação" #. type: Title # #: ../src/en/cookbook/sentry-integration.md #, no-wrap msgid "Sentry integration" -msgstr "" +msgstr "Integração com o Sentry" #. type: Title ## #: ../src/en/cookbook/sentry-integration.md #, no-wrap msgid "What is Sentry" -msgstr "" +msgstr "O que é o Sentry" #. type: Plain text #: ../src/en/cookbook/sentry-integration.md @@ -45,91 +40,90 @@ msgid "" "[Sentry](https://sentry.io/) is a tool for monitoring and debugging application stability and performance.\n" "Sentry gives you access to the events that you send there from your application.\n" msgstr "" +"O [Sentry](https://sentry.io/) é uma ferramenta para monitorar e depurar a estabilidade e o desempenho de aplicações.\n" +"O Sentry dá acesso aos eventos que você envia para ele a partir da sua aplicação.\n" #. type: Plain text #: ../src/en/cookbook/sentry-integration.md msgid "Most often, Sentry is used for monitoring errors (exceptions). You can enrich errors with context to better understand the problem: - Request arguments - Tags for grouping exceptions - Environment state: environment variables, application state, and other global attributes" -msgstr "" +msgstr "Na maioria das vezes, o Sentry é usado para monitorar erros (exceções). Você pode enriquecer os erros com contexto para entender melhor o problema: - Argumentos da requisição - Tags para agrupar exceções - Estado do ambiente: variáveis de ambiente, estado da aplicação e outros atributos globais" #. type: Plain text #: ../src/en/cookbook/sentry-integration.md msgid "You can find the full list of features on the official website: https://sentry.io/welcome/" -msgstr "" +msgstr "Você encontra a lista completa de funcionalidades no site oficial: https://sentry.io/welcome/" #. type: Title ### #: ../src/en/cookbook/sentry-integration.md #, no-wrap msgid "Install the package" -msgstr "" +msgstr "Instale o pacote" #. type: Plain text #: ../src/en/cookbook/sentry-integration.md msgid "Install the required package `yiisoft/yii-sentry` with the following command:" -msgstr "" +msgstr "Instale o pacote necessário `yiisoft/yii-sentry` com o seguinte comando:" #. type: Fenced code block (shell) #: ../src/en/cookbook/sentry-integration.md #, no-wrap msgid "composer require yiisoft/yii-sentry --prefer-dist\n" -msgstr "" +msgstr "composer require yiisoft/yii-sentry --prefer-dist\n" #. type: Title ### #: ../src/en/cookbook/sentry-integration.md #, no-wrap msgid "Install an HTTP driver" -msgstr "" +msgstr "Instale um driver HTTP" #. type: Plain text #: ../src/en/cookbook/sentry-integration.md msgid "The [`getsentry/sentry-php`](https://github.com/getsentry/sentry-php) library requires the `php-http/httplug` package and any HTTP driver. In the example below we’ll use the Guzzle adapter." -msgstr "" +msgstr "A biblioteca [`getsentry/sentry-php`](https://github.com/getsentry/sentry-php) exige o pacote `php-http/httplug` e algum driver HTTP. No exemplo abaixo, vamos usar o adaptador do Guzzle." #. type: Plain text #: ../src/en/cookbook/sentry-integration.md #, no-wrap msgid "> You can find the list of all adapters on [this page](https://docs.php-http.org/en/latest/clients.html#clients-adapters).\n" -msgstr "" +msgstr "> Você encontra a lista de todos os adaptadores [nesta página](https://docs.php-http.org/en/latest/clients.html#clients-adapters).\n" #. type: Plain text #: ../src/en/cookbook/sentry-integration.md msgid "To install the packages, run the following command:" -msgstr "" +msgstr "Para instalar os pacotes, execute o seguinte comando:" #. type: Fenced code block (shell) #: ../src/en/cookbook/sentry-integration.md #, no-wrap msgid "composer require php-http/httplug php-http/guzzle7-adapter --prefer-dist\n" -msgstr "" +msgstr "composer require php-http/httplug php-http/guzzle7-adapter --prefer-dist\n" #. type: Title ## -#: ../src/en/cookbook/sentry-integration.md -#: ../src/en/guide/concept/configuration.md -#: ../src/en/guide/tutorial/using-yii-with-roadrunner.md -#: ../src/en/guide/views/view-injections.md +#: ../src/en/cookbook/sentry-integration.md ../src/en/guide/concept/configuration.md ../src/en/guide/tutorial/using-yii-with-roadrunner.md ../src/en/guide/views/view-injections.md #, no-wrap msgid "Configuration" -msgstr "" +msgstr "Configuração" #. type: Title ### #: ../src/en/cookbook/sentry-integration.md #, no-wrap msgid "Get and store the token" -msgstr "" +msgstr "Obtenha e guarde o token" #. type: Plain text #: ../src/en/cookbook/sentry-integration.md msgid "Next, configure the application." -msgstr "" +msgstr "Em seguida, configure a aplicação." #. type: Plain text #: ../src/en/cookbook/sentry-integration.md msgid "First, register at [Sentry](https://sentry.io) and create a project." -msgstr "" +msgstr "Primeiro, cadastre-se no [Sentry](https://sentry.io) e crie um projeto." #. type: Plain text #: ../src/en/cookbook/sentry-integration.md msgid "Then, in the project settings on the “General Settings” tab, find the “Security Token” field and copy its value." -msgstr "" +msgstr "Depois, nas configurações do projeto, na aba “General Settings”, encontre o campo “Security Token” e copie o valor dele." #. type: Plain text #: ../src/en/cookbook/sentry-integration.md @@ -138,6 +132,8 @@ msgid "" "Now put this token into the package configuration. By default, the config is located at `config/packages/yiisoft/yii-sentry/config/params.php`.\n" "Set the copied token as the value of the array element at `yiisoft/yii-sentry` => `options` => `dsn`. Example:\n" msgstr "" +"Agora coloque esse token na configuração do pacote. Por padrão, a configuração fica em `config/packages/yiisoft/yii-sentry/config/params.php`.\n" +"Defina o token copiado como valor do elemento do array em `yiisoft/yii-sentry` => `options` => `dsn`. Exemplo:\n" #. type: Fenced code block (diff) #: ../src/en/cookbook/sentry-integration.md @@ -151,22 +147,29 @@ msgid "" " ],\n" "],\n" msgstr "" +"'yiisoft/yii-sentry' => [\n" +" 'enabled' => true,\n" +" 'options' => [\n" +"- 'dsn' => '',\n" +"+ 'dsn' => 'TOKEN',\n" +" ],\n" +"],\n" #. type: Title ### #: ../src/en/cookbook/sentry-integration.md #, no-wrap msgid "Configure the HTTP client" -msgstr "" +msgstr "Configure o cliente HTTP" #. type: Plain text #: ../src/en/cookbook/sentry-integration.md msgid "After installing the HTTP client, configure it." -msgstr "" +msgstr "Depois de instalar o cliente HTTP, configure-o." #. type: Plain text #: ../src/en/cookbook/sentry-integration.md msgid "Create the file `config/common/sentry.php` and put the following code into it:" -msgstr "" +msgstr "Crie o arquivo `config/common/sentry.php` e coloque nele o seguinte código:" #. type: Fenced code block (php) #: ../src/en/cookbook/sentry-integration.md @@ -186,28 +189,41 @@ msgid "" " ],\n" "];\n" msgstr "" +" \\GuzzleHttp\\Client::class,\n" +" \\Http\\Client\\HttpAsyncClient::class => [\n" +" 'class' => \\Http\\Adapter\\Guzzle7\\Client::class,\n" +" '__construct()' => [\n" +" \\Yiisoft\\Factory\\Definition\\Reference::to(\\Http\\Client\\HttpClient::class),\n" +" ],\n" +" ],\n" +"];\n" #. type: Title # #: ../src/en/cookbook/sentry-integration.md #, no-wrap msgid "Integration" -msgstr "" +msgstr "Integração" #. type: Title ### #: ../src/en/cookbook/sentry-integration.md #, no-wrap msgid "Web" -msgstr "" +msgstr "Web" #. type: Plain text #: ../src/en/cookbook/sentry-integration.md msgid "Sentry support for `web` is implemented as middleware." -msgstr "" +msgstr "O suporte do Sentry para `web` é implementado como middleware." #. type: Plain text #: ../src/en/cookbook/sentry-integration.md msgid "That means you only need to add `SentryMiddleware` to the global middleware list in `config/web/application.php`:" -msgstr "" +msgstr "Isso significa que você só precisa adicionar o `SentryMiddleware` à lista global de middlewares em `config/web/application.php`:" #. type: Fenced code block (diff) #: ../src/en/cookbook/sentry-integration.md @@ -232,19 +248,37 @@ msgid "" " ],\n" "];\n" msgstr "" +"return [\n" +" Yiisoft\\Yii\\Web\\Application::class => [\n" +" '__construct()' => [\n" +" 'dispatcher' => DynamicReference::to(static function (Injector $injector) {\n" +" return ($injector->make(MiddlewareDispatcher::class))\n" +" ->withMiddlewares(\n" +" [\n" +" Router::class,\n" +" SubFolder::class,\n" +"+ SentryMiddleware::class,\n" +" ErrorCatcher::class,\n" +" ]\n" +" );\n" +" }),\n" +" 'fallbackHandler' => Reference::to(NotFoundHandler::class),\n" +" ],\n" +" ],\n" +"];\n" #. type: Title ## #: ../src/en/cookbook/sentry-integration.md ../src/en/internals/003-roadmap.md #, no-wrap msgid "Console" -msgstr "" +msgstr "Console" #. type: Plain text #: ../src/en/cookbook/sentry-integration.md msgid "Sentry supports `console` via a handler for the [ConsoleEvents::ERROR](https://symfony.com/doc/current/components/console/events.html#the-consoleevents-error-event) event." -msgstr "" +msgstr "O Sentry suporta o `console` por meio de um handler para o evento [ConsoleEvents::ERROR](https://symfony.com/doc/current/components/console/events.html#the-consoleevents-error-event)." #. type: Plain text #: ../src/en/cookbook/sentry-integration.md msgid "The package provides a configuration file that automatically subscribes the application to this event." -msgstr "" +msgstr "O pacote fornece um arquivo de configuração que inscreve a aplicação nesse evento automaticamente." diff --git a/_translations/po/pt-BR/cookbook_third-party-integrations_index.md.po b/_translations/po/pt-BR/cookbook_third-party-integrations_index.md.po index 7a826276..c2531abe 100644 --- a/_translations/po/pt-BR/cookbook_third-party-integrations_index.md.po +++ b/_translations/po/pt-BR/cookbook_third-party-integrations_index.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-10-07 20:23+0000\n" "PO-Revision-Date: 2026-10-07 20:23+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -29,24 +29,24 @@ msgstr "Fique à vontade para enviar seus próprios textos via pull request. Os #: ../src/cookbook/third-party-integrations/index.md #, no-wrap msgid "Third-Party Integrations" -msgstr "" +msgstr "Integrações de terceiros" #. type: Plain text #: ../src/cookbook/third-party-integrations/index.md msgid "This is a collection of community-contributed guides for integrating third-party packages with Yii3." -msgstr "" +msgstr "Esta é uma coleção de guias, contribuídos pela comunidade, para integrar pacotes de terceiros com o Yii3." #. type: Bullet: '- ' #: ../src/cookbook/third-party-integrations/index.md msgid "The Yii community creates the guides." -msgstr "" +msgstr "Os guias são criados pela comunidade Yii." #. type: Bullet: '- ' #: ../src/cookbook/third-party-integrations/index.md msgid "[Symfony Messenger integration guide](symfony-messenger-integration-guide.md)" -msgstr "" +msgstr "[Guia de integração com o Symfony Messenger](symfony-messenger-integration-guide.md)" #. type: Bullet: '- ' #: ../src/cookbook/third-party-integrations/index.md msgid "[Symfony Scheduler integration guide](symfony-scheduler-integration-guide.md)" -msgstr "" +msgstr "[Guia de integração com o Symfony Scheduler](symfony-scheduler-integration-guide.md)" diff --git a/_translations/po/pt-BR/cookbook_third-party-integrations_symfony-messenger-integration-guide.md.po b/_translations/po/pt-BR/cookbook_third-party-integrations_symfony-messenger-integration-guide.md.po index b2f94256..31313d57 100644 --- a/_translations/po/pt-BR/cookbook_third-party-integrations_symfony-messenger-integration-guide.md.po +++ b/_translations/po/pt-BR/cookbook_third-party-integrations_symfony-messenger-integration-guide.md.po @@ -8,53 +8,47 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-09-25 14:35+0000\n" "PO-Revision-Date: 2026-09-25 14:35+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/cookbook/making-http-requests.md -#: ../src/cookbook/sentry-integration.md -#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md -#: ../src/guide/tutorial/using-yii-with-frankenphp.md -#: ../src/guide/tutorial/using-yii-with-roadrunner.md -#: ../src/guide/tutorial/using-yii-with-swoole.md ../src/guide/views/asset.md -#: ../src/guide/views/view.md ../src/guide/views/widget.md +#: ../src/cookbook/making-http-requests.md ../src/cookbook/sentry-integration.md ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md ../src/guide/tutorial/using-yii-with-frankenphp.md ../src/guide/tutorial/using-yii-with-roadrunner.md ../src/guide/tutorial/using-yii-with-swoole.md ../src/guide/views/asset.md ../src/guide/views/view.md ../src/guide/views/widget.md #, no-wrap msgid "Installation" -msgstr "" +msgstr "Instalação" #. type: Title # #: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md #, no-wrap msgid "Symfony Messenger integration guide" -msgstr "" +msgstr "Guia de integração com o Symfony Messenger" #. type: Plain text #: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md msgid "The [Symfony Messenger](https://symfony.com/doc/current/components/messenger.html) component helps applications send and receive messages to/from other applications or via message queues." -msgstr "" +msgstr "O componente [Symfony Messenger](https://symfony.com/doc/current/components/messenger.html) ajuda as aplicações a enviar e receber mensagens de/para outras aplicações ou por meio de filas de mensagens." #. type: Fenced code block (shell) #: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md #, no-wrap msgid "composer require symfony/messenger\n" -msgstr "" +msgstr "composer require symfony/messenger\n" #. type: Title ## #: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md #, no-wrap msgid "How to use with Yii" -msgstr "" +msgstr "Como usar com o Yii" #. type: Title ### #: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md #, no-wrap msgid "1. Create a Message and Handler." -msgstr "" +msgstr "1. Crie uma Message e um Handler." #. type: Fenced code block (php) #: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md @@ -69,6 +63,14 @@ msgid "" " }\n" "}\n" msgstr "" +"namespace App\\Messages;\n" +"\n" +"final readonly class MyMessage\n" +"{\n" +" public function __construct(public string $content)\n" +" {\n" +" }\n" +"}\n" #. type: Fenced code block (php) #: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md @@ -90,17 +92,32 @@ msgid "" " }\n" "}\n" msgstr "" +"namespace App\\Messages;\n" +"\n" +"use Psr\\Log\\LoggerInterface;\n" +"\n" +"final readonly class MyMessageHandler\n" +"{\n" +" public function __construct(private LoggerInterface $logger)\n" +" {\n" +" }\n" +" public function __invoke(MyMessage $message): void\n" +" {\n" +" // ...\n" +" $this->logger->info(\"The message with the content '$message->content' has been received.\");\n" +" }\n" +"}\n" #. type: Title ### #: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md #, no-wrap msgid "2. Implement the ServiceProviderInterface." -msgstr "" +msgstr "2. Implemente a ServiceProviderInterface." #. type: Plain text #: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md msgid "This instance of the ServiceProviderInterface is used to configure certain Symfony Messenger commands." -msgstr "" +msgstr "Essa instância da ServiceProviderInterface é usada para configurar alguns comandos do Symfony Messenger." #. type: Fenced code block (php) #: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md @@ -145,22 +162,60 @@ msgid "" " }\n" "}\n" msgstr "" +"namespace App\\Services;\n" +"\n" +"use Psr\\Container\\ContainerInterface;\n" +"use Symfony\\Contracts\\Service\\ServiceProviderInterface;\n" +"\n" +"final readonly class ServiceProvider implements ServiceProviderInterface\n" +"{\n" +" /**\n" +" * @param ContainerInterface $container\n" +" * @param array $serviceMap\n" +" */\n" +" public function __construct(\n" +" private ContainerInterface $container,\n" +" private array $serviceMap)\n" +" {\n" +" }\n" +"\n" +" /**\n" +" * @inheritDoc\n" +" */\n" +" public function get(string $id): mixed\n" +" {\n" +" return $this->container->get($id);\n" +" }\n" +"\n" +" public function has(string $id): bool\n" +" {\n" +" return $this->container->has($id);\n" +" }\n" +"\n" +" /**\n" +" * @inheritDoc\n" +" */\n" +" public function getProvidedServices(): array\n" +" {\n" +" return $this->serviceMap;\n" +" }\n" +"}\n" #. type: Title ### #: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md #, no-wrap msgid "3. Configure the Symfony Messenger." -msgstr "" +msgstr "3. Configure o Symfony Messenger." #. type: Plain text #: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md msgid "Example uses the [symfony/doctrine-messenger](https://packagist.org/packages/symfony/doctrine-messenger) package for transport:" -msgstr "" +msgstr "O exemplo usa o pacote [symfony/doctrine-messenger](https://packagist.org/packages/symfony/doctrine-messenger) como transporte:" #. type: Plain text #: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md msgid "Add the Doctrine packages to the `composer.json`:" -msgstr "" +msgstr "Adicione os pacotes do Doctrine ao `composer.json`:" #. type: Fenced code block (json) #: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md @@ -176,22 +231,31 @@ msgid "" " },\n" "}\n" msgstr "" +"{\n" +" // ...\n" +" \"require\": {\n" +" // ...\n" +" \"doctrine/orm\": \"^3\",\n" +" \"doctrine/dbal\": \"^4\",\n" +" \"symfony/cache\": \"^7\"\n" +" },\n" +"}\n" #. type: Plain text #: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md msgid "Install Doctrine:" -msgstr "" +msgstr "Instale o Doctrine:" #. type: Fenced code block (shell) #: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md #, no-wrap msgid "composer install\n" -msgstr "" +msgstr "composer install\n" #. type: Plain text #: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md msgid "Configure the Doctrine connection in the `config/common/params.php`:" -msgstr "" +msgstr "Configure a conexão do Doctrine em `config/common/params.php`:" #. type: Fenced code block (php) #: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md @@ -212,22 +276,36 @@ msgid "" " ],\n" "];\n" msgstr "" +"return [\n" +" // ...\n" +" 'doctrine' => [\n" +" 'paths' => [\n" +" ],\n" +" 'isDevMode' => false,\n" +" 'connection' => [\n" +" 'driver' => 'pdo_mysql',\n" +" 'user' => 'site1',\n" +" 'password' => 'secret',\n" +" 'dbname' => 'site3'\n" +" ]\n" +" ],\n" +"];\n" #. type: Plain text #: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md msgid "Install the Symfony Doctrine Messenger package:" -msgstr "" +msgstr "Instale o pacote Symfony Doctrine Messenger:" #. type: Fenced code block (shell) #: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md #, no-wrap msgid "composer require symfony/doctrine-messenger\n" -msgstr "" +msgstr "composer require symfony/doctrine-messenger\n" #. type: Plain text #: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md msgid "Configure the Doctrine and Symfony Messenger dependencies in the `config/common/di/application.php`:" -msgstr "" +msgstr "Configure as dependências do Doctrine e do Symfony Messenger em `config/common/di/application.php`:" #. type: Fenced code block (php) #: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md @@ -387,17 +465,170 @@ msgid "" " },\n" "];\n" msgstr "" +"use App\\Messages\\MyMessage;\n" +"use App\\Messages\\MyMessageHandler;\n" +"use App\\Services\\ServiceProvider;\n" +"use Doctrine\\DBAL\\DriverManager;\n" +"use Doctrine\\ORM\\Configuration;\n" +"use Doctrine\\ORM\\EntityManager;\n" +"use Doctrine\\ORM\\EntityManagerInterface;\n" +"use Doctrine\\ORM\\ORMSetup;\n" +"use Doctrine\\ORM\\Proxy\\ProxyFactory;\n" +"use Doctrine\\ORM\\Tools\\Console\\EntityManagerProvider;\n" +"use Doctrine\\ORM\\Tools\\Console\\EntityManagerProvider\\SingleManagerProvider;\n" +"use Psr\\Cache\\CacheItemPoolInterface;\n" +"use Psr\\Container\\ContainerInterface;\n" +"use Psr\\Log\\LoggerInterface;\n" +"use Symfony\\Component\\Cache\\Adapter\\FilesystemAdapter;\n" +"use Symfony\\Component\\EventDispatcher\\EventDispatcher;\n" +"use Symfony\\Component\\EventDispatcher\\EventDispatcherInterface;\n" +"use Symfony\\Component\\Messenger\\Bridge\\Doctrine\\Transport\\Connection;\n" +"use Symfony\\Component\\Messenger\\Bridge\\Doctrine\\Transport\\DoctrineTransport;\n" +"use Symfony\\Component\\Messenger\\Command\\ConsumeMessagesCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\DebugCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\FailedMessagesRemoveCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\FailedMessagesRetryCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\FailedMessagesShowCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\SetupTransportsCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\StatsCommand;\n" +"use Symfony\\Component\\Messenger\\EventListener\\StopWorkerOnRestartSignalListener;\n" +"use Symfony\\Component\\Messenger\\Handler\\HandlersLocator;\n" +"use Symfony\\Component\\Messenger\\MessageBus;\n" +"use Symfony\\Component\\Messenger\\Middleware\\HandleMessageMiddleware;\n" +"use Symfony\\Component\\Messenger\\Middleware\\SendMessageMiddleware;\n" +"use Symfony\\Component\\Messenger\\RoutableMessageBus;\n" +"use Symfony\\Component\\Messenger\\Transport\\Sender\\SendersLocator;\n" +"use Symfony\\Component\\Messenger\\Transport\\Serialization\\PhpSerializer;\n" +"use Symfony\\Component\\Messenger\\Transport\\Serialization\\SerializerInterface;\n" +"use Symfony\\Contracts\\Service\\ServiceProviderInterface;\n" +"use Yiisoft\\Aliases\\Aliases;\n" +"use Yiisoft\\Definitions\\Reference;\n" +"\n" +"class_alias(MessageBus::class, 'MyMessageBus');\n" +"\n" +"return [\n" +" // ...\n" +" CacheItemPoolInterface::class => static function (ContainerInterface $container) {\n" +" return new FilesystemAdapter(directory: $container->get(Aliases::class)->get('@runtime'));\n" +" }, //One of the following adapters can be used instead: Psr16Adapter, RedisAdapter, MemcachedAdapter, DoctrineDbalAdapter, and so forth.\n" +"\n" +" Configuration::class => static function (ContainerInterface $container) use ($params) {\n" +" $config = ORMSetup::createAttributeMetadataConfiguration( // on PHP >= 8.4, use ORMSetup::createAttributeMetadataConfig()\n" +" paths: $params['doctrine']['paths'],\n" +" isDevMode: $params['doctrine']['isDevMode'],\n" +" cache: $container->get(CacheItemPoolInterface::class));\n" +" $config->setAutoGenerateProxyClasses(ProxyFactory::AUTOGENERATE_FILE_NOT_EXISTS_OR_CHANGED);\n" +" return $config;\n" +" },\n" +"\n" +" EntityManagerInterface::class => static function (ContainerInterface $container) use ($params) {\n" +" $configuration = $container->get(Configuration::class);\n" +" return new EntityManager(\n" +" DriverManager::getConnection(\n" +" $params['doctrine']['connection'],\n" +" $configuration\n" +" ),\n" +" $configuration);\n" +" },\n" +" EntityManagerProvider::class => SingleManagerProvider::class,\n" +"\n" +" SerializerInterface::class => PhpSerializer::class,\n" +" 'DoctrineTransport' => static function (ContainerInterface $container) use ($params) {\n" +" $configuration = $container->get(Configuration::class);\n" +" $connection = new Connection([], DriverManager::getConnection(\n" +" $params['doctrine']['connection'],\n" +" $configuration\n" +" ));\n" +" return new DoctrineTransport($connection, $container->get(SerializerInterface::class));\n" +" },\n" +"\n" +" MyMessageBus::class => static function (ContainerInterface $container) {\n" +" return new MyMessageBus([\n" +" new SendMessageMiddleware(sendersLocator: new SendersLocator([\n" +" MyMessage::class => ['DoctrineTransport']\n" +" ], $container)),\n" +" new HandleMessageMiddleware(new HandlersLocator([\n" +" MyMessage::class => [$container->get(MyMessageHandler::class)]\n" +" ])),\n" +" ]);\n" +" },\n" +"\n" +" EventDispatcherInterface::class => static function (ContainerInterface $container) {\n" +" $eventDispatcher = new EventDispatcher();\n" +" $eventDispatcher->addSubscriber($container->get(StopWorkerOnRestartSignalListener::class));\n" +" return $eventDispatcher;\n" +" },\n" +" ServiceProviderInterface::class => [\n" +" 'class' => ServiceProvider::class,\n" +" '__construct()' => [\n" +" 'container' => Reference::to(ContainerInterface::class),\n" +" 'serviceMap' => [\n" +" 'DoctrineTransport' => DoctrineTransport::class\n" +" ]\n" +" ],\n" +" ],\n" +"\n" +" ConsumeMessagesCommand::class => static function (ContainerInterface $container) {\n" +" return new ConsumeMessagesCommand(\n" +" $container->get(RoutableMessageBus::class),\n" +" $container,\n" +" $container->get(EventDispatcherInterface::class),\n" +" $container->get(LoggerInterface::class),\n" +" array_keys($container->get(ServiceProviderInterface::class)->getProvidedServices())\n" +" );\n" +" },\n" +" DebugCommand::class => [\n" +" '__construct()' => [\n" +" 'mapping' => [\n" +" MyMessageBus::class => [Reference::to(MyMessageHandler::class)]\n" +" ]\n" +" ],\n" +" ],\n" +" FailedMessagesRemoveCommand::class => [\n" +" '__construct()' => [\n" +" 'globalFailureReceiverName' => null,\n" +" 'failureTransports' => Reference::to(ServiceProviderInterface::class)\n" +" ],\n" +" ],\n" +" FailedMessagesRetryCommand::class => [\n" +" '__construct()' => [\n" +" 'globalReceiverName' => null,\n" +" 'failureTransports' => Reference::to(ServiceProviderInterface::class),\n" +" 'messageBus' => Reference::to(MyMessageBus::class),\n" +" 'eventDispatcher' => Reference::to(EventDispatcherInterface::class),\n" +" 'logger' => Reference::to(LoggerInterface::class),\n" +" ],\n" +" ],\n" +" FailedMessagesShowCommand::class => [\n" +" '__construct()' => [\n" +" 'globalFailureReceiverName' => null,\n" +" 'failureTransports' => Reference::to(ServiceProviderInterface::class)\n" +" ],\n" +" ],\n" +" SetupTransportsCommand::class => static function (ContainerInterface $container) {\n" +" return new SetupTransportsCommand(\n" +" $container,\n" +" array_keys($container->get(ServiceProviderInterface::class)->getProvidedServices())\n" +" );\n" +" },\n" +" StatsCommand::class => static function (ContainerInterface $container) {\n" +" return new StatsCommand(\n" +" $container,\n" +" array_keys($container->get(ServiceProviderInterface::class)->getProvidedServices())\n" +" );\n" +" },\n" +"];\n" #. type: Title ### #: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md #, no-wrap msgid "4. Integrate the Symfony Messenger commands into the Yii console." -msgstr "" +msgstr "4. Integre os comandos do Symfony Messenger ao console do Yii." #. type: Plain text #: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md msgid "Add the commands to `config/console/commands.php`:" -msgstr "" +msgstr "Adicione os comandos em `config/console/commands.php`:" #. type: Fenced code block (php) #: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md @@ -424,17 +655,37 @@ msgid "" " 'symfony:messenger:stop-workers' => StopWorkersCommand::class\n" "];\n" msgstr "" +"use Symfony\\Component\\Messenger\\Command\\ConsumeMessagesCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\DebugCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\FailedMessagesRemoveCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\FailedMessagesRetryCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\FailedMessagesShowCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\SetupTransportsCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\StatsCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\StopWorkersCommand;\n" +"\n" +"return [\n" +" // ...\n" +" 'symfony:messenger:consume' => ConsumeMessagesCommand::class,\n" +" 'symfony:messenger:debug' => DebugCommand::class,\n" +" 'symfony:messenger:failed:remove' => FailedMessagesRemoveCommand::class,\n" +" 'symfony:messenger:failed:retry' => FailedMessagesRetryCommand::class,\n" +" 'symfony:messenger:failed:show' => FailedMessagesShowCommand::class,\n" +" 'symfony:messenger:setup-transports' => SetupTransportsCommand::class,\n" +" 'symfony:messenger:stats' => StatsCommand::class,\n" +" 'symfony:messenger:stop-workers' => StopWorkersCommand::class\n" +"];\n" #. type: Title ### #: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md #, no-wrap msgid "5. Dispatch a message." -msgstr "" +msgstr "5. Despache uma mensagem." #. type: Plain text #: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md msgid "Example:" -msgstr "" +msgstr "Exemplo:" #. type: Fenced code block (php) #: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md @@ -457,15 +708,31 @@ msgid "" " }\n" "}\n" msgstr "" +"use App\\Messages\\MyMessage;\n" +"use MyMessageBus;\n" +"use Psr\\Http\\Message\\ResponseInterface;\n" +"\n" +"final readonly class MyController\n" +"{\n" +" public function __construct(private MyMessageBus $bus)\n" +" {\n" +" }\n" +" \n" +" public function sendMessage(): ResponseInterface\n" +" {\n" +" $this->bus->dispatch(new MyMessage('Hello Symfony Messenger!'));\n" +" // ...\n" +" }\n" +"}\n" #. type: Title ### #: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md #, no-wrap msgid "6. Consume messages." -msgstr "" +msgstr "6. Consuma as mensagens." #. type: Fenced code block (bash) #: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md #, no-wrap msgid "./yii symfony:messenger:consume DoctrineTransport --bus=MyMessageBus\n" -msgstr "" +msgstr "./yii symfony:messenger:consume DoctrineTransport --bus=MyMessageBus\n" diff --git a/_translations/po/pt-BR/cookbook_third-party-integrations_symfony-scheduler-integration-guide.md.po b/_translations/po/pt-BR/cookbook_third-party-integrations_symfony-scheduler-integration-guide.md.po index 30edcac1..f61ae0a2 100644 --- a/_translations/po/pt-BR/cookbook_third-party-integrations_symfony-scheduler-integration-guide.md.po +++ b/_translations/po/pt-BR/cookbook_third-party-integrations_symfony-scheduler-integration-guide.md.po @@ -8,51 +8,39 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-10-08 12:04+0000\n" "PO-Revision-Date: 2026-10-08 12:04+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/cookbook/making-http-requests.md -#: ../src/cookbook/sentry-integration.md -#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md -#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md -#: ../src/guide/tutorial/using-yii-with-frankenphp.md -#: ../src/guide/tutorial/using-yii-with-rapira.md -#: ../src/guide/tutorial/using-yii-with-roadrunner.md -#: ../src/guide/tutorial/using-yii-with-swoole.md ../src/guide/views/asset.md -#: ../src/guide/views/view.md ../src/guide/views/widget.md +#: ../src/cookbook/making-http-requests.md ../src/cookbook/sentry-integration.md ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md ../src/guide/tutorial/using-yii-with-frankenphp.md ../src/guide/tutorial/using-yii-with-rapira.md ../src/guide/tutorial/using-yii-with-roadrunner.md ../src/guide/tutorial/using-yii-with-swoole.md ../src/guide/views/asset.md ../src/guide/views/view.md ../src/guide/views/widget.md #, no-wrap msgid "Installation" -msgstr "" +msgstr "Instalação" #. type: Fenced code block (shell) -#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md -#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md #, no-wrap msgid "composer require symfony/messenger\n" -msgstr "" +msgstr "composer require symfony/messenger\n" #. type: Title ## -#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md -#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md #, no-wrap msgid "How to use with Yii" -msgstr "" +msgstr "Como usar com o Yii" #. type: Title ### -#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md -#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md #, no-wrap msgid "1. Create a Message and Handler." -msgstr "" +msgstr "1. Crie uma Message e um Handler." #. type: Fenced code block (php) -#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md -#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md #, no-wrap msgid "" "namespace App\\Messages;\n" @@ -64,10 +52,17 @@ msgid "" " }\n" "}\n" msgstr "" +"namespace App\\Messages;\n" +"\n" +"final readonly class MyMessage\n" +"{\n" +" public function __construct(public string $content)\n" +" {\n" +" }\n" +"}\n" #. type: Fenced code block (php) -#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md -#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md #, no-wrap msgid "" "namespace App\\Messages;\n" @@ -86,10 +81,24 @@ msgid "" " }\n" "}\n" msgstr "" +"namespace App\\Messages;\n" +"\n" +"use Psr\\Log\\LoggerInterface;\n" +"\n" +"final readonly class MyMessageHandler\n" +"{\n" +" public function __construct(private LoggerInterface $logger)\n" +" {\n" +" }\n" +" public function __invoke(MyMessage $message): void\n" +" {\n" +" // ...\n" +" $this->logger->info(\"The message with the content '$message->content' has been received.\");\n" +" }\n" +"}\n" #. type: Fenced code block (php) -#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md -#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md #, no-wrap msgid "" "namespace App\\Services;\n" @@ -131,23 +140,58 @@ msgid "" " }\n" "}\n" msgstr "" +"namespace App\\Services;\n" +"\n" +"use Psr\\Container\\ContainerInterface;\n" +"use Symfony\\Contracts\\Service\\ServiceProviderInterface;\n" +"\n" +"final readonly class ServiceProvider implements ServiceProviderInterface\n" +"{\n" +" /**\n" +" * @param ContainerInterface $container\n" +" * @param array $serviceMap\n" +" */\n" +" public function __construct(\n" +" private ContainerInterface $container,\n" +" private array $serviceMap)\n" +" {\n" +" }\n" +"\n" +" /**\n" +" * @inheritDoc\n" +" */\n" +" public function get(string $id): mixed\n" +" {\n" +" return $this->container->get($id);\n" +" }\n" +"\n" +" public function has(string $id): bool\n" +" {\n" +" return $this->container->has($id);\n" +" }\n" +"\n" +" /**\n" +" * @inheritDoc\n" +" */\n" +" public function getProvidedServices(): array\n" +" {\n" +" return $this->serviceMap;\n" +" }\n" +"}\n" #. type: Title ### -#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md -#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md #, no-wrap msgid "4. Integrate the Symfony Messenger commands into the Yii console." -msgstr "" +msgstr "4. Integre os comandos do Symfony Messenger ao console do Yii." #. type: Plain text -#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md -#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md msgid "Add the commands to `config/console/commands.php`:" -msgstr "" +msgstr "Adicione os comandos em `config/console/commands.php`:" #. type: Fenced code block (php) -#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md -#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md #, no-wrap msgid "" "use Symfony\\Component\\Messenger\\Command\\ConsumeMessagesCommand;\n" @@ -171,35 +215,54 @@ msgid "" " 'symfony:messenger:stop-workers' => StopWorkersCommand::class\n" "];\n" msgstr "" +"use Symfony\\Component\\Messenger\\Command\\ConsumeMessagesCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\DebugCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\FailedMessagesRemoveCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\FailedMessagesRetryCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\FailedMessagesShowCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\SetupTransportsCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\StatsCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\StopWorkersCommand;\n" +"\n" +"return [\n" +" // ...\n" +" 'symfony:messenger:consume' => ConsumeMessagesCommand::class,\n" +" 'symfony:messenger:debug' => DebugCommand::class,\n" +" 'symfony:messenger:failed:remove' => FailedMessagesRemoveCommand::class,\n" +" 'symfony:messenger:failed:retry' => FailedMessagesRetryCommand::class,\n" +" 'symfony:messenger:failed:show' => FailedMessagesShowCommand::class,\n" +" 'symfony:messenger:setup-transports' => SetupTransportsCommand::class,\n" +" 'symfony:messenger:stats' => StatsCommand::class,\n" +" 'symfony:messenger:stop-workers' => StopWorkersCommand::class\n" +"];\n" #. type: Plain text -#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md -#: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md +#: ../src/cookbook/third-party-integrations/symfony-messenger-integration-guide.md ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md msgid "Example:" -msgstr "" +msgstr "Exemplo:" #. type: Title # #: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md #, no-wrap msgid "Symfony Scheduler integration guide" -msgstr "" +msgstr "Guia de integração com o Symfony Scheduler" #. type: Plain text #: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md msgid "The [Symfony Scheduler](https://symfony.com/doc/current/scheduler.html) component manages task scheduling within your PHP application, like running a task each night at 3 AM, every two weeks except for holidays or any other custom schedule you might need." -msgstr "" +msgstr "O componente [Symfony Scheduler](https://symfony.com/doc/current/scheduler.html) gerencia o agendamento de tarefas na sua aplicação PHP, como rodar uma tarefa toda noite às 3h, a cada duas semanas exceto em feriados, ou qualquer outro agendamento personalizado de que você precise." #. type: Fenced code block (shell) #: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md #, no-wrap msgid "composer require symfony/scheduler\n" -msgstr "" +msgstr "composer require symfony/scheduler\n" #. type: Title ### #: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md #, no-wrap msgid "2. Attaching Recurring Messages to a Schedule." -msgstr "" +msgstr "2. Associe mensagens recorrentes a um Schedule." #. type: Fenced code block (php) #: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md @@ -225,43 +288,62 @@ msgid "" " }\n" "}\n" msgstr "" +"namespace App\\Scheduler;\n" +"\n" +"use App\\Messages\\MyMessage;\n" +"use Symfony\\Component\\Scheduler\\RecurringMessage;\n" +"use Symfony\\Component\\Scheduler\\Schedule;\n" +"use Symfony\\Component\\Scheduler\\ScheduleProviderInterface;\n" +"\n" +"class MyScheduleProvider implements ScheduleProviderInterface\n" +"{\n" +" public function getSchedule(): Schedule\n" +" {\n" +" return (new Schedule())\n" +" ->with(\n" +" RecurringMessage::every(\n" +" '10 seconds',\n" +" new MyMessage('Hello Symfony Scheduler!'))\n" +" );\n" +" }\n" +"}\n" #. type: Title ### #: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md #, no-wrap msgid "3. Configure the Symfony Scheduler." -msgstr "" +msgstr "3. Configure o Symfony Scheduler." #. type: Plain text #: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md msgid "Depending on your needs, the Symfony Scheduler component offers two ways to consume messages: using the `messenger:consume` command or [creating a worker programmatically](https://symfony.com/doc/current/scheduler.html#creating-a-consumer-programmatically). The example uses the [symfony/messenger](https://packagist.org/packages/symfony/messenger) package to consume messages." -msgstr "" +msgstr "Dependendo das suas necessidades, o componente Symfony Scheduler oferece duas formas de consumir mensagens: usando o comando `messenger:consume` ou [criando um worker programaticamente](https://symfony.com/doc/current/scheduler.html#creating-a-consumer-programmatically). O exemplo usa o pacote [symfony/messenger](https://packagist.org/packages/symfony/messenger) para consumir as mensagens." #. type: Plain text #: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md msgid "Install the Symfony Messenger package:" -msgstr "" +msgstr "Instale o pacote Symfony Messenger:" #. type: Plain text #: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md msgid "Install the Symfony Cache package:" -msgstr "" +msgstr "Instale o pacote Symfony Cache:" #. type: Fenced code block (shell) #: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md #, no-wrap msgid "composer require symfony/cache\n" -msgstr "" +msgstr "composer require symfony/cache\n" #. type: Plain text #: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md msgid "Implement the ServiceProviderInterface. This instance of the ServiceProviderInterface is used to configure certain Symfony Messenger commands." -msgstr "" +msgstr "Implemente a ServiceProviderInterface. Essa instância da ServiceProviderInterface é usada para configurar alguns comandos do Symfony Messenger." #. type: Plain text #: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md msgid "Configure the Symfony Scheduler and Symfony Messenger dependencies in the `config/common/di/application.php`:" -msgstr "" +msgstr "Configure as dependências do Symfony Scheduler e do Symfony Messenger em `config/common/di/application.php`:" #. type: Fenced code block (php) #: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md @@ -387,15 +469,134 @@ msgid "" " },\n" "];\n" msgstr "" +"use App\\Messages\\MyMessage;\n" +"use App\\Messages\\MyMessageHandler;\n" +"use App\\Scheduler\\MyScheduleProvider;\n" +"use App\\Services\\ServiceProvider;\n" +"use Psr\\Cache\\CacheItemPoolInterface;\n" +"use Psr\\Container\\ContainerInterface;\n" +"use Psr\\EventDispatcher\\EventDispatcherInterface;\n" +"use Psr\\Log\\LoggerInterface;\n" +"use Symfony\\Component\\Cache\\Adapter\\FilesystemAdapter;\n" +"use Symfony\\Component\\EventDispatcher\\EventDispatcher;\n" +"use Symfony\\Component\\Messenger\\Command\\ConsumeMessagesCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\DebugCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\FailedMessagesRemoveCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\FailedMessagesRetryCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\FailedMessagesShowCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\SetupTransportsCommand;\n" +"use Symfony\\Component\\Messenger\\Command\\StatsCommand;\n" +"use Symfony\\Component\\Messenger\\EventListener\\StopWorkerOnRestartSignalListener;\n" +"use Symfony\\Component\\Messenger\\Handler\\HandlersLocator;\n" +"use Symfony\\Component\\Messenger\\MessageBus;\n" +"use Symfony\\Component\\Messenger\\Middleware\\HandleMessageMiddleware;\n" +"use Symfony\\Component\\Messenger\\RoutableMessageBus;\n" +"use Symfony\\Component\\Scheduler\\Generator\\MessageGenerator;\n" +"use Symfony\\Component\\Scheduler\\Messenger\\SchedulerTransport;\n" +"use Symfony\\Contracts\\Service\\ServiceProviderInterface;\n" +"use Yiisoft\\Aliases\\Aliases;\n" +"use Yiisoft\\Definitions\\Reference;\n" +"\n" +"class_alias(MessageBus::class, 'MyMessageBus');\n" +"\n" +"return [\n" +" // ...\n" +" CacheItemPoolInterface::class => static function (ContainerInterface $container) {\n" +" return new FilesystemAdapter(directory: $container->get(Aliases::class)->get('@runtime'));\n" +" }, //One of the following adapters can be used instead: Psr16Adapter, RedisAdapter, MemcachedAdapter, DoctrineDbalAdapter, and so forth.\n" +"\n" +"\n" +" 'SchedulerTransport' => static function () {\n" +" return new SchedulerTransport(\n" +" new MessageGenerator(\n" +" new MyScheduleProvider(),\n" +" 'MySchedule'\n" +" )\n" +" );\n" +" },\n" +"\n" +" MyMessageBus::class => static function (ContainerInterface $container) {\n" +" return new MyMessageBus([\n" +" new HandleMessageMiddleware(new HandlersLocator([\n" +" MyMessage::class => [$container->get(MyMessageHandler::class)]\n" +" ])),\n" +" ]);\n" +" },\n" +"\n" +" EventDispatcherInterface::class => static function (ContainerInterface $container) {\n" +" $eventDispatcher = new EventDispatcher();\n" +" $eventDispatcher->addSubscriber($container->get(StopWorkerOnRestartSignalListener::class));\n" +" return $eventDispatcher;\n" +" },\n" +" ServiceProviderInterface::class => [\n" +" 'class' => ServiceProvider::class,\n" +" '__construct()' => [\n" +" 'container' => Reference::to(ContainerInterface::class),\n" +" 'serviceMap' => [\n" +" 'SchedulerTransport' => SchedulerTransport::class\n" +" ]\n" +" ],\n" +" ],\n" +"\n" +" ConsumeMessagesCommand::class => static function (ContainerInterface $container) {\n" +" return new ConsumeMessagesCommand(\n" +" $container->get(RoutableMessageBus::class),\n" +" $container,\n" +" $container->get(EventDispatcherInterface::class),\n" +" $container->get(LoggerInterface::class),\n" +" array_keys($container->get(ServiceProviderInterface::class)->getProvidedServices())\n" +" );\n" +" },\n" +" DebugCommand::class => [\n" +" '__construct()' => [\n" +" 'mapping' => [\n" +" MyMessageBus::class => [Reference::to(MyMessageHandler::class)]\n" +" ]\n" +" ],\n" +" ],\n" +" FailedMessagesRemoveCommand::class => [\n" +" '__construct()' => [\n" +" 'globalFailureReceiverName' => null,\n" +" 'failureTransports' => Reference::to(ServiceProviderInterface::class)\n" +" ],\n" +" ],\n" +" FailedMessagesRetryCommand::class => [\n" +" '__construct()' => [\n" +" 'globalReceiverName' => null,\n" +" 'failureTransports' => Reference::to(ServiceProviderInterface::class),\n" +" 'messageBus' => Reference::to(MyMessageBus::class),\n" +" 'eventDispatcher' => Reference::to(EventDispatcherInterface::class),\n" +" 'logger' => Reference::to(LoggerInterface::class),\n" +" ],\n" +" ],\n" +" FailedMessagesShowCommand::class => [\n" +" '__construct()' => [\n" +" 'globalFailureReceiverName' => null,\n" +" 'failureTransports' => Reference::to(ServiceProviderInterface::class)\n" +" ],\n" +" ],\n" +" SetupTransportsCommand::class => static function (ContainerInterface $container) {\n" +" return new SetupTransportsCommand(\n" +" $container,\n" +" array_keys($container->get(ServiceProviderInterface::class)->getProvidedServices())\n" +" );\n" +" },\n" +" StatsCommand::class => static function (ContainerInterface $container) {\n" +" return new StatsCommand(\n" +" $container,\n" +" array_keys($container->get(ServiceProviderInterface::class)->getProvidedServices())\n" +" );\n" +" },\n" +"];\n" #. type: Title ### #: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md #, no-wrap msgid "5. Consume messages." -msgstr "" +msgstr "5. Consuma as mensagens." #. type: Fenced code block (bash) #: ../src/cookbook/third-party-integrations/symfony-scheduler-integration-guide.md #, no-wrap msgid "./yii symfony:messenger:consume SchedulerTransport --bus=MyMessageBus\n" -msgstr "" +msgstr "./yii symfony:messenger:consume SchedulerTransport --bus=MyMessageBus\n" diff --git a/_translations/po/pt-BR/cookbook_using-htmx-for-partial-reloads.md.po b/_translations/po/pt-BR/cookbook_using-htmx-for-partial-reloads.md.po index 3a79c896..369fe9fa 100644 --- a/_translations/po/pt-BR/cookbook_using-htmx-for-partial-reloads.md.po +++ b/_translations/po/pt-BR/cookbook_using-htmx-for-partial-reloads.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-05-09 10:43+0000\n" "PO-Revision-Date: 2026-05-09 10:43+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,7 +19,7 @@ msgstr "" #: ../src/cookbook/using-htmx-for-partial-reloads.md #, no-wrap msgid "Using htmx for partial page reloads" -msgstr "" +msgstr "Usando htmx para recarregar partes da página" #. type: Plain text #: ../src/cookbook/using-htmx-for-partial-reloads.md @@ -29,39 +29,42 @@ msgid "" "application, this works well for grids: sorting, filtering, and pagination can update only the grid while the rest of\n" "the page stays in place.\n" msgstr "" +"O [htmx](https://htmx.org/) permite que links e formulários requisitem fragmentos de HTML e os troquem na página atual. Em uma\n" +"aplicação Yii, isso funciona bem para grids: ordenação, filtros e paginação podem atualizar só o grid enquanto o resto\n" +"da página continua no lugar.\n" #. type: Plain text #: ../src/cookbook/using-htmx-for-partial-reloads.md msgid "This recipe uses `GridView` as an example because it has links and forms that naturally benefit from partial reloads. The same pattern works for any widget or page fragment: render the fragment separately, add htmx attributes to the controls that should refresh it, and return only that fragment for htmx requests." -msgstr "" +msgstr "Esta receita usa o `GridView` como exemplo porque ele tem links e formulários que se beneficiam naturalmente de recargas parciais. O mesmo padrão funciona para qualquer widget ou fragmento de página: renderize o fragmento separadamente, adicione atributos do htmx aos controles que devem atualizá-lo e retorne apenas esse fragmento nas requisições do htmx." #. type: Title ## #: ../src/cookbook/using-htmx-for-partial-reloads.md #, no-wrap msgid "Install GridView" -msgstr "" +msgstr "Instale o GridView" #. type: Plain text #: ../src/cookbook/using-htmx-for-partial-reloads.md msgid "Install the data view package if the application doesn't use it yet:" -msgstr "" +msgstr "Instale o pacote de data view, se a aplicação ainda não o usa:" #. type: Fenced code block (shell) #: ../src/cookbook/using-htmx-for-partial-reloads.md #, no-wrap msgid "composer require yiisoft/yii-dataview\n" -msgstr "" +msgstr "composer require yiisoft/yii-dataview\n" #. type: Title ## #: ../src/cookbook/using-htmx-for-partial-reloads.md #, no-wrap msgid "Load htmx" -msgstr "" +msgstr "Carregue o htmx" #. type: Plain text #: ../src/cookbook/using-htmx-for-partial-reloads.md msgid "The simplest setup is loading htmx from a CDN. Create `src/Web/Shared/Layout/Main/HtmxAsset.php`:" -msgstr "" +msgstr "A configuração mais simples é carregar o htmx de uma CDN. Crie `src/Web/Shared/Layout/Main/HtmxAsset.php`:" #. type: Fenced code block (php) #: ../src/cookbook/using-htmx-for-partial-reloads.md @@ -89,16 +92,37 @@ msgid "" " ];\n" "}\n" msgstr "" +" 'sha384-H5SrcfygHmAuTDZphMHqBJLc3FhssKjG7w/CeCpFReSfwBWDTKpkzPP8c+cLsK+V',\n" +" 'crossorigin' => 'anonymous',\n" +" ];\n" +"}\n" #. type: Plain text #: ../src/cookbook/using-htmx-for-partial-reloads.md msgid "When updating the htmx version, update the URL and `integrity` value together." -msgstr "" +msgstr "Ao atualizar a versão do htmx, atualize a URL e o valor de `integrity` juntos." #. type: Plain text #: ../src/cookbook/using-htmx-for-partial-reloads.md msgid "For production applications, consider serving htmx from your application assets to avoid depending on a third-party CDN. Download `htmx.min.js` into `assets/main/js/htmx.min.js` and use a local asset bundle:" -msgstr "" +msgstr "Em aplicações de produção, considere servir o htmx a partir dos assets da sua aplicação para não depender de uma CDN de terceiros. Baixe o `htmx.min.js` para `assets/main/js/htmx.min.js` e use um asset bundle local:" #. type: Fenced code block (php) #: ../src/cookbook/using-htmx-for-partial-reloads.md @@ -123,11 +147,29 @@ msgid "" " ];\n" "}\n" msgstr "" +" */\n" +" $pagination = OffsetPagination::widget();\n" +"\n" +" return GridView::widget()\n" +" ->containerAttributes([\n" +" 'id' => 'UsersGridView',\n" +" 'class' => 'mt-4 position-relative',\n" +" ])\n" +" ->dataReader($this->dataReader())\n" +" ->pageSizeConstraint(5)\n" +" ->paginationWidget($pagination)\n" +" ->columns(\n" +" new DataColumn('id', header: 'ID', filter: true),\n" +" new DataColumn('login', header: 'Login', filter: true),\n" +" new DataColumn('name', header: 'Name', filter: true),\n" +" new DataColumn('status', header: 'Status', filter: true),\n" +" )\n" +" ->render();\n" +" }\n" +"\n" +" private function dataReader(): IterableDataReader\n" +" {\n" +" return new IterableDataReader([\n" +" ['id' => 1, 'login' => 'admin', 'name' => 'Alice Adams', 'status' => 'Active'],\n" +" ['id' => 2, 'login' => 'editor', 'name' => 'Eve Editor', 'status' => 'Active'],\n" +" ['id' => 3, 'login' => 'author', 'name' => 'Arthur Author', 'status' => 'Active'],\n" +" ['id' => 4, 'login' => 'reviewer', 'name' => 'Rita Reviewer', 'status' => 'Inactive'],\n" +" ['id' => 5, 'login' => 'support', 'name' => 'Sam Support', 'status' => 'Active'],\n" +" ['id' => 6, 'login' => 'guest', 'name' => 'Grace Guest', 'status' => 'Inactive'],\n" +" ]);\n" +" }\n" +"}\n" #. type: Plain text #: ../src/cookbook/using-htmx-for-partial-reloads.md msgid "For a real application, replace `dataReader()` with a reader backed by a database query or repository. Keep the widget responsible for rendering the grid fragment." -msgstr "" +msgstr "Em uma aplicação real, substitua `dataReader()` por um reader baseado em uma consulta ao banco de dados ou em um repositório. Mantenha o widget responsável por renderizar o fragmento do grid." #. type: Plain text #: ../src/cookbook/using-htmx-for-partial-reloads.md msgid "Create `src/Web/Users/Index/template.php`:" -msgstr "" +msgstr "Crie `src/Web/Users/Index/template.php`:" #. type: Fenced code block (php) #: ../src/cookbook/using-htmx-for-partial-reloads.md @@ -261,11 +376,27 @@ msgid "" "\n" "\n" msgstr "" +"setTitle('Users');\n" +"?>\n" +"

Users

\n" +"\n" +"\n" #. type: Plain text #: ../src/cookbook/using-htmx-for-partial-reloads.md msgid "Create `src/Web/Users/Index/Action.php`:" -msgstr "" +msgstr "Crie `src/Web/Users/Index/Action.php`:" #. type: Fenced code block (php) #: ../src/cookbook/using-htmx-for-partial-reloads.md @@ -293,11 +424,32 @@ msgid "" " }\n" "}\n" msgstr "" +"viewRenderer->render(__DIR__ . '/template');\n" +" }\n" +"}\n" #. type: Plain text #: ../src/cookbook/using-htmx-for-partial-reloads.md msgid "Add the action to `config/common/routes.php`:" -msgstr "" +msgstr "Adicione a action em `config/common/routes.php`:" #. type: Fenced code block (php) #: ../src/cookbook/using-htmx-for-partial-reloads.md @@ -323,22 +475,41 @@ msgid "" " ),\n" "];\n" msgstr "" +"routes(\n" +" Route::get('/')\n" +" ->action(Web\\HomePage\\Action::class)\n" +" ->name('home'),\n" +" Route::get('/users')\n" +" ->action(Web\\Users\\Index\\Action::class)\n" +" ->name('users/index'),\n" +" ),\n" +"];\n" #. type: Plain text #: ../src/cookbook/using-htmx-for-partial-reloads.md msgid "Open `/users` and make sure sorting, filtering, and pagination work with full page reloads first." -msgstr "" +msgstr "Abra `/users` e verifique primeiro se a ordenação, os filtros e a paginação funcionam com recarga completa da página." #. type: Title ## #: ../src/cookbook/using-htmx-for-partial-reloads.md #, no-wrap msgid "Add htmx attributes to the grid" -msgstr "" +msgstr "Adicione atributos do htmx ao grid" #. type: Plain text #: ../src/cookbook/using-htmx-for-partial-reloads.md msgid "Now update `UsersGrid` so the grid controls request a fragment and swap it into `#UsersGridView`:" -msgstr "" +msgstr "Agora atualize o `UsersGrid` para que os controles do grid requisitem um fragmento e o troquem em `#UsersGridView`:" #. type: Fenced code block (php) #: ../src/cookbook/using-htmx-for-partial-reloads.md @@ -413,57 +584,125 @@ msgid "" " }\n" "}\n" msgstr "" +" '#UsersGridView',\n" +" 'hx-target' => '#UsersGridView',\n" +" 'hx-replace-url' => 'true',\n" +" 'hx-swap' => 'outerHTML',\n" +" ];\n" +"\n" +" /** @var PaginationWidgetInterface */\n" +" $pagination = OffsetPagination::widget()->addLinkAttributes([\n" +" 'hx-boost' => 'true',\n" +" ...$htmxLoadAttributes,\n" +" ]);\n" +"\n" +" return GridView::widget()\n" +" ->containerAttributes([\n" +" 'id' => 'UsersGridView',\n" +" 'class' => 'mt-4 position-relative',\n" +" ])\n" +" ->dataReader($this->dataReader())\n" +" ->pageSizeConstraint(5)\n" +" ->sortableLinkAttributes([\n" +" 'hx-boost' => 'true',\n" +" ...$htmxLoadAttributes,\n" +" ])\n" +" ->filterFormAttributes([\n" +" 'hx-boost' => 'true',\n" +" ...$htmxLoadAttributes,\n" +" ])\n" +" ->paginationWidget($pagination)\n" +" ->columns(\n" +" new DataColumn('id', header: 'ID', filter: true),\n" +" new DataColumn('login', header: 'Login', filter: true),\n" +" new DataColumn('name', header: 'Name', filter: true),\n" +" new DataColumn('status', header: 'Status', filter: true),\n" +" )\n" +" ->render();\n" +" }\n" +"\n" +" private function dataReader(): IterableDataReader\n" +" {\n" +" return new IterableDataReader([\n" +" ['id' => 1, 'login' => 'admin', 'name' => 'Alice Adams', 'status' => 'Active'],\n" +" ['id' => 2, 'login' => 'editor', 'name' => 'Eve Editor', 'status' => 'Active'],\n" +" ['id' => 3, 'login' => 'author', 'name' => 'Arthur Author', 'status' => 'Active'],\n" +" ['id' => 4, 'login' => 'reviewer', 'name' => 'Rita Reviewer', 'status' => 'Inactive'],\n" +" ['id' => 5, 'login' => 'support', 'name' => 'Sam Support', 'status' => 'Active'],\n" +" ['id' => 6, 'login' => 'guest', 'name' => 'Grace Guest', 'status' => 'Inactive'],\n" +" ]);\n" +" }\n" +"}\n" #. type: Plain text #: ../src/cookbook/using-htmx-for-partial-reloads.md msgid "The important part is the shared `$htmxLoadAttributes` array:" -msgstr "" +msgstr "A parte importante é o array compartilhado `$htmxLoadAttributes`:" #. type: Bullet: '- ' #: ../src/cookbook/using-htmx-for-partial-reloads.md msgid "`hx-boost=\"true\"` makes the grid links and filter form send htmx requests." -msgstr "" +msgstr "`hx-boost=\"true\"` faz os links e o formulário de filtro do grid enviarem requisições htmx." #. type: Bullet: '- ' #: ../src/cookbook/using-htmx-for-partial-reloads.md msgid "`hx-target=\"#UsersGridView\"` tells htmx which element to replace." -msgstr "" +msgstr "`hx-target=\"#UsersGridView\"` diz ao htmx qual elemento substituir." #. type: Bullet: '- ' #: ../src/cookbook/using-htmx-for-partial-reloads.md msgid "`hx-swap=\"outerHTML\"` replaces the whole grid container with the response." -msgstr "" +msgstr "`hx-swap=\"outerHTML\"` substitui todo o container do grid pela resposta." #. type: Bullet: '- ' #: ../src/cookbook/using-htmx-for-partial-reloads.md msgid "`hx-replace-url=\"true\"` keeps the browser URL in sync with the current sort, filter, and page." -msgstr "" +msgstr "`hx-replace-url=\"true\"` mantém a URL do navegador sincronizada com a ordenação, o filtro e a página atuais." #. type: Bullet: '- ' #: ../src/cookbook/using-htmx-for-partial-reloads.md msgid "`hx-indicator=\"#UsersGridView\"` marks the grid as the loading indicator element while the request is active." -msgstr "" +msgstr "`hx-indicator=\"#UsersGridView\"` marca o grid como o elemento indicador de carregamento enquanto a requisição está ativa." #. type: Plain text #: ../src/cookbook/using-htmx-for-partial-reloads.md msgid "The target selector and the container `id` must match. In this example, both use `UsersGridView`." -msgstr "" +msgstr "O seletor de destino e o `id` do container precisam coincidir. Neste exemplo, ambos usam `UsersGridView`." #. type: Title ## #: ../src/cookbook/using-htmx-for-partial-reloads.md #, no-wrap msgid "Return partial HTML for htmx requests" -msgstr "" +msgstr "Retorne HTML parcial para requisições do htmx" #. type: Plain text #: ../src/cookbook/using-htmx-for-partial-reloads.md msgid "htmx sends the `HX-Request` header with its requests." -msgstr "" +msgstr "O htmx envia o header `HX-Request` nas suas requisições." #. type: Plain text #: ../src/cookbook/using-htmx-for-partial-reloads.md msgid "In the action, return only the widget when the header is present:" -msgstr "" +msgstr "Na action, retorne apenas o widget quando o header estiver presente:" #. type: Fenced code block (php) #: ../src/cookbook/using-htmx-for-partial-reloads.md @@ -498,44 +737,72 @@ msgid "" " }\n" "}\n" msgstr "" +"getHeaderLine('HX-Request') === 'true'\n" +" ? $this->htmlResponseFactory->createResponse(UsersGrid::widget())\n" +" : $this->viewRenderer->render(__DIR__ . '/template');\n" +"\n" +" return $response->withAddedHeader('Vary', 'HX-Request');\n" +" }\n" +"}\n" #. type: Plain text #: ../src/cookbook/using-htmx-for-partial-reloads.md msgid "The `Vary` header matters when a browser, proxy, or CDN caches responses. The same URL can return a full page without `HX-Request` and a fragment with `HX-Request: true`, so caches must keep these responses separate." -msgstr "" +msgstr "O header `Vary` importa quando um navegador, proxy ou CDN faz cache das respostas. A mesma URL pode retornar uma página completa sem `HX-Request` e um fragmento com `HX-Request: true`, então os caches precisam manter essas respostas separadas." #. type: Title ## #: ../src/cookbook/using-htmx-for-partial-reloads.md #, no-wrap msgid "Try it" -msgstr "" +msgstr "Experimente" #. type: Plain text #: ../src/cookbook/using-htmx-for-partial-reloads.md msgid "Open the list page and use sorting, filtering, or pagination. The browser URL should change, and only the grid HTML should be replaced." -msgstr "" +msgstr "Abra a página da lista e use a ordenação, os filtros ou a paginação. A URL do navegador deve mudar, e apenas o HTML do grid deve ser substituído." #. type: Plain text #: ../src/cookbook/using-htmx-for-partial-reloads.md msgid "In the browser developer tools, the htmx requests should include the `HX-Request` header. Their responses should contain only the grid container." -msgstr "" +msgstr "Nas ferramentas de desenvolvedor do navegador, as requisições do htmx devem incluir o header `HX-Request`. As respostas devem conter apenas o container do grid." #. type: Plain text #: ../src/cookbook/using-htmx-for-partial-reloads.md msgid "Use the same pattern for other widgets or page fragments:" -msgstr "" +msgstr "Use o mesmo padrão para outros widgets ou fragmentos de página:" #. type: Bullet: '1. ' #: ../src/cookbook/using-htmx-for-partial-reloads.md msgid "Put the reloadable HTML into a widget or another small renderer." -msgstr "" +msgstr "Coloque o HTML recarregável em um widget ou em outro pequeno renderizador." #. type: Bullet: '2. ' #: ../src/cookbook/using-htmx-for-partial-reloads.md msgid "Add htmx attributes to the links and forms that should refresh it." -msgstr "" +msgstr "Adicione atributos do htmx aos links e formulários que devem atualizá-lo." #. type: Bullet: '3. ' #: ../src/cookbook/using-htmx-for-partial-reloads.md msgid "Return the fragment for htmx requests and the full page for regular requests." -msgstr "" +msgstr "Retorne o fragmento para requisições do htmx e a página completa para requisições comuns." diff --git a/_translations/po/pt-BR/cookbook_using-yii-in-third-party-apps.md.po b/_translations/po/pt-BR/cookbook_using-yii-in-third-party-apps.md.po index 81c1cba4..58cee2cf 100644 --- a/_translations/po/pt-BR/cookbook_using-yii-in-third-party-apps.md.po +++ b/_translations/po/pt-BR/cookbook_using-yii-in-third-party-apps.md.po @@ -8,49 +8,45 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-06-05 22:11+0000\n" "PO-Revision-Date: 2026-06-05 22:11+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Fenced code block (sh) -#: ../src/cookbook/custom-migration-template.md -#: ../src/cookbook/using-yii-in-third-party-apps.md -#: ../src/guide/structure/designing-packages.md -#: ../src/guide/structure/module.md ../src/guide/structure/package.md -#: ../src/guide/tutorial/i18n.md +#: ../src/cookbook/custom-migration-template.md ../src/cookbook/using-yii-in-third-party-apps.md ../src/guide/structure/designing-packages.md ../src/guide/structure/module.md ../src/guide/structure/package.md ../src/guide/tutorial/i18n.md #, no-wrap msgid "composer yii-config-rebuild\n" -msgstr "" +msgstr "composer yii-config-rebuild\n" #. type: Title # #: ../src/cookbook/using-yii-in-third-party-apps.md #, no-wrap msgid "Using Yii in third-party applications" -msgstr "" +msgstr "Usando o Yii em aplicações de terceiros" #. type: Plain text #: ../src/cookbook/using-yii-in-third-party-apps.md msgid "Sometimes a project already has an entry point owned by another framework, CMS, or legacy application, but you still want to reuse Yii services: configuration, DI definitions, domain services, logging, mailers, database connections, or console-oriented application code." -msgstr "" +msgstr "Às vezes um projeto já tem um ponto de entrada controlado por outro framework, CMS ou aplicação legada, mas você ainda quer reaproveitar serviços do Yii: configuração, definições de DI, serviços de domínio, logs, mailers, conexões com banco de dados ou código de aplicação voltado ao console." #. type: Plain text #: ../src/cookbook/using-yii-in-third-party-apps.md msgid "Yii3 has no global application singleton. Bootstrap the Yii container explicitly and pass the services you need to the third-party code." -msgstr "" +msgstr "O Yii3 não tem um singleton global de aplicação. Inicialize o container do Yii explicitamente e passe os serviços de que você precisa ao código de terceiros." #. type: Title ## #: ../src/cookbook/using-yii-in-third-party-apps.md #, no-wrap msgid "Bootstrap the Yii container" -msgstr "" +msgstr "Inicialize o container do Yii" #. type: Plain text #: ../src/cookbook/using-yii-in-third-party-apps.md msgid "Create a small adapter in the host application, for example `bootstrap-yii-services.php`:" -msgstr "" +msgstr "Crie um pequeno adaptador na aplicação hospedeira, por exemplo `bootstrap-yii-services.php`:" #. type: Fenced code block (php) #: ../src/cookbook/using-yii-in-third-party-apps.md @@ -116,27 +112,86 @@ msgid "" " return $container;\n" "}\n" msgstr "" +"withValidate(Environment::appDebug())\n" +" ->withDefinitions(array_merge(\n" +" $config->get('di-console'),\n" +" [ConfigInterface::class => $config],\n" +" ))\n" +" ->withProviders($config->get('di-providers-console'))\n" +" ->withDelegates($config->get('di-delegates-console'));\n" +"\n" +" if ($config->has('di-tags-console')) {\n" +" $containerConfig = $containerConfig->withTags($config->get('di-tags-console'));\n" +" }\n" +"\n" +" $container = new Container($containerConfig);\n" +"\n" +" foreach ($config->get('bootstrap-console') as $callback) {\n" +" if (!is_callable($callback)) {\n" +" throw new RuntimeException(sprintf(\n" +" 'Bootstrap callback must be callable, \"%s\" given.',\n" +" get_debug_type($callback),\n" +" ));\n" +" }\n" +"\n" +" $callback($container);\n" +" }\n" +"\n" +" return $container;\n" +"}\n" #. type: Plain text #: ../src/cookbook/using-yii-in-third-party-apps.md msgid "The adapter builds only the Yii configuration and DI container, then runs the configured bootstrap callbacks. It does not create or run a Yii application runner, so the third-party application keeps ownership of the entry point and process lifecycle." -msgstr "" +msgstr "O adaptador monta apenas a configuração e o container de DI do Yii e depois executa os callbacks de bootstrap configurados. Ele não cria nem executa um runner de aplicação do Yii, então a aplicação de terceiros continua dona do ponto de entrada e do ciclo de vida do processo." #. type: Plain text #: ../src/cookbook/using-yii-in-third-party-apps.md msgid "Use console configuration groups when you need common services and console-safe services. Use web groups instead only when you intentionally need web-specific definitions from the `di-web` group, such as PSR-17 HTTP factories or web middleware dependencies." -msgstr "" +msgstr "Use os grupos de configuração de console quando precisar de serviços comuns e serviços seguros para o console. Use os grupos web apenas quando precisar intencionalmente de definições específicas da web do grupo `di-web`, como as factories HTTP da PSR-17 ou dependências de middlewares web." #. type: Title ## #: ../src/cookbook/using-yii-in-third-party-apps.md #, no-wrap msgid "Get Yii services from the host application" -msgstr "" +msgstr "Obtenha serviços do Yii a partir da aplicação hospedeira" #. type: Plain text #: ../src/cookbook/using-yii-in-third-party-apps.md msgid "Use the adapter from the third-party application:" -msgstr "" +msgstr "Use o adaptador a partir da aplicação de terceiros:" #. type: Fenced code block (php) #: ../src/cookbook/using-yii-in-third-party-apps.md @@ -158,132 +213,147 @@ msgid "" "\n" "echo $params->name;\n" msgstr "" +"get(ApplicationParams::class);\n" +"\n" +"echo $params->name;\n" #. type: Plain text #: ../src/cookbook/using-yii-in-third-party-apps.md msgid "In real integrations, prefer getting your own application services instead of framework infrastructure. For example, expose `InvoiceSender`, `ReportBuilder`, or `CatalogImporter` from Yii and call that service from the host application." -msgstr "" +msgstr "Em integrações reais, prefira obter os serviços da sua própria aplicação em vez da infraestrutura do framework. Por exemplo, exponha `InvoiceSender`, `ReportBuilder` ou `CatalogImporter` a partir do Yii e chame esse serviço na aplicação hospedeira." #. type: Title ## #: ../src/cookbook/using-yii-in-third-party-apps.md #, no-wrap msgid "Keep boundaries explicit" -msgstr "" +msgstr "Mantenha os limites explícitos" #. type: Plain text #: ../src/cookbook/using-yii-in-third-party-apps.md msgid "Avoid mixing request lifecycles. Let the host application continue to own its HTTP request and response. Let Yii provide services that do not assume Yii is handling the current request." -msgstr "" +msgstr "Evite misturar ciclos de vida de requisição. Deixe a aplicação hospedeira continuar dona da requisição e da resposta HTTP. Deixe o Yii fornecer serviços que não pressupõem que o Yii está tratando a requisição atual." #. type: Plain text #: ../src/cookbook/using-yii-in-third-party-apps.md msgid "Good candidates for reuse:" -msgstr "" +msgstr "Bons candidatos para reaproveitamento:" #. type: Bullet: '- ' #: ../src/cookbook/using-yii-in-third-party-apps.md msgid "domain services;" -msgstr "" +msgstr "serviços de domínio;" #. type: Bullet: '- ' #: ../src/cookbook/using-yii-in-third-party-apps.md msgid "repositories and database connections;" -msgstr "" +msgstr "repositórios e conexões com banco de dados;" #. type: Bullet: '- ' #: ../src/cookbook/using-yii-in-third-party-apps.md msgid "mailers and notification services;" -msgstr "" +msgstr "mailers e serviços de notificação;" #. type: Bullet: '- ' #: ../src/cookbook/using-yii-in-third-party-apps.md msgid "loggers;" -msgstr "" +msgstr "loggers;" #. type: Bullet: '- ' #: ../src/cookbook/using-yii-in-third-party-apps.md msgid "validators;" -msgstr "" +msgstr "validadores;" #. type: Bullet: '- ' #: ../src/cookbook/using-yii-in-third-party-apps.md msgid "queue producers;" -msgstr "" +msgstr "produtores de fila;" #. type: Bullet: '- ' #: ../src/cookbook/using-yii-in-third-party-apps.md msgid "command-like application services." -msgstr "" +msgstr "serviços de aplicação no estilo de comandos." #. type: Plain text #: ../src/cookbook/using-yii-in-third-party-apps.md msgid "Avoid pulling in Yii actions, middleware stacks, sessions, CSRF middleware, or view rendering unless the host application explicitly delegates that whole responsibility to Yii." -msgstr "" +msgstr "Evite trazer actions, pilhas de middlewares, sessões, middleware de CSRF ou renderização de views do Yii, a menos que a aplicação hospedeira delegue explicitamente essa responsabilidade inteira ao Yii." #. type: Title ## #: ../src/cookbook/using-yii-in-third-party-apps.md #, no-wrap msgid "Configuration groups" -msgstr "" +msgstr "Grupos de configuração" #. type: Plain text #: ../src/cookbook/using-yii-in-third-party-apps.md msgid "The default application template separates configuration by group:" -msgstr "" +msgstr "O template de aplicação padrão separa a configuração por grupo:" #. type: Bullet: '- ' #: ../src/cookbook/using-yii-in-third-party-apps.md msgid "`di` is shared by web and console entry points;" -msgstr "" +msgstr "`di` é compartilhado pelos pontos de entrada web e de console;" #. type: Bullet: '- ' #: ../src/cookbook/using-yii-in-third-party-apps.md msgid "`di-console` is console-specific and includes `di` in the template;" -msgstr "" +msgstr "`di-console` é específico do console e inclui `di` no template;" #. type: Bullet: '- ' #: ../src/cookbook/using-yii-in-third-party-apps.md msgid "`di-web` is web-specific and includes `di`;" -msgstr "" +msgstr "`di-web` é específico da web e inclui `di`;" #. type: Bullet: '- ' #: ../src/cookbook/using-yii-in-third-party-apps.md msgid "`params-console` and `params-web` extend common `params`." -msgstr "" +msgstr "`params-console` e `params-web` estendem o `params` comum." #. type: Plain text #: ../src/cookbook/using-yii-in-third-party-apps.md msgid "Choose the smallest group that contains the services you need. If the host application only needs domain services, keep those definitions in `config/common/di/*.php` so both Yii and the third-party app can use them without web-only dependencies." -msgstr "" +msgstr "Escolha o menor grupo que contém os serviços de que você precisa. Se a aplicação hospedeira só precisa de serviços de domínio, mantenha essas definições em `config/common/di/*.php` para que tanto o Yii quanto a aplicação de terceiros possam usá-las sem dependências exclusivas da web." #. type: Plain text #: ../src/cookbook/using-yii-in-third-party-apps.md msgid "After changing `config/configuration.php`, rebuild the merge plan:" -msgstr "" +msgstr "Depois de alterar `config/configuration.php`, reconstrua o merge plan:" #. type: Title ## #: ../src/cookbook/using-yii-in-third-party-apps.md #, no-wrap msgid "Error handling and logging" -msgstr "" +msgstr "Tratamento de erros e logs" #. type: Plain text #: ../src/cookbook/using-yii-in-third-party-apps.md msgid "The host application should remain responsible for top-level error handling. Catch exceptions at the integration boundary when the host app needs to convert them into its own response or error format." -msgstr "" +msgstr "A aplicação hospedeira deve continuar responsável pelo tratamento de erros de nível mais alto. Capture as exceções na fronteira da integração quando a aplicação hospedeira precisar convertê-las na sua própria resposta ou formato de erro." #. type: Plain text #: ../src/cookbook/using-yii-in-third-party-apps.md msgid "Yii services can still use `Psr\\Log\\LoggerInterface`. Configure the Yii logger to write to the same destination as the host application or bridge both applications to the same PSR-3 logger." -msgstr "" +msgstr "Os serviços do Yii ainda podem usar `Psr\\Log\\LoggerInterface`. Configure o logger do Yii para gravar no mesmo destino da aplicação hospedeira ou conecte as duas aplicações ao mesmo logger PSR-3." #. type: Title ## #: ../src/cookbook/using-yii-in-third-party-apps.md #, no-wrap msgid "Long-running host processes" -msgstr "" +msgstr "Processos hospedeiros de longa duração" #. type: Plain text #: ../src/cookbook/using-yii-in-third-party-apps.md msgid "If the third-party application is a worker, daemon, or event-loop server, avoid mutable shared state in services. Yii services resolved from the container are shared by default, so design them as stateless services or create a fresh container for each isolated job when stateful dependencies are unavoidable." -msgstr "" +msgstr "Se a aplicação de terceiros for um worker, um daemon ou um servidor com event loop, evite estado mutável compartilhado nos serviços. Os serviços do Yii obtidos do container são compartilhados por padrão, então projete-os como serviços sem estado ou crie um container novo para cada job isolado quando dependências com estado forem inevitáveis." diff --git a/_translations/po/pt-BR/cookbook_working-on-windows.md.po b/_translations/po/pt-BR/cookbook_working-on-windows.md.po index 96c79ebf..fd630d34 100644 --- a/_translations/po/pt-BR/cookbook_working-on-windows.md.po +++ b/_translations/po/pt-BR/cookbook_working-on-windows.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-05-05 22:18+0000\n" "PO-Revision-Date: 2026-05-05 22:18+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,23 +19,23 @@ msgstr "" #: ../src/cookbook/working-on-windows.md #, no-wrap msgid "Working on Windows" -msgstr "" +msgstr "Trabalhando no Windows" #. type: Plain text #: ../src/cookbook/working-on-windows.md msgid "Yii applications usually run on Linux in production. On Windows, choose a local workflow that stays close to that environment and keeps filesystem performance predictable." -msgstr "" +msgstr "Aplicações Yii geralmente rodam no Linux em produção. No Windows, escolha um fluxo de trabalho local que fique próximo desse ambiente e mantenha o desempenho do sistema de arquivos previsível." #. type: Title ## #: ../src/cookbook/working-on-windows.md #, no-wrap msgid "Recommended setup: WSL" -msgstr "" +msgstr "Configuração recomendada: WSL" #. type: Plain text #: ../src/cookbook/working-on-windows.md msgid "Use [Windows Subsystem for Linux](https://learn.microsoft.com/windows/wsl/) with a Linux distribution such as Ubuntu. Install PHP, Composer, Git, and Make inside WSL, then clone the project into the Linux filesystem:" -msgstr "" +msgstr "Use o [Windows Subsystem for Linux](https://learn.microsoft.com/windows/wsl/) com uma distribuição Linux como o Ubuntu. Instale PHP, Composer, Git e Make dentro do WSL e depois clone o projeto no sistema de arquivos do Linux:" #. type: Fenced code block (shell) #: ../src/cookbook/working-on-windows.md @@ -46,27 +46,31 @@ msgid "" "cd my-app\n" "composer install\n" msgstr "" +"cd ~\n" +"git clone https://github.com/yiisoft/app.git my-app\n" +"cd my-app\n" +"composer install\n" #. type: Plain text #: ../src/cookbook/working-on-windows.md msgid "Keep the project under the WSL filesystem, for example `/home/user/projects/my-app`. Avoid working from a mounted Windows path such as `/mnt/c/Users/user/projects/my-app`; it is much slower for Composer, tests, and tools that read many small files." -msgstr "" +msgstr "Mantenha o projeto no sistema de arquivos do WSL, por exemplo `/home/user/projects/my-app`. Evite trabalhar a partir de um caminho montado do Windows, como `/mnt/c/Users/user/projects/my-app`; ele é muito mais lento para o Composer, os testes e as ferramentas que leem muitos arquivos pequenos." #. type: Plain text #: ../src/cookbook/working-on-windows.md msgid "You can open the project from Windows editors through the WSL integration. In PhpStorm, open the project from the WSL filesystem. In VS Code, use the WSL extension and open the folder from inside the WSL session." -msgstr "" +msgstr "Você pode abrir o projeto em editores do Windows por meio da integração com o WSL. No PhpStorm, abra o projeto a partir do sistema de arquivos do WSL. No VS Code, use a extensão WSL e abra a pasta de dentro da sessão do WSL." #. type: Title ## #: ../src/cookbook/working-on-windows.md #, no-wrap msgid "Docker with WSL" -msgstr "" +msgstr "Docker com WSL" #. type: Plain text #: ../src/cookbook/working-on-windows.md msgid "Docker Desktop with the WSL backend is also a good Windows setup. Keep the project in the WSL filesystem and run Docker commands from WSL:" -msgstr "" +msgstr "O Docker Desktop com o backend WSL também é uma boa configuração no Windows. Mantenha o projeto no sistema de arquivos do WSL e rode os comandos do Docker a partir do WSL:" #. type: Fenced code block (shell) #: ../src/cookbook/working-on-windows.md @@ -77,32 +81,36 @@ msgid "" "make yii\n" "make test\n" msgstr "" +"make build\n" +"make up\n" +"make yii\n" +"make test\n" #. type: Plain text #: ../src/cookbook/working-on-windows.md msgid "This keeps bind mounts fast and gives containers Linux paths that match the tooling used by the Yii application templates." -msgstr "" +msgstr "Isso mantém os bind mounts rápidos e dá aos containers caminhos Linux que batem com as ferramentas usadas pelos templates de aplicação do Yii." #. type: Plain text #: ../src/cookbook/working-on-windows.md msgid "If you need IDE links from debug stack traces, set `APP_HOST_PATH` to the project path that your IDE can open." -msgstr "" +msgstr "Se você precisar de links para a IDE nos stack traces de debug, defina `APP_HOST_PATH` com o caminho do projeto que a sua IDE consegue abrir." #. type: Title ## #: ../src/cookbook/working-on-windows.md #, no-wrap msgid "Git Bash" -msgstr "" +msgstr "Git Bash" #. type: Plain text #: ../src/cookbook/working-on-windows.md msgid "[Git for Windows](https://git-scm.com/downloads/win) installs Git Bash and common Unix tools. It can be enough when you want to run the application directly on Windows without WSL or Docker." -msgstr "" +msgstr "O [Git for Windows](https://git-scm.com/downloads/win) instala o Git Bash e ferramentas Unix comuns. Ele pode bastar quando você quer rodar a aplicação diretamente no Windows, sem WSL nem Docker." #. type: Plain text #: ../src/cookbook/working-on-windows.md msgid "Use this option when your project does not depend on Linux-only extensions or shell scripts. Check the same commands you expect contributors to use:" -msgstr "" +msgstr "Use esta opção quando o seu projeto não depende de extensões ou scripts de shell exclusivos do Linux. Teste os mesmos comandos que você espera que os contribuidores usem:" #. type: Fenced code block (shell) #: ../src/cookbook/working-on-windows.md @@ -111,50 +119,52 @@ msgid "" "composer install\n" "composer test\n" msgstr "" +"composer install\n" +"composer test\n" #. type: Plain text #: ../src/cookbook/working-on-windows.md msgid "If the project uses `make`, Git for Windows includes a Bash environment, but `make` availability depends on your local installation. Install it separately when needed." -msgstr "" +msgstr "Se o projeto usa `make`, o Git for Windows inclui um ambiente Bash, mas a disponibilidade do `make` depende da sua instalação local. Instale-o separadamente quando necessário." #. type: Title ## #: ../src/cookbook/working-on-windows.md #, no-wrap msgid "PowerShell and CMD" -msgstr "" +msgstr "PowerShell e CMD" #. type: Plain text #: ../src/cookbook/working-on-windows.md msgid "PowerShell and CMD can run PHP and Composer, but they differ from the common Linux server environment in quoting, environment variables, paths, and shell utilities. Use them for simple commands only." -msgstr "" +msgstr "O PowerShell e o CMD conseguem rodar PHP e Composer, mas diferem do ambiente comum de servidores Linux em aspas, variáveis de ambiente, caminhos e utilitários de shell. Use-os apenas para comandos simples." #. type: Plain text #: ../src/cookbook/working-on-windows.md msgid "For regular Yii development on Windows, prefer WSL or Docker with WSL." -msgstr "" +msgstr "Para o desenvolvimento regular com Yii no Windows, prefira o WSL ou o Docker com WSL." #. type: Title ## #: ../src/cookbook/working-on-windows.md #, no-wrap msgid "Choosing a workflow" -msgstr "" +msgstr "Escolhendo um fluxo de trabalho" #. type: Plain text #: ../src/cookbook/working-on-windows.md msgid "Use WSL when you want the closest local match to a Linux server and do not need containers for every service." -msgstr "" +msgstr "Use o WSL quando quiser o ambiente local mais parecido com um servidor Linux e não precisar de containers para cada serviço." #. type: Plain text #: ../src/cookbook/working-on-windows.md msgid "Use Docker with WSL when you want the application, database, and other services described by Compose files." -msgstr "" +msgstr "Use o Docker com WSL quando quiser a aplicação, o banco de dados e outros serviços descritos em arquivos do Compose." #. type: Plain text #: ../src/cookbook/working-on-windows.md msgid "Use Git Bash for small projects or quick checks that run directly on Windows." -msgstr "" +msgstr "Use o Git Bash para projetos pequenos ou verificações rápidas que rodam diretamente no Windows." #. type: Plain text #: ../src/cookbook/working-on-windows.md msgid "Use PowerShell or CMD when the command is known to be platform-neutral." -msgstr "" +msgstr "Use o PowerShell ou o CMD quando se sabe que o comando é independente de plataforma." diff --git a/src/pt-BR/cookbook/configuring-webservers/apache.md b/src/pt-BR/cookbook/configuring-webservers/apache.md index e70f518b..d1a0a30b 100644 --- a/src/pt-BR/cookbook/configuring-webservers/apache.md +++ b/src/pt-BR/cookbook/configuring-webservers/apache.md @@ -1,60 +1,60 @@ -# Configuring web servers: Apache +# Configurando servidores web: Apache -Use the following configuration in Apache's `httpd.conf` file or within a -virtual host configuration. Note that you should replace -`path/to/app/public` with the actual path for `app/public`. +Use a configuração a seguir no arquivo `httpd.conf` do Apache ou na +configuração de um virtual host. Substitua `path/to/app/public` pelo caminho +real de `app/public`. ```apache -# Set document root to be "app/public" +# Define o document root como "app/public" DocumentRoot "path/to/app/public" - # use mod_rewrite for pretty URL support + # usa mod_rewrite para suportar URLs amigáveis RewriteEngine on - # Do not allow access to URLs with a script name + # Não permite acesso a URLs com o nome do script RewriteCond %{THE_REQUEST} index.php [NC] RewriteRule . - [R=404,L] - # If a directory or a file exists, use the request directly + # Se um diretório ou arquivo existir, usa a requisição diretamente RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d - # Otherwise forward the request to index.php + # Caso contrário, encaminha a requisição para index.php RewriteRule . index.php SetEnv APP_ENV dev - # ...other settings... + # ...outras configurações... ``` -In case you have `AllowOverride All` you can add `.htaccess` file with the -following configuration instead of using `httpd.conf`: +Se você tiver `AllowOverride All`, pode adicionar um arquivo `.htaccess` com +a configuração a seguir em vez de usar o `httpd.conf`: ```apache -# use mod_rewrite for pretty URL support +# usa mod_rewrite para suportar URLs amigáveis RewriteEngine on -# Do not allow access to URLs with a script name +# Não permite acesso a URLs com o nome do script RewriteCond %{THE_REQUEST} index.php [NC] RewriteRule . - [R=404,L] -# If a directory or a file exists, use the request directly +# Se um diretório ou arquivo existir, usa a requisição diretamente RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d -# Otherwise forward the request to index.php +# Caso contrário, encaminha a requisição para index.php RewriteRule . index.php SetEnv APP_ENV dev -# ...other settings... +# ...outras configurações... ``` -In the above, note the usage of `SetEnv`. Since Yii3 application templates -use environment variables, this is a possible place to set them. In -production environment remember to set `APP_ENV` to `prod`. +Observe o uso de `SetEnv` acima. Como os templates de aplicação do Yii3 usam +variáveis de ambiente, este é um lugar possível para defini-las. Em +produção, lembre-se de definir `APP_ENV` como `prod`. -See [application logs](general.md#application-logs) for logging -configuration. +Veja [logs da aplicação](general.md#logs-da-aplicacao) para a configuração +de logs. diff --git a/src/pt-BR/cookbook/configuring-webservers/general.md b/src/pt-BR/cookbook/configuring-webservers/general.md index 64c5cae3..d5878778 100644 --- a/src/pt-BR/cookbook/configuring-webservers/general.md +++ b/src/pt-BR/cookbook/configuring-webservers/general.md @@ -1,40 +1,42 @@ -# Configuring web servers: General +# Configurando servidores web: geral -On a production server, if you don't use Docker, configure your web server -to serve only the application's public files. Point the document root of -your web server to the `app/public` folder. +Em um servidor de produção, se você não usa Docker, configure seu servidor +web para servir apenas os arquivos públicos da aplicação. Aponte o document +root do servidor web para a pasta `app/public`. > [!IMPORTANT] -> If you're running your Yii application behind a reverse proxy, you might need to configure -> [Trusted proxies and headers](../../guide/security/trusted-request.md). +> Se você executa sua aplicação Yii atrás de um proxy reverso, pode ser necessário configurar +> [proxies e headers confiáveis](../../guide/security/trusted-request.md). -## Application logs +## Logs da aplicação -Yii3 application templates write application logs to standard output -(`stdout`, or `php://stdout`) by default. They don't create application log -files. Standard error (`stderr`) requires explicit log target -configuration. Docker collects container output, but on a server without -containers you must configure where that output goes or [configure a file -target](../../guide/runtime/logging.md#logging-to-files). Web server access -and error log settings don't configure Yii's log targets. +Os templates de aplicação do Yii3 escrevem os logs da aplicação na saída +padrão (`stdout`, ou `php://stdout`) por padrão. Eles não criam arquivos de +log da aplicação. A saída de erro padrão (`stderr`) exige configuração +explícita de destino de log. O Docker coleta a saída dos containers, mas em +um servidor sem containers você precisa configurar para onde essa saída vai +ou [configurar um destino de +arquivo](../../guide/runtime/logging.md#logs-em-arquivos). As configurações +de log de acesso e de erro do servidor web não configuram os destinos de log +do Yii. ### PHP-FPM -If your web server uses PHP-FPM, enable worker output capture in the -application's PHP-FPM pool configuration: +Se o seu servidor web usa PHP-FPM, habilite a captura da saída dos workers +na configuração do pool PHP-FPM da aplicação: ```ini catch_workers_output = yes ``` -Reload PHP-FPM after changing its configuration. PHP-FPM sends worker -standard output and standard error to its main error log. The `error_log` -directive in `php-fpm.conf` sets the destination. Without this setting, -PHP-FPM redirects both streams to `/dev/null` by default. See the [PHP-FPM -configuration -reference](https://www.php.net/manual/en/install.fpm.configuration.php). +Recarregue o PHP-FPM depois de alterar a configuração. O PHP-FPM envia a +saída padrão e a saída de erro dos workers para o seu log de erro +principal. A diretiva `error_log` em `php-fpm.conf` define o destino. Sem +essa configuração, o PHP-FPM redireciona as duas saídas para `/dev/null` por +padrão. Veja a [referência de configuração do +PHP-FPM](https://www.php.net/manual/en/install.fpm.configuration.php). -## Specific server configurations +## Configurações específicas de servidores - [Nginx](nginx.md) - [Apache](apache.md) diff --git a/src/pt-BR/cookbook/configuring-webservers/iis.md b/src/pt-BR/cookbook/configuring-webservers/iis.md index 971a2570..812ec443 100644 --- a/src/pt-BR/cookbook/configuring-webservers/iis.md +++ b/src/pt-BR/cookbook/configuring-webservers/iis.md @@ -1,10 +1,10 @@ -# Configuring web servers: IIS +# Configurando servidores web: IIS -When you use [IIS](https://www.iis.net/), host the application in a virtual -host (Website) where the document root points to the `path/to/app/public` -folder and configure the website to run PHP. In that `public` folder, place -a file named `web.config` at `path/to/app/public/web.config`. Use the -following content: +Ao usar o [IIS](https://www.iis.net/), hospede a aplicação em um virtual +host (Website) cujo document root aponte para a pasta `path/to/app/public` e +configure o site para executar PHP. Nessa pasta `public`, coloque um +arquivo chamado `web.config` em `path/to/app/public/web.config`. Use o +seguinte conteúdo: ```xml @@ -29,8 +29,8 @@ following content: ``` -Also, [IIS documentation](https://learn.microsoft.com/en-us/iis/) could be -useful to configure PHP on IIS. +A [documentação do IIS](https://learn.microsoft.com/en-us/iis/) também pode +ser útil para configurar o PHP no IIS. -See [application logs](general.md#application-logs) for logging -configuration. +Veja [logs da aplicação](general.md#logs-da-aplicacao) para a configuração +de logs. diff --git a/src/pt-BR/cookbook/configuring-webservers/lighttpd.md b/src/pt-BR/cookbook/configuring-webservers/lighttpd.md index aee8a84e..a4b6a482 100644 --- a/src/pt-BR/cookbook/configuring-webservers/lighttpd.md +++ b/src/pt-BR/cookbook/configuring-webservers/lighttpd.md @@ -1,10 +1,10 @@ -# Configuring web servers: lighttpd +# Configurando servidores web: lighttpd -To use [lighttpd](https://www.lighttpd.net/) >= 1.4.24, put `index.php` in the web root and add the following to the configuration: +Para usar o [lighttpd](https://www.lighttpd.net/) >= 1.4.24, coloque o `index.php` na raiz web e adicione o seguinte à configuração: ``` url.rewrite-if-not-file = ("(.*)" => "/index.php/$0") ``` -See [application logs](general.md#application-logs) for logging -configuration. +Veja [logs da aplicação](general.md#logs-da-aplicacao) para a configuração +de logs. diff --git a/src/pt-BR/cookbook/configuring-webservers/nginx-unit.md b/src/pt-BR/cookbook/configuring-webservers/nginx-unit.md index 4f363428..e83b4893 100644 --- a/src/pt-BR/cookbook/configuring-webservers/nginx-unit.md +++ b/src/pt-BR/cookbook/configuring-webservers/nginx-unit.md @@ -1,13 +1,14 @@ -# Configuring web servers: NGINX Unit and FreeUnit +# Configurando servidores web: NGINX Unit e FreeUnit -Run Yii-based apps using [NGINX Unit](https://unit.nginx.org/) with a PHP -language module. The same configuration format is used by -[FreeUnit](https://github.com/freeunitorg/freeunit), a community LTS fork of -Unit. With FreeUnit Docker images, such as -`ghcr.io/freeunitorg/freeunit:latest-php8.5`, put the configuration in +Execute aplicações baseadas em Yii usando o [NGINX +Unit](https://unit.nginx.org/) com um módulo de linguagem PHP. O mesmo +formato de configuração é usado pelo +[FreeUnit](https://github.com/freeunitorg/freeunit), um fork LTS do Unit +mantido pela comunidade. Com as imagens Docker do FreeUnit, como +`ghcr.io/freeunitorg/freeunit:latest-php8.5`, coloque a configuração em `/var/lib/unit/config.json`. -Here is a sample configuration. +Aqui está um exemplo de configuração. ```json { @@ -59,12 +60,12 @@ Here is a sample configuration. } ``` -You can also [set up](https://unit.nginx.org/configuration/#php) your PHP -environment or supply a custom `php.ini` in the same configuration. +Você também pode [configurar](https://unit.nginx.org/configuration/#php) o +ambiente PHP ou fornecer um `php.ini` personalizado na mesma configuração. -Since Yii3 application templates use environment variables, you can set them -in `applications.yii.environment`. In a production environment, remember to -set `APP_ENV` to `prod`. +Como os templates de aplicação do Yii3 usam variáveis de ambiente, você pode +defini-las em `applications.yii.environment`. Em produção, lembre-se de +definir `APP_ENV` como `prod`. -See [application logs](general.md#application-logs) for logging -configuration. +Veja [logs da aplicação](general.md#logs-da-aplicacao) para a configuração +de logs. diff --git a/src/pt-BR/cookbook/configuring-webservers/nginx.md b/src/pt-BR/cookbook/configuring-webservers/nginx.md index 5b47c96c..e54edfea 100644 --- a/src/pt-BR/cookbook/configuring-webservers/nginx.md +++ b/src/pt-BR/cookbook/configuring-webservers/nginx.md @@ -1,17 +1,17 @@ -# Configuring web servers: Nginx +# Configurando servidores web: Nginx -To use [Nginx](https:/nginx.org/), install PHP as an [FPM -SAPI](https://secure.php.net/install.fpm). Use the following Nginx -configuration, replacing `path/to/app/public` with the actual path for -`app/public` and `mysite.test` with the actual hostname to serve. +Para usar o [Nginx](https:/nginx.org/), instale o PHP como [FPM +SAPI](https://secure.php.net/install.fpm). Use a configuração do Nginx a +seguir, substituindo `path/to/app/public` pelo caminho real de `app/public` +e `mysite.test` pelo hostname real a ser servido. ```nginx server { charset utf-8; client_max_body_size 128M; - listen 80; ## listen for ipv4 - #listen [::]:80 default_server ipv6only=on; ## listen for ipv6 + listen 80; ## escuta em ipv4 + #listen [::]:80 default_server ipv6only=on; ## escuta em ipv6 server_name mysite.test; root /path/to/app/public; @@ -21,17 +21,17 @@ server { error_log /path/to/basic/log/error.log; location / { - # Redirect everything that isn't a real file to index.php + # Redireciona para index.php tudo que não for um arquivo real try_files $uri $uri/ /index.php$is_args$args; } - # uncomment to avoid processing of calls to non-existing static files by Yii + # descomente para evitar que o Yii processe chamadas a arquivos estáticos inexistentes #location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ { # try_files $uri =404; #} #error_page 404 /404.html; - # deny accessing php files for the /assets directory + # bloqueia o acesso a arquivos php no diretório /assets location ~ ^/assets/.*\.php$ { deny all; } @@ -51,16 +51,17 @@ server { } ``` -When you use this configuration, also set `cgi.fix_pathinfo=0` in the -`php.ini` file to avoid many unnecessary system `stat()` calls. +Ao usar essa configuração, defina também `cgi.fix_pathinfo=0` no arquivo +`php.ini` para evitar muitas chamadas de sistema `stat()` desnecessárias. -Also, note that when running an HTTPS server, you need to add `fastcgi_param -HTTPS on;` so that Yii can detect if a connection is secure. +Além disso, ao executar um servidor HTTPS, você precisa adicionar +`fastcgi_param HTTPS on;` para que o Yii consiga detectar se a conexão é +segura. -In the above, note the usage of `fastcgi_param APP_ENV`. Since Yii3 -application templates use environment variables, this is a possible place to -set them. In production environment remember to set `APP_ENV` to `prod`. +Observe o uso de `fastcgi_param APP_ENV` acima. Como os templates de +aplicação do Yii3 usam variáveis de ambiente, este é um lugar possível para +defini-las. Em produção, lembre-se de definir `APP_ENV` como `prod`. -The Nginx `access_log` and `error_log` directives above don't capture -PHP-FPM worker output. See [application logs](general.md#application-logs) -for logging configuration. +As diretivas `access_log` e `error_log` do Nginx acima não capturam a saída +dos workers do PHP-FPM. Veja [logs da +aplicação](general.md#logs-da-aplicacao) para a configuração de logs. diff --git a/src/pt-BR/cookbook/configuring-xdebug.md b/src/pt-BR/cookbook/configuring-xdebug.md index 14d17192..1584a93e 100644 --- a/src/pt-BR/cookbook/configuring-xdebug.md +++ b/src/pt-BR/cookbook/configuring-xdebug.md @@ -1,26 +1,28 @@ -# Configuring Xdebug +# Configurando o Xdebug -Xdebug lets an IDE stop PHP code on breakpoints while the application -handles a web request, console command, or test. The IDE listens for debug -connections. PHP starts the request and Xdebug connects back to the IDE. +O Xdebug permite que a IDE pare o código PHP em breakpoints enquanto a +aplicação processa uma requisição web, um comando de console ou um teste. A +IDE escuta conexões de depuração. O PHP inicia a requisição e o Xdebug se +conecta de volta à IDE. -Yii works with the regular Xdebug setup. Configure Xdebug for the PHP -runtime that executes the code and make sure the IDE can map runtime paths -to project files. +O Yii funciona com a configuração comum do Xdebug. Configure o Xdebug no +runtime PHP que executa o código e garanta que a IDE consiga mapear os +caminhos do runtime para os arquivos do projeto. -## Check Xdebug +## Verificando o Xdebug -Use Xdebug 3. The default debug port is `9003`. +Use o Xdebug 3. A porta de depuração padrão é `9003`. -Without Docker, install Xdebug for the PHP executable that runs the -application, then check it: +Sem Docker, instale o Xdebug no executável PHP que roda a aplicação e depois +verifique: ```shell php --version php --ri xdebug ``` -In `php.ini` or an Xdebug-specific ini file, enable step debugging: +No `php.ini` ou em um arquivo ini específico do Xdebug, habilite a depuração +passo a passo: ```ini xdebug.mode=develop,debug @@ -29,27 +31,29 @@ xdebug.client_host=127.0.0.1 xdebug.client_port=9003 ``` -`trigger` starts a debug session only when a browser extension, query -parameter, cookie, or `XDEBUG_SESSION` environment variable asks for it. +`trigger` inicia uma sessão de depuração apenas quando uma extensão do +navegador, um parâmetro de query string, um cookie ou a variável de ambiente +`XDEBUG_SESSION` pedir. -With Docker, the Yii application template installs Xdebug in the development -image. Enable step debugging in `docker/dev/override.env`: +Com Docker, o template de aplicação do Yii instala o Xdebug na imagem de +desenvolvimento. Habilite a depuração passo a passo em +`docker/dev/override.env`: ```dotenv XDEBUG_MODE=develop,debug XDEBUG_CONFIG="client_host=host.docker.internal idekey=phpstorm" ``` -Keep the default `SERVER_NAME=:80` from `docker/dev/.env` unless the -application needs a different Caddy address. Set the browser port with -`DEV_PORT` in `docker/.env`: +Mantenha o `SERVER_NAME=:80` padrão de `docker/dev/.env`, a menos que a +aplicação precise de outro endereço no Caddy. Defina a porta do navegador +com `DEV_PORT` em `docker/.env`: ```dotenv DEV_PORT=80 ``` -On Linux, Docker must resolve `host.docker.internal` to the host -gateway. The current Yii application template already has this in +No Linux, o Docker precisa resolver `host.docker.internal` para o gateway do +host. O template de aplicação atual do Yii já traz isso em `docker/compose.yml`: ```yaml @@ -59,8 +63,8 @@ services: - "host.docker.internal:host-gateway" ``` -Rebuild the development image if Xdebug was added after the image had -already been built: +Reconstrua a imagem de desenvolvimento se o Xdebug foi adicionado depois que +a imagem já tinha sido construída: ```shell make build @@ -68,35 +72,36 @@ make build ## PhpStorm -In **Settings** > **PHP** > **Debug**, check that Xdebug listens on port `9003`. Start listening with +Em **Settings** > **PHP** > **Debug**, verifique se o Xdebug escuta na porta `9003`. Comece a escutar com **Run** > **Start Listening for PHP Debug Connections**. -For browser debugging, install a browser extension from **Settings** > **PHP** > **Debug**. In the extension options, -use `phpstorm` as the IDE key. +Para depurar pelo navegador, instale uma extensão de navegador a partir de **Settings** > **PHP** > **Debug**. Nas opções da extensão, +use `phpstorm` como IDE key. -When PHP runs in Docker, configure a server in **Settings** > **PHP** > **Servers**: +Quando o PHP roda no Docker, configure um servidor em **Settings** > **PHP** > **Servers**: -- Name: `localhost`. +- Nome: `localhost`. - Host: `localhost`. -- Port: `80`, or the host port configured by `DEV_PORT`. -- Debugger: `Xdebug`. -- Path mapping: map the project root on the host to `/app` in the container. +- Porta: `80`, ou a porta do host configurada em `DEV_PORT`. +- Depurador: `Xdebug`. +- Mapeamento de caminhos: mapeie a raiz do projeto no host para `/app` no + container. -Use the project root for the mapping. Mapping only `public/` leaves files -under `src/`, `config/`, and `vendor/` unmapped. The path in the container -must match the path used by PHP. In the default template, the project is -mounted into `/app`. +Use a raiz do projeto no mapeamento. Mapear só `public/` deixa sem +mapeamento os arquivos em `src/`, `config/` e `vendor/`. O caminho no +container precisa ser igual ao caminho usado pelo PHP. No template padrão, o +projeto é montado em `/app`. -For local PHP, PhpStorm usually uses the same filesystem paths as PHP, so -path mappings are usually unnecessary. +Com PHP local, o PhpStorm normalmente usa os mesmos caminhos do sistema de +arquivos que o PHP, então mapeamentos de caminhos costumam ser +desnecessários. ## VS Code -Install the [PHP -Debug](https://marketplace.visualstudio.com/items?itemName=xdebug.php-debug) -extension. +Instale a extensão [PHP +Debug](https://marketplace.visualstudio.com/items?itemName=xdebug.php-debug). -For PHP that runs on the same filesystem as VS Code, create +Para PHP rodando no mesmo sistema de arquivos que o VS Code, crie `.vscode/launch.json`: ```json @@ -113,7 +118,7 @@ For PHP that runs on the same filesystem as VS Code, create } ``` -For Docker, add path mappings: +Para Docker, adicione mapeamentos de caminhos: ```json { @@ -132,14 +137,15 @@ For Docker, add path mappings: } ``` -Start this configuration before running the web request, command, or test. +Inicie essa configuração antes de executar a requisição web, o comando ou o +teste. ## Zed -Install or enable the PHP extension in Zed. It provides the `Xdebug` debug -adapter. +Instale ou habilite a extensão PHP no Zed. Ela fornece o adaptador de +depuração `Xdebug`. -Create `.zed/debug.json`: +Crie `.zed/debug.json`: ```json [ @@ -152,7 +158,7 @@ Create `.zed/debug.json`: ] ``` -For Docker, add path mappings: +Para Docker, adicione mapeamentos de caminhos: ```json [ @@ -168,53 +174,53 @@ For Docker, add path mappings: ] ``` -Start the configuration with **debugger: start** before running the web -request, command, or test. Zed can also load debug configurations from -`.vscode/launch.json` when `.zed/debug.json` is absent. +Inicie a configuração com **debugger: start** antes de executar a requisição +web, o comando ou o teste. O Zed também consegue carregar configurações de +depuração de `.vscode/launch.json` quando `.zed/debug.json` não existe. -## Debug a web request +## Depurando uma requisição web -Without Docker: +Sem Docker: -1. Start listening in the IDE. -2. Put a breakpoint in an action or middleware. -3. Start the built-in server with an Xdebug trigger: +1. Comece a escutar na IDE. +2. Coloque um breakpoint em uma action ou middleware. +3. Inicie o servidor embutido com um trigger do Xdebug: ```shell ./yii serve --xdebug ``` -4. Open or reload the page in the browser. +4. Abra ou recarregue a página no navegador. -The `--xdebug` option passes `XDEBUG_MODE=debug XDEBUG_TRIGGER=yes` to the -built-in PHP server. If you use another web server, enable debugging with -the browser extension and reload the page. +A opção `--xdebug` passa `XDEBUG_MODE=debug XDEBUG_TRIGGER=yes` para o +servidor embutido do PHP. Se você usa outro servidor web, habilite a +depuração com a extensão do navegador e recarregue a página. -With Docker: +Com Docker: -1. Add the Docker Xdebug variables to `docker/dev/override.env`. -2. Start or restart the development containers: +1. Adicione as variáveis do Xdebug para Docker em `docker/dev/override.env`. +2. Inicie ou reinicie os containers de desenvolvimento: ```shell make up ``` -3. Start listening in the IDE. -4. Put a breakpoint in an action or middleware. -5. Enable debugging in the browser extension and reload the page. +3. Comece a escutar na IDE. +4. Coloque um breakpoint em uma action ou middleware. +5. Habilite a depuração na extensão do navegador e recarregue a página. -If the IDE accepts a connection and the breakpoint stays inactive, check -path mappings first. +Se a IDE aceita a conexão e o breakpoint continua inativo, verifique +primeiro os mapeamentos de caminhos. -## Debug a console command +## Depurando um comando de console -Without Docker, start the command with an Xdebug trigger: +Sem Docker, inicie o comando com um trigger do Xdebug: ```shell XDEBUG_MODE=debug XDEBUG_SESSION=phpstorm ./yii hello ``` -With Docker, pass the trigger to the container: +Com Docker, passe o trigger para o container: ```shell docker compose -f docker/compose.yml -f docker/dev/compose.yml run --rm \ @@ -224,24 +230,25 @@ docker compose -f docker/compose.yml -f docker/dev/compose.yml run --rm \ app ./yii hello ``` -Use the command name and arguments you need instead of `hello`. +Use o nome do comando e os argumentos de que você precisa no lugar de +`hello`. -## Debug tests +## Depurando testes -Without Docker, start the test runner with an Xdebug trigger: +Sem Docker, inicie o executor de testes com um trigger do Xdebug: ```shell XDEBUG_MODE=debug XDEBUG_SESSION=phpstorm vendor/bin/codecept run ``` -With Docker, configure `docker/test/override.env`: +Com Docker, configure `docker/test/override.env`: ```dotenv XDEBUG_MODE=debug,coverage XDEBUG_CONFIG="client_host=host.docker.internal idekey=phpstorm" ``` -Then run the test container with a trigger: +Depois, rode o container de testes com um trigger: ```shell docker compose -f docker/compose.yml -f docker/test/compose.yml run --rm \ @@ -250,29 +257,31 @@ docker compose -f docker/compose.yml -f docker/test/compose.yml run --rm \ app ./vendor/bin/codecept run ``` -Use `make test` for regular test runs. Use the explicit `docker compose` -command when you need to pass debug-only environment variables to one run. - -## Troubleshooting - -- The IDE must listen before PHP starts the request. -- Xdebug connects from PHP to the IDE. Allow incoming connections to port - `9003` in the host firewall. -- In Docker, `client_host` must be reachable from the container. The Yii - template uses `host.docker.internal`. -- For CLI and tests, set `XDEBUG_SESSION=phpstorm` or another trigger - accepted by your Xdebug configuration. -- For Docker path mappings, map the host project root to `/app`. -- To inspect connection attempts, temporarily add - `log=/app/runtime/xdebug.log` to `XDEBUG_CONFIG`. - -## See also - -- [Xdebug step debugging](https://xdebug.org/docs/step_debug) -- [PhpStorm Xdebug - documentation](https://www.jetbrains.com/help/phpstorm/configuring-xdebug.html) -- [PhpStorm servers and path - mappings](https://www.jetbrains.com/help/phpstorm/servers.html) +Use `make test` para execuções normais dos testes. Use o comando `docker +compose` explícito quando precisar passar variáveis de ambiente só de +depuração para uma execução. + +## Solução de problemas + +- A IDE precisa estar escutando antes de o PHP iniciar a requisição. +- O Xdebug se conecta do PHP para a IDE. Libere conexões de entrada na porta + `9003` no firewall do host. +- No Docker, o `client_host` precisa ser acessível a partir do container. O + template do Yii usa `host.docker.internal`. +- Para CLI e testes, defina `XDEBUG_SESSION=phpstorm` ou outro trigger + aceito pela sua configuração do Xdebug. +- Para mapeamentos de caminhos no Docker, mapeie a raiz do projeto no host + para `/app`. +- Para inspecionar as tentativas de conexão, adicione temporariamente + `log=/app/runtime/xdebug.log` ao `XDEBUG_CONFIG`. + +## Veja também + +- [Depuração passo a passo do Xdebug](https://xdebug.org/docs/step_debug) +- [Documentação do Xdebug no + PhpStorm](https://www.jetbrains.com/help/phpstorm/configuring-xdebug.html) +- [Servidores e mapeamentos de caminhos no + PhpStorm](https://www.jetbrains.com/help/phpstorm/servers.html) - [VS Code PHP Debug](https://github.com/xdebug/vscode-php-debug) -- [Zed PHP documentation](https://zed.dev/docs/languages/php#debugging) -- [Docker in application templates](../guide/tutorial/docker.md) +- [Documentação de PHP no Zed](https://zed.dev/docs/languages/php#debugging) +- [Docker nos templates de aplicação](../guide/tutorial/docker.md) diff --git a/src/pt-BR/cookbook/custom-hydrator-type-casters.md b/src/pt-BR/cookbook/custom-hydrator-type-casters.md index 941ee344..1448c31a 100644 --- a/src/pt-BR/cookbook/custom-hydrator-type-casters.md +++ b/src/pt-BR/cookbook/custom-hydrator-type-casters.md @@ -1,36 +1,38 @@ -# Custom hydrator type casters - -[Yii Hydrator](https://github.com/yiisoft/hydrator) creates objects and -fills them with data from arrays. It's used directly and by packages built -on top of it: - -- [Yii Input HTTP](https://github.com/yiisoft/input-http) fills request - input objects from query parameters, request body, and, with the help of - [Yii Router](https://github.com/yiisoft/router), route arguments. -- [Yii Form Model](https://github.com/yiisoft/form-model) provides - `FormHydrator` that fills form models from submitted data. - -The incoming data is usually "raw": HTTP requests, database rows, and queue -messages contain strings, numbers, and arrays. Before assigning a value to a -property or passing it to a constructor parameter, the hydrator converts it -to the declared type. A *type caster* performs this conversion. By writing -your own type caster, you teach the hydrator to create your types, such as -value objects, from raw data. - -## Why custom type casters - -Out of the box, the hydrator uses a composite type caster with two casters: - -- `PhpNativeTypeCaster` casts values to built-in PHP types, such as `int`, - `string`, `bool`, and `array`. -- `HydratorTypeCaster` creates nested objects from arrays using the hydrator - itself. - -That's enough for DTOs with scalar properties, but not for a rich domain -model. Consider a property typed as `UserId`, `Email`, or `Money`. The -incoming value is a string, and neither of the default casters knows how to -turn it into such an object. So you end up declaring the property as -`string` and converting it by hand wherever it's used: +# Type casters personalizados para o hydrator + +O [Yii Hydrator](https://github.com/yiisoft/hydrator) cria objetos e os +preenche com dados de arrays. Ele é usado diretamente e por pacotes +construídos sobre ele: + +- O [Yii Input HTTP](https://github.com/yiisoft/input-http) preenche objetos + de entrada da requisição a partir de parâmetros da query string, do corpo + da requisição e, com a ajuda do [Yii + Router](https://github.com/yiisoft/router), dos argumentos da rota. +- O [Yii Form Model](https://github.com/yiisoft/form-model) fornece o + `FormHydrator`, que preenche form models com os dados enviados. + +Os dados recebidos geralmente são "brutos": requisições HTTP, linhas do +banco de dados e mensagens de fila contêm strings, números e arrays. Antes +de atribuir um valor a uma propriedade ou passá-lo a um parâmetro do +construtor, o hydrator o converte para o tipo declarado. Um *type caster* +faz essa conversão. Ao escrever seu próprio type caster, você ensina o +hydrator a criar seus tipos, como value objects, a partir de dados brutos. + +## Por que type casters personalizados + +Por padrão, o hydrator usa um type caster composto com dois casters: + +- `PhpNativeTypeCaster` converte valores para tipos nativos do PHP, como + `int`, `string`, `bool` e `array`. +- `HydratorTypeCaster` cria objetos aninhados a partir de arrays usando o + próprio hydrator. + +Isso basta para DTOs com propriedades escalares, mas não para um modelo de +domínio rico. Considere uma propriedade tipada como `UserId`, `Email` ou +`Money`. O valor recebido é uma string, e nenhum dos casters padrão sabe +transformá-lo em um objeto desses. Assim, você acaba declarando a +propriedade como `string` e convertendo-a manualmente onde quer que ela seja +usada: ```php final class CreatePostForm extends FormModel @@ -38,16 +40,16 @@ final class CreatePostForm extends FormModel public string $authorId = ''; } -// In every action that uses the form: +// Em toda action que usa o formulário: try { $authorId = new UserId($form->authorId); } catch (InvalidArgumentException) { - // Report the error somehow. + // Reporte o erro de alguma forma. } ``` -With a type caster for `UserId`, you can declare the property with its real -type. The conversion happens during hydration: +Com um type caster para `UserId`, você pode declarar a propriedade com seu +tipo real. A conversão acontece durante a hidratação: ```php final class CreatePostForm extends FormModel @@ -55,77 +57,78 @@ final class CreatePostForm extends FormModel public ?UserId $authorId = null; } -// $form->authorId is already an instance of UserId. +// $form->authorId já é uma instância de UserId. ``` -The conversion logic lives in a single place. Once you register the caster, -the hydrator applies it to every property and constructor parameter of the -matching type in every object it creates. +A lógica de conversão fica em um único lugar. Depois que você registra o +caster, o hydrator o aplica a todas as propriedades e parâmetros de +construtor do tipo correspondente em todos os objetos que ele cria. -Typical use cases are: +Casos de uso típicos: -- value objects, such as entity IDs, emails, phone numbers, and money - amounts. -- types from third-party libraries, such as UUIDs, dates, or currencies. -- consistent normalization of values, for example, parsing dates in a format - specific to your application. +- value objects, como IDs de entidades, e-mails, números de telefone e + valores monetários. +- tipos de bibliotecas de terceiros, como UUIDs, datas ou moedas. +- normalização consistente de valores, por exemplo, interpretar datas em um + formato específico da sua aplicação. -## Anatomy of a type caster +## Anatomia de um type caster -A type caster implements `Yiisoft\Hydrator\TypeCaster\TypeCasterInterface` -with a single method: +Um type caster implementa `Yiisoft\Hydrator\TypeCaster\TypeCasterInterface`, +que tem um único método: ```php public function cast(mixed $value, TypeCastContext $context): Result; ``` -- `$value` is the raw value to convert. -- `$context` is a `Yiisoft\Hydrator\TypeCaster\TypeCastContext`. Its - `getReflectionType()` method returns the declared type of the target - property or constructor parameter. Use it to decide whether the caster - supports the target type. -- The method returns a `Yiisoft\Hydrator\Result`: - `Result::success($convertedValue)` if the conversion succeeded or - `Result::fail()` if the caster can't handle the value. - -Follow these rules when writing a type caster: - -1. **Check the target type first.** If the declared type isn't the one your - caster is responsible for, return `Result::fail()` right away so other - casters can handle the value. -2. **Handle both named and union types.** PHP represents a nullable type - such as `?Email` (or `Email|null`) with `ReflectionNamedType` and - `Email|string` with `ReflectionUnionType`. In the latter case, look for - your type among its subtypes. -3. **Don't handle `null` yourself.** If the value is `null`, just return - `Result::fail()`. `PhpNativeTypeCaster` returns `null` for any type that - allows it, so a `null` value assigned to `?Email` stays `null`. -4. **Accept already converted values.** If the value is already an instance - of the target type, return it as is. -5. **Fail instead of throwing.** If your caster can't convert the value, for - example, a malformed string, return `Result::fail()`. An exception would - break the whole hydration. - -Keep in mind what happens when no caster succeeds: - -- For a property, the cast fails silently. The hydrator doesn't set the - property or report an error, so the property keeps its default - value. Reporting the problem to the user is the job of the validation that - runs after hydration. See [Null and invalid - values](#null-and-invalid-values) for an example. -- For a constructor parameter, the hydrator omits the argument. If the - parameter has a default value, it's used. Otherwise, object creation - fails with `WrongConstructorArgumentsCountException`, even for a nullable - parameter without a default value. - -## Registering a type caster - -Combine type casters with `CompositeTypeCaster`. It tries the casters one by -one and uses the result of the first one that succeeds. To add your caster, -redefine `TypeCasterInterface` in the DI container configuration, for -example, in `config/common/di/hydrator.php`. The `HydratorInterface` -implementation from the container uses this chain, as do packages that rely -on it, such as Yii Input HTTP: +- `$value` é o valor bruto a ser convertido. +- `$context` é um `Yiisoft\Hydrator\TypeCaster\TypeCastContext`. Seu método + `getReflectionType()` retorna o tipo declarado da propriedade ou do + parâmetro de construtor de destino. Use-o para decidir se o caster suporta + o tipo de destino. +- O método retorna um `Yiisoft\Hydrator\Result`: + `Result::success($convertedValue)` se a conversão deu certo ou + `Result::fail()` se o caster não consegue lidar com o valor. + +Siga estas regras ao escrever um type caster: + +1. **Verifique o tipo de destino primeiro.** Se o tipo declarado não for + aquele pelo qual seu caster é responsável, retorne `Result::fail()` + imediatamente para que outros casters possam lidar com o valor. +2. **Trate tipos nomeados e tipos união.** O PHP representa um tipo anulável + como `?Email` (ou `Email|null`) com `ReflectionNamedType` e + `Email|string` com `ReflectionUnionType`. No segundo caso, procure seu + tipo entre os subtipos. +3. **Não trate `null` você mesmo.** Se o valor for `null`, apenas retorne + `Result::fail()`. O `PhpNativeTypeCaster` retorna `null` para qualquer + tipo que o permita, então um valor `null` atribuído a `?Email` continua + `null`. +4. **Aceite valores já convertidos.** Se o valor já for uma instância do + tipo de destino, retorne-o como está. +5. **Falhe em vez de lançar exceções.** Se seu caster não consegue converter + o valor, por exemplo, uma string malformada, retorne + `Result::fail()`. Uma exceção quebraria toda a hidratação. + +Tenha em mente o que acontece quando nenhum caster tem sucesso: + +- Para uma propriedade, a conversão falha silenciosamente. O hydrator não + define a propriedade nem reporta um erro, então a propriedade mantém seu + valor padrão. Reportar o problema ao usuário é papel da validação que roda + após a hidratação. Veja [Valores nulos e + inválidos](#valores-nulos-e-invalidos) para um exemplo. +- Para um parâmetro de construtor, o hydrator omite o argumento. Se o + parâmetro tiver um valor padrão, ele é usado. Caso contrário, a criação + do objeto falha com `WrongConstructorArgumentsCountException`, mesmo para + um parâmetro anulável sem valor padrão. + +## Registrando um type caster + +Combine type casters com `CompositeTypeCaster`. Ele tenta os casters um a um +e usa o resultado do primeiro que tiver sucesso. Para adicionar seu caster, +redefina `TypeCasterInterface` na configuração do container de DI, por +exemplo, em `config/common/di/hydrator.php`. A implementação de +`HydratorInterface` do container usa essa cadeia, assim como os pacotes que +dependem dela, como o Yii Input HTTP: ```php |null */ @@ -377,28 +381,28 @@ final readonly class UuidValueTypeCaster implements TypeCasterInterface } ``` -The caster follows the [rules for writing a type -caster](#anatomy-of-a-type-caster). It chooses the class to create from the -declared type. All IDs share the same UUID format, so a string alone can't -tell whether it's a user ID or a post ID. A single caster therefore serves -all `UuidValue` child classes, and adding a new ID class doesn't require -changes to the caster. For the same reason, the caster fails for a type with -several ID classes, such as `UserId|PostId`. There's no way to choose the -right one. +O caster segue as [regras para escrever um type +caster](#anatomia-de-um-type-caster). Ele escolhe a classe a ser criada a +partir do tipo declarado. Todos os IDs compartilham o mesmo formato UUID, +então uma string sozinha não diz se é um ID de usuário ou de post. Por isso, +um único caster atende todas as classes filhas de `UuidValue`, e adicionar +uma nova classe de ID não exige mudanças no caster. Pelo mesmo motivo, o +caster falha para um tipo com várias classes de ID, como +`UserId|PostId`. Não há como escolher a correta. -Register `UuidValueTypeCaster` as shown in the [Registering a type -caster](#registering-a-type-caster) section, including the [form model -configuration](#registering-for-form-models) if you use Yii Form Model. +Registre o `UuidValueTypeCaster` como mostrado na seção [Registrando um type +caster](#registrando-um-type-caster), incluindo a [configuração para form +models](#registrando-para-form-models) se você usa o Yii Form Model. -### Using the value objects +### Usando os value objects -Now any class that's populated by the hydrator can declare ID value objects -directly. +Agora qualquer classe preenchida pelo hydrator pode declarar value objects +de ID diretamente. #### Hydrator -The same string becomes a different value object depending on the type of -the property: +A mesma string se torna um value object diferente dependendo do tipo da +propriedade: ```php use App\Post\PostId; @@ -417,17 +421,18 @@ $filter = $hydrator->create(CommentFilter::class, [ 'postId' => '0192f2a4-7a4b-7c3e-9a1b-3f5c8d2e6a10', ]); -// $filter->authorId is UserId, $filter->postId is PostId. -// $filter->authorId->equals($filter->postId) returns false. +// $filter->authorId é UserId, $filter->postId é PostId. +// $filter->authorId->equals($filter->postId) retorna false. ``` -#### Request input +#### Entrada da requisição -The [Yii Input HTTP](https://github.com/yiisoft/input-http) package uses the -hydrator to fill request input objects, so the same type caster works for -query parameters, request body, and route arguments. The `RouteArgument` -attribute comes from [Yii Router](https://github.com/yiisoft/router). Extend -`AbstractInput` to get the input validated after hydration: +O pacote [Yii Input HTTP](https://github.com/yiisoft/input-http) usa o +hydrator para preencher objetos de entrada da requisição, então o mesmo type +caster funciona para parâmetros da query string, corpo da requisição e +argumentos da rota. O atributo `RouteArgument` vem do [Yii +Router](https://github.com/yiisoft/router). Estenda `AbstractInput` para que +a entrada seja validada após a hidratação: ```php getValidationResult()->isValid()) { - // Return an error response. + // Retorne uma resposta de erro. } - // $input->id is PostId, $input->authorId is UserId. + // $input->id é PostId, $input->authorId é UserId. // ... } } @@ -474,10 +479,10 @@ final readonly class Action #### Form model -`FormHydrator` from [Yii Form Model](https://github.com/yiisoft/form-model) -populates form models. Once you [register the caster for form -models](#registering-for-form-models), you can declare form properties as -value objects too: +O `FormHydrator` do [Yii Form Model](https://github.com/yiisoft/form-model) +preenche form models. Depois que você [registra o caster para form +models](#registrando-para-form-models), também pode declarar propriedades de +formulário como value objects: ```php formHydrator->populateFromPostAndValidate($form, $request)) { - // $form->authorId is UserId. + // $form->authorId é UserId. // ... } @@ -527,38 +532,40 @@ final readonly class Action } ``` -### Null and invalid values +### Valores nulos e inválidos -Here is what happens with a property declared as `?UserId` for different -input values: +Veja o que acontece com uma propriedade declarada como `?UserId` para +diferentes valores de entrada: -| Input value | Handled by | Property value | +| Valor de entrada | Tratado por | Valor da propriedade | |------------------------------------------|------------------------|----------------------------------| -| `'0192f2a4-7a4b-7c3e-9a1b-3f5c8d2e6a10'` | `UuidValueTypeCaster` | `UserId` instance | +| `'0192f2a4-7a4b-7c3e-9a1b-3f5c8d2e6a10'` | `UuidValueTypeCaster` | instância de `UserId` | | `null` | `PhpNativeTypeCaster` | `null` | -| `'not-a-uuid'` | none, all casters fail | default value, `null` in example | - -The last row is the important one: the hydrator doesn't report the malformed -value. With the `Required` rule, validation catches it with the "cannot be -blank" error. See the [request input](#request-input) and [form -model](#form-model) examples. But if the property is optional, an invalid -UUID is silently turned into `null` and is indistinguishable from a missing -value. If that's not acceptable, keep the raw value for validation: declare -the property as `string`, validate its format, and convert it to the value -object after validation. - -## When to use a type caster - -A type caster fits well when the conversion: - -- depends only on the value and the declared type. -- is the same everywhere in the application. -- doesn't need I/O, such as database queries or HTTP calls. - -Value objects for IDs, emails, and money amounts match all three. Keep the -conversion in a dedicated mapper or a domain factory instead when it: - -- needs a database lookup, for example, turning an ID into a loaded entity. -- depends on context, such as the current user. -- combines several input fields into one object. -- differs between use cases. +| `'not-a-uuid'` | nenhum, todos falham | valor padrão, `null` no exemplo | + +A última linha é a importante: o hydrator não reporta o valor malformado. +Com a regra `Required`, a validação o detecta com o erro "cannot be blank". +Veja os exemplos de [entrada da requisição](#entrada-da-requisicao) e [form +model](#form-model). Mas, se a propriedade for opcional, um UUID inválido é +silenciosamente transformado em `null` e fica indistinguível de um valor +ausente. Se isso não for aceitável, mantenha o valor bruto para validação: +declare a propriedade como `string`, valide seu formato e converta-a para o +value object após a validação. + +## Quando usar um type caster + +Um type caster é uma boa escolha quando a conversão: + +- depende apenas do valor e do tipo declarado. +- é a mesma em toda a aplicação. +- não precisa de I/O, como consultas ao banco de dados ou chamadas HTTP. + +Value objects para IDs, e-mails e valores monetários atendem aos três +critérios. Mantenha a conversão em um mapper dedicado ou em uma factory de +domínio quando ela: + +- precisa consultar o banco de dados, por exemplo, transformar um ID em uma + entidade carregada. +- depende de contexto, como o usuário atual. +- combina vários campos de entrada em um único objeto. +- difere entre casos de uso. diff --git a/src/pt-BR/cookbook/custom-migration-template.md b/src/pt-BR/cookbook/custom-migration-template.md index 99675545..d1e90b87 100644 --- a/src/pt-BR/cookbook/custom-migration-template.md +++ b/src/pt-BR/cookbook/custom-migration-template.md @@ -1,16 +1,17 @@ -# Using a custom migration template +# Usando um template de migration personalizado -The `migrate:create` command from `yiisoft/db-migration` generates migration -classes from PHP view templates. Use a custom template when your project -wants a standard header, strict class shape, comments, helper calls, or -team-specific placeholders in every new migration. +O comando `migrate:create` do `yiisoft/db-migration` gera classes de +migration a partir de templates PHP de view. Use um template personalizado +quando seu projeto quiser um cabeçalho padrão, um formato de classe rígido, +comentários, chamadas a helpers ou placeholders específicos da equipe em +toda nova migration. -This recipe assumes migrations are already configured as described in the -[Database migrations](../guide/databases/db-migrations.md) guide. +Esta receita assume que as migrations já estão configuradas como descrito no +guia [Migrations de banco de dados](../guide/databases/db-migrations.md). -## Create a template +## Crie um template -Create `resources/migration-templates/migration.php`: +Crie `resources/migration-templates/migration.php`: ```php implements RevertibleMigrationInterface } ``` -The template is a PHP file that prints the generated migration. For the -default `create` command, the most useful variables are `$className` and -`$namespace`. +O template é um arquivo PHP que imprime a migration gerada. Para o comando +`create` padrão, as variáveis mais úteis são `$className` e `$namespace`. -## Configure the generator +## Configure o gerador -Create `config/common/di/migration-generator.php`: +Crie `config/common/di/migration-generator.php`: ```php B[Reverse Proxy: Angie] - B --> C[Yii application] - B --> D[Another application] + A[Internet] --> B[Proxy reverso: Angie] + B --> C[Aplicação Yii] + B --> D[Outra aplicação] subgraph Docker Compose Project B @@ -31,31 +31,31 @@ graph LR end ``` -## Prerequisites +## Pré-requisitos -- A server with a fresh Linux distribution. -- A domain name pointing to your server's IP address. -- Docker and Docker Compose. -- Open TCP ports `80` and `443`. -- SSH access to your server. -- Basic knowledge of Docker and command-line tools. +- Um servidor com uma distribuição Linux recém-instalada. +- Um nome de domínio apontando para o IP do seu servidor. +- Docker e Docker Compose. +- Portas TCP `80` e `443` abertas. +- Acesso SSH ao seu servidor. +- Conhecimento básico de Docker e de ferramentas de linha de comando. -## Project structure +## Estrutura do projeto -The example requires a single Docker Compose configuration: +O exemplo precisa de uma única configuração do Docker Compose: ```text yii-angie-demo/ └── docker-compose.yml ``` -## Configuring Docker Compose +## Configurando o Docker Compose -Create `docker-compose.yml` with the following configuration. Replace: +Crie o `docker-compose.yml` com a configuração a seguir. Substitua: -- `admin@example.com` with your email address; -- `registry.example.com/yii-app:1.0.0` with your application image; -- `example-demo.example.com` with the domain pointing to your server. +- `admin@example.com` pelo seu endereço de e-mail; +- `registry.example.com/yii-app:1.0.0` pela imagem da sua aplicação; +- `example-demo.example.com` pelo domínio que aponta para o seu servidor. ```yaml services: @@ -92,27 +92,27 @@ volumes: angie_acme: ``` -`VIRTUAL_HOST` is the application's public domain. +`VIRTUAL_HOST` é o domínio público da aplicação. -`VIRTUAL_PORT` is the container's internal port to which Angie should proxy -requests. +`VIRTUAL_PORT` é a porta interna do container para a qual o Angie deve +encaminhar as requisições. -Angie Docker Proxy automatically discovers `VIRTUAL_HOST` and `VIRTUAL_PORT` -from the environment variables and issues certificates using the Angie ACME -module and Let's Encrypt. +O Angie Docker Proxy descobre `VIRTUAL_HOST` e `VIRTUAL_PORT` +automaticamente pelas variáveis de ambiente e emite certificados usando o +módulo ACME do Angie e o Let's Encrypt. -## Starting the services +## Subindo os serviços -Start the proxy and application containers: +Suba os containers do proxy e da aplicação: ```bash docker compose up -d ``` -## Adding another application +## Adicionando outra aplicação -To expose another application, add it to `services` in `docker-compose.yml` -and attach it to the `proxy` network: +Para expor outra aplicação, adicione-a em `services` no `docker-compose.yml` +e conecte-a à rede `proxy`: ```yaml services: @@ -125,61 +125,62 @@ services: - proxy ``` -Apply the changes: +Aplique as alterações: ```bash docker compose up -d ``` -## How it works +## Como funciona -Angie Docker Proxy monitors the Docker API and discovers containers -configured with `VIRTUAL_HOST` and `VIRTUAL_PORT`. It generates the Angie -configuration, obtains TLS certificates using ACME, and forwards incoming -requests to the corresponding containers through the shared Docker network. +O Angie Docker Proxy monitora a API do Docker e descobre os containers +configurados com `VIRTUAL_HOST` e `VIRTUAL_PORT`. Ele gera a configuração +do Angie, obtém certificados TLS via ACME e encaminha as requisições +recebidas para os containers correspondentes pela rede Docker compartilhada. -When containers are added, removed, or updated, the proxy regenerates its -configuration and performs a graceful reload. Existing connections continue -to be handled while the updated configuration is applied. +Quando containers são adicionados, removidos ou atualizados, o proxy gera a +configuração de novo e faz um reload gracioso. As conexões existentes +continuam sendo atendidas enquanto a configuração atualizada é aplicada. -For configuration options and implementation details, see the [Angie Docker -Proxy documentation](https://hub.docker.com/r/angiesoftware/proxy). +Para opções de configuração e detalhes de implementação, veja a +[documentação do Angie Docker +Proxy](https://hub.docker.com/r/angiesoftware/proxy). -## Verification +## Verificação -Check the containers: +Verifique os containers: ```bash docker compose ps ``` -Check the HTTP redirect: +Verifique o redirecionamento HTTP: ```bash curl -I http://example-demo.example.com/ ``` -Expected result: +Resultado esperado: ```text HTTP/1.1 301 Moved Permanently Location: https://example-demo.example.com/ ``` -Check HTTPS: +Verifique o HTTPS: ```bash curl -I https://example-demo.example.com/ ``` -Expected result: +Resultado esperado: ```text HTTP/1.1 200 OK Server: Angie/... ``` -Check the certificate: +Verifique o certificado: ```bash echo | openssl s_client \ @@ -188,7 +189,7 @@ echo | openssl s_client \ | openssl x509 -noout -issuer -subject -dates ``` -Expected issuer: +Emissor esperado: ```text Let's Encrypt @@ -197,38 +198,38 @@ Let's Encrypt ## Logs -Proxy logs: +Logs do proxy: ```bash docker compose logs -f angie-proxy ``` -## Stopping the services +## Parando os serviços -Stop the services: +Pare os serviços: ```bash docker compose down ``` -Stop the services and remove the certificates: +Pare os serviços e remova os certificados: ```bash docker compose down -v ``` -## Limitations +## Limitações -This setup is intended for Docker Compose. Kubernetes doesn't expose -workloads through the Docker API and requires an Ingress or Gateway API -controller. Docker Swarm also uses the Docker API, but Swarm deployment -isn't covered in this guide. +Esta configuração é feita para o Docker Compose. O Kubernetes não expõe +workloads pela API do Docker e exige um controller de Ingress ou de Gateway +API. O Docker Swarm também usa a API do Docker, mas o deploy no Swarm não é +coberto neste guia. -## For more information +## Para mais informações -- [Angie Docker Proxy - documentation](https://hub.docker.com/r/angiesoftware/proxy) -- [Yii Application Template](https://github.com/yiisoft/app) -- [Docker in Yii Application - Templates](https://yiisoft.github.io/docs/guide/tutorial/docker.html) -- [Docker Compose documentation](https://docs.docker.com/compose/) +- [Documentação do Angie Docker + Proxy](https://hub.docker.com/r/angiesoftware/proxy) +- [Template de aplicação do Yii](https://github.com/yiisoft/app) +- [Docker nos templates de aplicação do + Yii](https://yiisoft.github.io/docs/guide/tutorial/docker.html) +- [Documentação do Docker Compose](https://docs.docker.com/compose/) diff --git a/src/pt-BR/cookbook/deployment/autoscaling.md b/src/pt-BR/cookbook/deployment/autoscaling.md index 4ba2993f..ade2eb4b 100644 --- a/src/pt-BR/cookbook/deployment/autoscaling.md +++ b/src/pt-BR/cookbook/deployment/autoscaling.md @@ -1,40 +1,40 @@ -# Configuring an application for autoscaling +# Configurando uma aplicação para autoscaling -Autoscaling works when any application instance can handle any request and -can be added or removed without special local state. In Yii applications -this mostly means keeping runtime state outside the container or VM, making -health checks cheap, and running migrations and workers separately from web -replicas. +O autoscaling funciona quando qualquer instância da aplicação consegue +atender qualquer requisição e pode ser adicionada ou removida sem estado +local especial. Em aplicações Yii, isso significa principalmente manter o +estado de runtime fora do container ou da VM, deixar os health checks +baratos e rodar migrations e workers separados das réplicas web. -## Keep web instances stateless +## Mantenha as instâncias web sem estado -Do not store user-visible state on the local filesystem of a web -instance. Local files disappear when an instance is replaced and are not -visible to other replicas. +Não guarde estado visível ao usuário no sistema de arquivos local de uma +instância web. Arquivos locais somem quando uma instância é substituída e +não ficam visíveis para as outras réplicas. -Move these resources to shared services: +Mova estes recursos para serviços compartilhados: -- Sessions: use a shared session handler when users can move between - replicas. See [Sessions](../../guide/runtime/sessions.md) and prefer - closing sessions early. -- Cache: use Redis, Memcached, database, or another shared PSR-16 cache - backend for data that must be consistent across replicas. See [Data - caching](../../guide/caching/data.md). -- Uploads: store files in object storage, a shared volume, or a service - dedicated to file storage. Local `runtime` or `public/uploads` directories - are safe only for temporary files. -- Generated assets: build them into the image or publish them to shared - storage/CDN during deployment. -- Logs: write to stdout/stderr or a central log target. Do not depend on - files inside a short-lived instance. +- Sessões: use um handler de sessão compartilhado quando os usuários puderem + alternar entre réplicas. Veja [Sessões](../../guide/runtime/sessions.md) e + prefira fechar as sessões cedo. +- Cache: use Redis, Memcached, banco de dados ou outro backend de cache + PSR-16 compartilhado para dados que precisam ser consistentes entre as + réplicas. Veja [Cache de dados](../../guide/caching/data.md). +- Uploads: guarde arquivos em object storage, em um volume compartilhado ou + em um serviço dedicado ao armazenamento de arquivos. Os diretórios locais + `runtime` ou `public/uploads` só são seguros para arquivos temporários. +- Assets gerados: inclua-os na imagem ou publique-os em um armazenamento + compartilhado/CDN durante o deploy. +- Logs: escreva em stdout/stderr ou em um destino de log central. Não + dependa de arquivos dentro de uma instância de vida curta. -Sticky sessions can reduce immediate pressure, but they are not a substitute -for shared state. A replacement instance or deployment rollout still breaks -local session and upload storage. +Sticky sessions podem aliviar a pressão imediata, mas não substituem o +estado compartilhado. Uma instância substituta ou o rollout de um deploy +ainda quebram o armazenamento local de sessões e de uploads. -## Add health endpoints +## Adicione endpoints de saúde -Use a cheap liveness endpoint for the load balancer or orchestrator: +Use um endpoint de liveness barato para o load balancer ou o orquestrador: ```php B[Reverse Proxy: Caddy] + A[Internet] --> B[Proxy reverso: Caddy] B --> C[app1.example.com] B --> D[app2.example.com] @@ -19,43 +19,44 @@ graph LR end ``` -## Prerequisites +## Pré-requisitos -- A server with a fresh installation of a Linux distribution (Ubuntu 22.04 - LTS or later recommended) -- A domain name pointing to your server's IP address -- SSH access to your server -- Basic knowledge of Docker and command-line tools +- Um servidor com uma distribuição Linux recém-instalada (recomendado Ubuntu + 22.04 LTS ou mais recente) +- Um nome de domínio apontando para o IP do seu servidor +- Acesso SSH ao seu servidor +- Conhecimento básico de Docker e de ferramentas de linha de comando -## Server preparation +## Preparando o servidor -### Install Docker +### Instale o Docker -For installation instructions, see the [official Docker -documentation](https://docs.docker.com/engine/install/ubuntu/). +Para as instruções de instalação, veja a [documentação oficial do +Docker](https://docs.docker.com/engine/install/ubuntu/). -### Initialize Docker Swarm +### Inicialize o Docker Swarm -Initialize your server as a Docker Swarm manager: +Inicialize o seu servidor como manager do Docker Swarm: ```bash docker swarm init --advertise-addr ``` -Replace `` with your server's public IP address. +Substitua `` pelo IP público do seu servidor. -### Set up the reverse proxy network +### Configure a rede do proxy reverso -Create a dedicated overlay network for reverse proxy to communicate with -your services: +Crie uma rede overlay dedicada para o proxy reverso se comunicar com os seus +serviços: ```bash docker network create --driver=overlay reverse_proxy_public ``` -## Setting up Caddy as reverse proxy +## Configurando o Caddy como proxy reverso -To deploy Caddy as reverse proxy create a file `caddy-stack.yml`: +Para fazer o deploy do Caddy como proxy reverso, crie um arquivo +`caddy-stack.yml`: ```yaml services: @@ -78,15 +79,15 @@ networks: external: true ``` -Deploy Caddy: +Faça o deploy do Caddy: ```bash docker stack deploy -c caddy-stack.yml caddy ``` -Caddy automatically discovers services with Caddy labels and sets up HTTPS -using Let's Encrypt. Yii3 application templates are using Caddy labels by -default: +O Caddy descobre automaticamente os serviços com labels do Caddy e configura +HTTPS usando o Let's Encrypt. Os templates de aplicação do Yii3 usam labels +do Caddy por padrão: ```yaml deploy: @@ -96,17 +97,17 @@ deploy: ``` > [!IMPORTANT] -> Make sure your domain DNS records are configured and pointing to your server before deploying services with -> Caddy labels, as Let's Encrypt requires domain validation. +> Garanta que os registros DNS do seu domínio estejam configurados e apontando para o seu servidor antes de fazer o deploy de serviços com +> labels do Caddy, porque o Let's Encrypt exige a validação do domínio. -## Setting up a container registry +## Configurando um registro de containers -You need a container registry to store your Docker images. Choose one of the -following options. +Você precisa de um registro de containers para guardar as suas imagens +Docker. Escolha uma das opções a seguir. -### Option 1: Using Forgejo +### Opção 1: usando o Forgejo -To deploy Forgejo create a file `forgejo-stack.yml`: +Para fazer o deploy do Forgejo, crie um arquivo `forgejo-stack.yml`: ```yaml services: @@ -131,21 +132,21 @@ networks: external: true ``` -Deploy Forgejo: +Faça o deploy do Forgejo: ```bash docker stack deploy -c forgejo-stack.yml forgejo ``` -Replace `git.example.com` with your desired subdomain. +Substitua `git.example.com` pelo subdomínio desejado. -After deployment, access Forgejo at `https://git.example.com` and complete -the initial setup. Make sure to enable the container registry in the -settings. +Depois do deploy, acesse o Forgejo em `https://git.example.com` e conclua a +configuração inicial. Não esqueça de habilitar o registro de containers nas +configurações. -### Option 2: Using Gitea +### Opção 2: usando o Gitea -To deploy Gitea create a file `gitea-stack.yml`: +Para fazer o deploy do Gitea, crie um arquivo `gitea-stack.yml`: ```yaml services: @@ -170,30 +171,31 @@ networks: external: true ``` -Deploy Gitea: +Faça o deploy do Gitea: ```bash docker stack deploy -c gitea-stack.yml gitea ``` -Replace `git.example.com` with your desired subdomain. +Substitua `git.example.com` pelo subdomínio desejado. -After deployment, access Gitea at `https://git.example.com` and complete the -initial setup. Make sure to enable the container registry in the settings. +Depois do deploy, acesse o Gitea em `https://git.example.com` e conclua a +configuração inicial. Não esqueça de habilitar o registro de containers nas +configurações. -## Configuring your Yii application +## Configurando a sua aplicação Yii -### Update the Makefile configuration +### Atualize a configuração do Makefile -The [Yii application template](https://github.com/yiisoft/app) includes a -Makefile with deployment commands. Update the `docker/.env` file in your -project: +O [template de aplicação do Yii](https://github.com/yiisoft/app) inclui um +Makefile com comandos de deploy. Atualize o arquivo `docker/.env` do seu +projeto: ```bash STACK_NAME=myapp # -# Production +# Produção # PROD_HOST=app.example.com @@ -203,36 +205,37 @@ IMAGE=git.example.com/username/myapp IMAGE_TAG=latest ``` -Replace the values: - `STACK_NAME`: A unique name for your application stack -- `PROD_HOST`: The domain name where your app will be accessible - -`PROD_SSH`: SSH connection string to your server (format: `ssh://user@host`) -- `IMAGE`: Full path to your container image in the registry - `IMAGE_TAG`: -Image tag, typically `latest` or a version number +Substitua os valores: - `STACK_NAME`: um nome único para a stack da sua +aplicação - `PROD_HOST`: o nome de domínio em que a aplicação vai ficar +acessível - `PROD_SSH`: a string de conexão SSH com o seu servidor (formato: +`ssh://user@host`) - `IMAGE`: o caminho completo da imagem do container no +registro - `IMAGE_TAG`: a tag da imagem, normalmente `latest` ou um número +de versão -### Configure the production environment +### Configure o ambiente de produção -Update `docker/prod/.env` with your production environment variables: +Atualize o `docker/prod/.env` com as variáveis de ambiente de produção: ```bash APP_ENV=prod YII_DEBUG=false YII_ENV=prod -# Database configuration +# Configuração do banco de dados DB_HOST=db DB_NAME=myapp DB_USER=myapp DB_PASSWORD=secure_password_here -# Add other environment-specific variables +# Adicione outras variáveis específicas do ambiente ``` > [!WARNING] -> Never commit sensitive credentials to version control. Use `docker/prod/override.env` for sensitive values and add it to `.gitignore`. +> Nunca faça commit de credenciais sensíveis no controle de versão. Use `docker/prod/override.env` para valores sensíveis e adicione-o ao `.gitignore`. -### Review the production Docker Compose configuration +### Revise a configuração do Docker Compose de produção -The default `docker/prod/compose.yml` includes: +O `docker/prod/compose.yml` padrão inclui: ```yaml services: @@ -271,19 +274,19 @@ services: caddy.reverse_proxy: "{{upstreams 80}}" ``` -This configuration: -- Runs 2 replicas for high availability -- Uses a rolling update strategy with automatic rollback on failure -- Configures `labels` for automatic HTTPS on the reverse proxy -- Disables obtaining of HTTPs certificates on the container itself - since proxy communicates with the container via HTTP. That is `auto_https off`. +Essa configuração: +- Roda 2 réplicas para alta disponibilidade +- Usa uma estratégia de rolling update com rollback automático em caso de falha +- Configura `labels` para HTTPS automático no proxy reverso +- Desabilita a obtenção de certificados HTTPS no próprio container, + já que o proxy se comunica com o container via HTTP. Isso é o `auto_https off`. -If you need a database, add it to the stack: +Se você precisa de um banco de dados, adicione-o à stack: ```yaml services: app: - # ... existing configuration ... + # ... configuração existente ... db: image: postgres:18-alpine @@ -312,70 +315,70 @@ secrets: external: true ``` -Create the database password secret on the server: +Crie o secret com a senha do banco de dados no servidor: ```bash echo "your_secure_password" | docker secret create db_password - ``` -## Building and pushing the image +## Construindo e enviando a imagem -### Set up Docker login on your local machine +### Configure o login do Docker na sua máquina local -Configure Docker to authenticate with your container registry: +Configure o Docker para se autenticar no seu registro de containers: ```bash docker login git.example.com ``` -Enter your username and password when prompted. +Informe o seu usuário e a sua senha quando solicitado. -### Build the production image +### Construa a imagem de produção -Use the Makefile to build your production image: +Use o Makefile para construir a imagem de produção: ```bash make prod-build ``` -This runs the command defined in the Makefile: +Isso executa o comando definido no Makefile: ```bash docker build --file docker/Dockerfile --target prod --pull -t ${IMAGE}:${IMAGE_TAG} . ``` -The Dockerfile uses a multi-stage build: 1. Installs Composer dependencies -in a builder stage 2. Creates a minimal production image with only the -necessary files 3. Runs as a non-root user (`www-data`) +O Dockerfile usa um build multi-stage: 1. Instala as dependências do +Composer em um estágio de build 2. Cria uma imagem de produção mínima, só +com os arquivos necessários 3. Roda como um usuário não root (`www-data`) -### Push the image to the registry +### Envie a imagem para o registro -Push your built image to the container registry: +Envie a imagem construída para o registro de containers: ```bash make prod-push ``` -This executes: +Isso executa: ```bash docker push ${IMAGE}:${IMAGE_TAG} ``` -## Deploying to Docker Swarm +## Fazendo deploy no Docker Swarm -### Configure SSH access +### Configure o acesso SSH -Set up SSH key-based authentication to your server: +Configure a autenticação por chave SSH no seu servidor: ```bash -# Generate SSH key (if you don't have one) +# Gera uma chave SSH (se você ainda não tiver uma) ssh-keygen -t ed25519 -C "your_email@example.com" -# Copy the key to your server +# Copia a chave para o seu servidor ssh-copy-id user@your-server-ip -# Add the SSH host to your SSH config (~/.ssh/config) +# Adiciona o host SSH à sua configuração SSH (~/.ssh/config) cat >> ~/.ssh/config << EOF Host docker-web HostName your-server-ip @@ -384,86 +387,87 @@ Host docker-web EOF ``` -### Set up Docker context +### Configure o contexto do Docker -Create a Docker context for remote deployment: +Crie um contexto do Docker para o deploy remoto: ```bash docker context create swarm-prod --docker "host=ssh://docker-web" ``` -Alternatively, configure the `DOCKER_HOST` environment variable: +Como alternativa, configure a variável de ambiente `DOCKER_HOST`: ```bash export DOCKER_HOST=ssh://docker-web ``` -### Deploy the application +### Faça o deploy da aplicação -Deploy your application stack to Docker Swarm: +Faça o deploy da stack da sua aplicação no Docker Swarm: ```bash make prod-deploy ``` -This executes: +Isso executa: ```bash docker -H ${PROD_SSH} stack deploy --prune --detach=false --with-registry-auth -c docker/compose.yml -c docker/prod/compose.yml ${STACK_NAME} ``` -The `--with-registry-auth` flag ensures the Swarm nodes can pull images from -your private registry. +A flag `--with-registry-auth` garante que os nós do Swarm consigam baixar +imagens do seu registro privado. -### Verify the deployment +### Verifique o deploy -Check the status of your services: +Verifique o status dos seus serviços: ```bash docker -H ssh://docker-web service ls docker -H ssh://docker-web service ps ${STACK_NAME}_app ``` -View logs: +Veja os logs: ```bash docker -H ssh://docker-web service logs ${STACK_NAME}_app ``` -## Monitoring and maintenance +## Monitoramento e manutenção -### View service logs +### Veja os logs do serviço ```bash -# View all logs +# Mostra todos os logs docker -H ssh://docker-web service logs -f ${STACK_NAME}_app -# View logs from the last 100 lines +# Mostra as últimas 100 linhas de log docker -H ssh://docker-web service logs --tail 100 ${STACK_NAME}_app -# View logs with timestamps +# Mostra os logs com timestamps docker -H ssh://docker-web service logs -t ${STACK_NAME}_app ``` -### Scale the application +### Escale a aplicação -Adjust the number of replicas: +Ajuste o número de réplicas: ```bash docker -H ssh://docker-web service scale ${STACK_NAME}_app=3 ``` -Or update the `replicas` value in `docker/prod/compose.yml` and redeploy. +Ou atualize o valor de `replicas` em `docker/prod/compose.yml` e faça o +deploy de novo. -### Resource limits +### Limites de recursos -Add resource limits to prevent containers from consuming all server -resources. Update `docker/prod/compose.yml`: +Adicione limites de recursos para evitar que os containers consumam todos os +recursos do servidor. Atualize o `docker/prod/compose.yml`: ```yaml services: app: - # ... existing configuration ... + # ... configuração existente ... deploy: resources: limits: @@ -474,20 +478,20 @@ services: memory: 256M ``` -## Security considerations +## Considerações de segurança -### Use Docker secrets for sensitive data +### Use Docker secrets para dados sensíveis -Instead of environment variables, use Docker secrets for sensitive -information: +Em vez de variáveis de ambiente, use Docker secrets para informações +sensíveis: ```bash -# Create secrets +# Cria os secrets echo "database_password" | docker secret create db_password - echo "api_key" | docker secret create api_key - ``` -Update `docker/prod/compose.yml`: +Atualize o `docker/prod/compose.yml`: ```yaml services: @@ -503,89 +507,89 @@ secrets: external: true ``` -Access secrets in your application at `/run/secrets/secret_name`. +Acesse os secrets na sua aplicação em `/run/secrets/secret_name`. -### Set up a firewall +### Configure um firewall -Configure UFW (Uncomplicated Firewall) on your server: +Configure o UFW (Uncomplicated Firewall) no seu servidor: ```bash -# Allow SSH +# Libera SSH sudo ufw allow 22/tcp -# Allow HTTP and HTTPS +# Libera HTTP e HTTPS sudo ufw allow 80/tcp sudo ufw allow 443/tcp -# Allow Docker Swarm ports (if you plan to add more nodes) +# Libera as portas do Docker Swarm (se você pretende adicionar mais nós) sudo ufw allow 2377/tcp sudo ufw allow 7946/tcp sudo ufw allow 7946/udp sudo ufw allow 4789/udp -# Enable the firewall +# Habilita o firewall sudo ufw enable ``` -### Keep the system updated +### Mantenha o sistema atualizado -Regularly update your server and Docker: +Atualize regularmente o seu servidor e o Docker: ```bash -# Update system packages +# Atualiza os pacotes do sistema sudo apt-get update && sudo apt-get upgrade -y -# Update Docker images +# Atualiza as imagens Docker docker -H ssh://docker-web service update --image ${IMAGE}:${IMAGE_TAG} ${STACK_NAME}_app ``` -## Troubleshooting +## Solução de problemas -### Service won't start +### O serviço não sobe -Check service events and logs: +Verifique os eventos e os logs do serviço: ```bash docker -H ssh://docker-web service ps ${STACK_NAME}_app --no-trunc docker -H ssh://docker-web service logs ${STACK_NAME}_app ``` -Common issues: - **Image pull errors**: Verify registry authentication with -`docker -H ssh://docker-web login` - **Port conflicts**: Ensure no other -services are using ports 80/443 - **Resource constraints**: Check available -resources with `docker -H ssh://docker-web node ls` +Problemas comuns: - **Erros ao baixar a imagem**: verifique a autenticação +no registro com `docker -H ssh://docker-web login` - **Conflitos de porta**: +garanta que nenhum outro serviço esteja usando as portas 80/443 - +**Limitação de recursos**: verifique os recursos disponíveis com `docker -H +ssh://docker-web node ls` -### SSL certificate issues +### Problemas com certificados SSL -If Caddy can't obtain certificates: - Verify DNS is pointing to your server -- Check that ports 80 and 443 are accessible from the internet - Ensure the -email in the Let's Encrypt configuration is valid - Check logs: `docker -H -ssh://docker-web service logs caddy` +Se o Caddy não consegue obter os certificados: - Verifique se o DNS aponta +para o seu servidor - Verifique se as portas 80 e 443 estão acessíveis pela +internet - Garanta que o e-mail na configuração do Let's Encrypt é válido - +Verifique os logs: `docker -H ssh://docker-web service logs caddy` -### Container registry connection issues +### Problemas de conexão com o registro de containers -Test registry connectivity: +Teste a conectividade com o registro: ```bash -# From your local machine +# Na sua máquina local docker pull git.example.com/username/myapp:latest -# From the server +# No servidor docker -H ssh://docker-web pull git.example.com/username/myapp:latest ``` ## Resumo -You've successfully deployed a Yii application to Docker Swarm with: - A -container registry (Forgejo or Gitea) - Automatic HTTPS via Caddy - -Zero-downtime deployments with rolling updates - High availability with -multiple replicas +Você fez o deploy de uma aplicação Yii no Docker Swarm com: - Um registro de +containers (Forgejo ou Gitea) - HTTPS automático via Caddy - Deploys sem +downtime com rolling updates - Alta disponibilidade com várias réplicas -The Makefile commands simplify the deployment workflow: - `make prod-build` -- Build the production image - `make prod-push` - Push to the registry - -`make prod-deploy` - Deploy to Docker Swarm +Os comandos do Makefile simplificam o fluxo de deploy: - `make prod-build` - +Constrói a imagem de produção - `make prod-push` - Envia para o registro - +`make prod-deploy` - Faz o deploy no Docker Swarm -For more information, see: - [Yii Application -Template](https://github.com/yiisoft/app) - [Docker Swarm -Documentation](https://docs.docker.com/engine/swarm/) - [Caddy Docker +Para mais informações, veja: - [Template de aplicação do +Yii](https://github.com/yiisoft/app) - [Documentação do Docker +Swarm](https://docs.docker.com/engine/swarm/) - [Caddy Docker Proxy](https://github.com/lucaslorentz/caddy-docker-proxy) diff --git a/src/pt-BR/cookbook/deployment/docker-swarm-traefik.md b/src/pt-BR/cookbook/deployment/docker-swarm-traefik.md index f5c725de..c85d10df 100644 --- a/src/pt-BR/cookbook/deployment/docker-swarm-traefik.md +++ b/src/pt-BR/cookbook/deployment/docker-swarm-traefik.md @@ -1,14 +1,14 @@ -# Deploying Yii applications to Docker Swarm and Traefik +# Fazendo deploy de aplicações Yii no Docker Swarm com Traefik -This guide walks you through deploying a Yii application to [Docker -Swarm](https://docs.docker.com/engine/swarm/) starting from a blank server, -using [Traefik](https://traefik.io/traefik) as a reverse proxy and deploying -from a container registry ([Forgejo](https://forgejo.org/) or -[Gitea](https://about.gitea.com/)). +Este guia mostra como fazer o deploy de uma aplicação Yii no [Docker +Swarm](https://docs.docker.com/engine/swarm/) a partir de um servidor +vazio, usando o [Traefik](https://traefik.io/traefik) como proxy reverso e +fazendo o deploy a partir de um registro de containers +([Forgejo](https://forgejo.org/) ou [Gitea](https://about.gitea.com/)). ```mermaid graph LR - A[Internet] --> B[Reverse Proxy: Traefik] + A[Internet] --> B[Proxy reverso: Traefik] B --> C[app1.example.com] B --> D[app2.example.com] @@ -19,43 +19,44 @@ graph LR end ``` -## Prerequisites +## Pré-requisitos -- A server with a fresh installation of a Linux distribution (Ubuntu 22.04 - LTS or later recommended) -- A domain name pointing to your server's IP address -- SSH access to your server -- Basic knowledge of Docker and command-line tools +- Um servidor com uma distribuição Linux recém-instalada (recomendado Ubuntu + 22.04 LTS ou mais recente) +- Um nome de domínio apontando para o IP do seu servidor +- Acesso SSH ao seu servidor +- Conhecimento básico de Docker e de ferramentas de linha de comando -## Server preparation +## Preparando o servidor -### Install Docker +### Instale o Docker -For installation instructions, see the [official Docker -documentation](https://docs.docker.com/engine/install/ubuntu/). +Para as instruções de instalação, veja a [documentação oficial do +Docker](https://docs.docker.com/engine/install/ubuntu/). -### Initialize Docker Swarm +### Inicialize o Docker Swarm -Initialize your server as a Docker Swarm manager: +Inicialize o seu servidor como manager do Docker Swarm: ```bash docker swarm init --advertise-addr ``` -Replace `` with your server's public IP address. +Substitua `` pelo IP público do seu servidor. -### Set up the reverse proxy network +### Configure a rede do proxy reverso -Create a dedicated overlay network for reverse proxy to communicate with -your services: +Crie uma rede overlay dedicada para o proxy reverso se comunicar com os seus +serviços: ```bash docker network create --driver=overlay reverse_proxy_public ``` -## Setting up Traefik as reverse proxy +## Configurando o Traefik como proxy reverso -To deploy Traefik as reverse proxy create a file `traefik-stack.yml`: +Para fazer o deploy do Traefik como proxy reverso, crie um arquivo +`traefik-stack.yml`: ```yaml services: @@ -93,20 +94,20 @@ networks: external: true ``` -Deploy Traefik: +Faça o deploy do Traefik: ```bash docker stack deploy -c traefik-stack.yml traefik ``` -## Setting up a container registry +## Configurando um registro de containers -You need a container registry to store your Docker images. Choose one of the -following options. +Você precisa de um registro de containers para guardar as suas imagens +Docker. Escolha uma das opções a seguir. -### Option 1: Using Forgejo +### Opção 1: usando o Forgejo -To deploy Forgejo create a file `forgejo-stack.yml`: +Para fazer o deploy do Forgejo, crie um arquivo `forgejo-stack.yml`: ```yaml services: @@ -134,21 +135,21 @@ networks: external: true ``` -Deploy Forgejo: +Faça o deploy do Forgejo: ```bash docker stack deploy -c forgejo-stack.yml forgejo ``` -Replace `git.example.com` with your desired subdomain. +Substitua `git.example.com` pelo subdomínio desejado. -After deployment, access Forgejo at `https://git.example.com` and complete -the initial setup. Make sure to enable the container registry in the -settings. +Depois do deploy, acesse o Forgejo em `https://git.example.com` e conclua a +configuração inicial. Não esqueça de habilitar o registro de containers nas +configurações. -### Option 2: Using Gitea +### Opção 2: usando o Gitea -To deploy Gitea create a file `gitea-stack.yml`: +Para fazer o deploy do Gitea, crie um arquivo `gitea-stack.yml`: ```yaml services: @@ -176,30 +177,31 @@ networks: external: true ``` -Deploy Gitea: +Faça o deploy do Gitea: ```bash docker stack deploy -c gitea-stack.yml gitea ``` -Replace `git.example.com` with your desired subdomain. +Substitua `git.example.com` pelo subdomínio desejado. -After deployment, access Gitea at `https://git.example.com` and complete the -initial setup. Make sure to enable the container registry in the settings. +Depois do deploy, acesse o Gitea em `https://git.example.com` e conclua a +configuração inicial. Não esqueça de habilitar o registro de containers nas +configurações. -## Configuring your Yii application +## Configurando a sua aplicação Yii -### Update the Makefile configuration +### Atualize a configuração do Makefile -The [Yii application template](https://github.com/yiisoft/app) includes a -Makefile with deployment commands. Update the `docker/.env` file in your -project: +O [template de aplicação do Yii](https://github.com/yiisoft/app) inclui um +Makefile com comandos de deploy. Atualize o arquivo `docker/.env` do seu +projeto: ```bash STACK_NAME=myapp # -# Production +# Produção # PROD_HOST=app.example.com @@ -209,37 +211,38 @@ IMAGE=git.example.com/username/myapp IMAGE_TAG=latest ``` -Replace the values: - `STACK_NAME`: A unique name for your application stack -- `PROD_HOST`: The domain name where your app will be accessible - -`PROD_SSH`: SSH connection string to your server (format: `ssh://user@host`) -- `IMAGE`: Full path to your container image in the registry - `IMAGE_TAG`: -Image tag, typically `latest` or a version number +Substitua os valores: - `STACK_NAME`: um nome único para a stack da sua +aplicação - `PROD_HOST`: o nome de domínio em que a aplicação vai ficar +acessível - `PROD_SSH`: a string de conexão SSH com o seu servidor (formato: +`ssh://user@host`) - `IMAGE`: o caminho completo da imagem do container no +registro - `IMAGE_TAG`: a tag da imagem, normalmente `latest` ou um número +de versão -### Configure the production environment +### Configure o ambiente de produção -Update `docker/prod/.env` with your production environment variables: +Atualize o `docker/prod/.env` com as variáveis de ambiente de produção: ```bash APP_ENV=prod YII_DEBUG=false YII_ENV=prod -# Database configuration +# Configuração do banco de dados DB_HOST=db DB_NAME=myapp DB_USER=myapp DB_PASSWORD=secure_password_here -# Add other environment-specific variables +# Adicione outras variáveis específicas do ambiente ``` > [!WARNING] -> Never commit sensitive credentials to version control. Use `docker/prod/override.env` for sensitive values and add it to `.gitignore`. +> Nunca faça commit de credenciais sensíveis no controle de versão. Use `docker/prod/override.env` para valores sensíveis e adicione-o ao `.gitignore`. -### Review the production Docker Compose configuration +### Revise a configuração do Docker Compose de produção -When using Traefik, you'll need to modify the Yii application's -`docker/prod/compose.yml` to use Traefik labels instead of Caddy labels: +Ao usar o Traefik, você precisa alterar o `docker/prod/compose.yml` da +aplicação Yii para usar labels do Traefik em vez de labels do Caddy: ```yaml services: @@ -281,19 +284,19 @@ services: - "traefik.http.services.app.loadbalancer.server.port=80" ``` -This configuration: -- Runs 2 replicas for high availability -- Uses a rolling update strategy with automatic rollback on failure -- Configures `labels` for automatic HTTPS on the reverse proxy -- Disables obtaining of HTTPs certificates on the container itself - since proxy communicates with the container via HTTP. That is `auto_https off`. +Essa configuração: +- Roda 2 réplicas para alta disponibilidade +- Usa uma estratégia de rolling update com rollback automático em caso de falha +- Configura `labels` para HTTPS automático no proxy reverso +- Desabilita a obtenção de certificados HTTPS no próprio container, + já que o proxy se comunica com o container via HTTP. Isso é o `auto_https off`. -If you need a database, add it to the stack: +Se você precisa de um banco de dados, adicione-o à stack: ```yaml services: app: - # ... existing configuration ... + # ... configuração existente ... db: image: postgres:18-alpine @@ -322,70 +325,70 @@ secrets: external: true ``` -Create the database password secret on the server: +Crie o secret com a senha do banco de dados no servidor: ```bash echo "your_secure_password" | docker secret create db_password - ``` -## Building and pushing the image +## Construindo e enviando a imagem -### Set up Docker login on your local machine +### Configure o login do Docker na sua máquina local -Configure Docker to authenticate with your container registry: +Configure o Docker para se autenticar no seu registro de containers: ```bash docker login git.example.com ``` -Enter your username and password when prompted. +Informe o seu usuário e a sua senha quando solicitado. -### Build the production image +### Construa a imagem de produção -Use the Makefile to build your production image: +Use o Makefile para construir a imagem de produção: ```bash make prod-build ``` -This runs the command defined in the Makefile: +Isso executa o comando definido no Makefile: ```bash docker build --file docker/Dockerfile --target prod --pull -t ${IMAGE}:${IMAGE_TAG} . ``` -The Dockerfile uses a multi-stage build: 1. Installs Composer dependencies -in a builder stage 2. Creates a minimal production image with only the -necessary files 3. Runs as a non-root user (`www-data`) +O Dockerfile usa um build multi-stage: 1. Instala as dependências do +Composer em um estágio de build 2. Cria uma imagem de produção mínima, só +com os arquivos necessários 3. Roda como um usuário não root (`www-data`) -### Push the image to the registry +### Envie a imagem para o registro -Push your built image to the container registry: +Envie a imagem construída para o registro de containers: ```bash make prod-push ``` -This executes: +Isso executa: ```bash docker push ${IMAGE}:${IMAGE_TAG} ``` -## Deploying to Docker Swarm +## Fazendo deploy no Docker Swarm -### Configure SSH access +### Configure o acesso SSH -Set up SSH key-based authentication to your server: +Configure a autenticação por chave SSH no seu servidor: ```bash -# Generate SSH key (if you don't have one) +# Gera uma chave SSH (se você ainda não tiver uma) ssh-keygen -t ed25519 -C "your_email@example.com" -# Copy the key to your server +# Copia a chave para o seu servidor ssh-copy-id user@your-server-ip -# Add the SSH host to your SSH config (~/.ssh/config) +# Adiciona o host SSH à sua configuração SSH (~/.ssh/config) cat >> ~/.ssh/config << EOF Host docker-web HostName your-server-ip @@ -394,86 +397,87 @@ Host docker-web EOF ``` -### Set up Docker context +### Configure o contexto do Docker -Create a Docker context for remote deployment: +Crie um contexto do Docker para o deploy remoto: ```bash docker context create swarm-prod --docker "host=ssh://docker-web" ``` -Alternatively, configure the `DOCKER_HOST` environment variable: +Como alternativa, configure a variável de ambiente `DOCKER_HOST`: ```bash export DOCKER_HOST=ssh://docker-web ``` -### Deploy the application +### Faça o deploy da aplicação -Deploy your application stack to Docker Swarm: +Faça o deploy da stack da sua aplicação no Docker Swarm: ```bash make prod-deploy ``` -This executes: +Isso executa: ```bash docker -H ${PROD_SSH} stack deploy --prune --detach=false --with-registry-auth -c docker/compose.yml -c docker/prod/compose.yml ${STACK_NAME} ``` -The `--with-registry-auth` flag ensures the Swarm nodes can pull images from -your private registry. +A flag `--with-registry-auth` garante que os nós do Swarm consigam baixar +imagens do seu registro privado. -### Verify the deployment +### Verifique o deploy -Check the status of your services: +Verifique o status dos seus serviços: ```bash docker -H ssh://docker-web service ls docker -H ssh://docker-web service ps ${STACK_NAME}_app ``` -View logs: +Veja os logs: ```bash docker -H ssh://docker-web service logs ${STACK_NAME}_app ``` -## Monitoring and maintenance +## Monitoramento e manutenção -### View service logs +### Veja os logs do serviço ```bash -# View all logs +# Mostra todos os logs docker -H ssh://docker-web service logs -f ${STACK_NAME}_app -# View logs from the last 100 lines +# Mostra as últimas 100 linhas de log docker -H ssh://docker-web service logs --tail 100 ${STACK_NAME}_app -# View logs with timestamps +# Mostra os logs com timestamps docker -H ssh://docker-web service logs -t ${STACK_NAME}_app ``` -### Scale the application +### Escale a aplicação -Adjust the number of replicas: +Ajuste o número de réplicas: ```bash docker -H ssh://docker-web service scale ${STACK_NAME}_app=3 ``` -Or update the `replicas` value in `docker/prod/compose.yml` and redeploy. +Ou atualize o valor de `replicas` em `docker/prod/compose.yml` e faça o +deploy de novo. -### Resource limits +### Limites de recursos -Add resource limits to prevent containers from consuming all server -resources. Update `docker/prod/compose.yml`: +Adicione limites de recursos para evitar que os containers consumam todos os +recursos do servidor. Atualize o `docker/prod/compose.yml`: ```yaml services: app: - # ... existing configuration ... + # ... configuração existente ... deploy: resources: limits: @@ -484,20 +488,20 @@ services: memory: 256M ``` -## Security considerations +## Considerações de segurança -### Use Docker secrets for sensitive data +### Use Docker secrets para dados sensíveis -Instead of environment variables, use Docker secrets for sensitive -information: +Em vez de variáveis de ambiente, use Docker secrets para informações +sensíveis: ```bash -# Create secrets +# Cria os secrets echo "database_password" | docker secret create db_password - echo "api_key" | docker secret create api_key - ``` -Update `docker/prod/compose.yml`: +Atualize o `docker/prod/compose.yml`: ```yaml services: @@ -513,89 +517,89 @@ secrets: external: true ``` -Access secrets in your application at `/run/secrets/secret_name`. +Acesse os secrets na sua aplicação em `/run/secrets/secret_name`. -### Set up a firewall +### Configure um firewall -Configure UFW (Uncomplicated Firewall) on your server: +Configure o UFW (Uncomplicated Firewall) no seu servidor: ```bash -# Allow SSH +# Libera SSH sudo ufw allow 22/tcp -# Allow HTTP and HTTPS +# Libera HTTP e HTTPS sudo ufw allow 80/tcp sudo ufw allow 443/tcp -# Allow Docker Swarm ports (if you plan to add more nodes) +# Libera as portas do Docker Swarm (se você pretende adicionar mais nós) sudo ufw allow 2377/tcp sudo ufw allow 7946/tcp sudo ufw allow 7946/udp sudo ufw allow 4789/udp -# Enable the firewall +# Habilita o firewall sudo ufw enable ``` -### Keep the system updated +### Mantenha o sistema atualizado -Regularly update your server and Docker: +Atualize regularmente o seu servidor e o Docker: ```bash -# Update system packages +# Atualiza os pacotes do sistema sudo apt-get update && sudo apt-get upgrade -y -# Update Docker images +# Atualiza as imagens Docker docker -H ssh://docker-web service update --image ${IMAGE}:${IMAGE_TAG} ${STACK_NAME}_app ``` -## Troubleshooting +## Solução de problemas -### Service won't start +### O serviço não sobe -Check service events and logs: +Verifique os eventos e os logs do serviço: ```bash docker -H ssh://docker-web service ps ${STACK_NAME}_app --no-trunc docker -H ssh://docker-web service logs ${STACK_NAME}_app ``` -Common issues: - **Image pull errors**: Verify registry authentication with -`docker -H ssh://docker-web login` - **Port conflicts**: Ensure no other -services are using ports 80/443 - **Resource constraints**: Check available -resources with `docker -H ssh://docker-web node ls` +Problemas comuns: - **Erros ao baixar a imagem**: verifique a autenticação +no registro com `docker -H ssh://docker-web login` - **Conflitos de porta**: +garanta que nenhum outro serviço esteja usando as portas 80/443 - +**Limitação de recursos**: verifique os recursos disponíveis com `docker -H +ssh://docker-web node ls` -### SSL certificate issues +### Problemas com certificados SSL -If Traefik can't obtain certificates: - Verify DNS is pointing to your -server - Check that ports 80 and 443 are accessible from the internet - -Ensure the email in the Let's Encrypt configuration is valid - Check logs: -`docker -H ssh://docker-web service logs traefik_traefik` +Se o Traefik não consegue obter os certificados: - Verifique se o DNS aponta +para o seu servidor - Verifique se as portas 80 e 443 estão acessíveis pela +internet - Garanta que o e-mail na configuração do Let's Encrypt é válido - +Verifique os logs: `docker -H ssh://docker-web service logs traefik_traefik` -### Container registry connection issues +### Problemas de conexão com o registro de containers -Test registry connectivity: +Teste a conectividade com o registro: ```bash -# From your local machine +# Na sua máquina local docker pull git.example.com/username/myapp:latest -# From the server +# No servidor docker -H ssh://docker-web pull git.example.com/username/myapp:latest ``` ## Resumo -You've successfully deployed a Yii application to Docker Swarm with: - A -container registry (Forgejo or Gitea) - Automatic HTTPS via Traefik - -Zero-downtime deployments with rolling updates - High availability with -multiple replicas +Você fez o deploy de uma aplicação Yii no Docker Swarm com: - Um registro de +containers (Forgejo ou Gitea) - HTTPS automático via Traefik - Deploys sem +downtime com rolling updates - Alta disponibilidade com várias réplicas -The Makefile commands simplify the deployment workflow: - `make prod-build` -- Build the production image - `make prod-push` - Push to the registry - -`make prod-deploy` - Deploy to Docker Swarm +Os comandos do Makefile simplificam o fluxo de deploy: - `make prod-build` - +Constrói a imagem de produção - `make prod-push` - Envia para o registro - +`make prod-deploy` - Faz o deploy no Docker Swarm -For more information, see: - [Yii Application -Template](https://github.com/yiisoft/app) - [Docker Swarm -Documentation](https://docs.docker.com/engine/swarm/) - [Traefik -Documentation](https://doc.traefik.io/traefik/) +Para mais informações, veja: - [Template de aplicação do +Yii](https://github.com/yiisoft/app) - [Documentação do Docker +Swarm](https://docs.docker.com/engine/swarm/) - [Documentação do +Traefik](https://doc.traefik.io/traefik/) diff --git a/src/pt-BR/cookbook/deployment/docker-swarm.md b/src/pt-BR/cookbook/deployment/docker-swarm.md index 242ee4d3..8856bd8c 100644 --- a/src/pt-BR/cookbook/deployment/docker-swarm.md +++ b/src/pt-BR/cookbook/deployment/docker-swarm.md @@ -1,4 +1,4 @@ -# Deploying Yii applications to Docker Swarm +# Fazendo deploy de aplicações Yii no Docker Swarm -- [Using Caddy](docker-swarm-caddy.md) -- [Using Traefik](docker-swarm-traefik.md) +- [Usando Caddy](docker-swarm-caddy.md) +- [Usando Traefik](docker-swarm-traefik.md) diff --git a/src/pt-BR/cookbook/deployment/rolling-update-migrations.md b/src/pt-BR/cookbook/deployment/rolling-update-migrations.md index d857edce..5d0c2488 100644 --- a/src/pt-BR/cookbook/deployment/rolling-update-migrations.md +++ b/src/pt-BR/cookbook/deployment/rolling-update-migrations.md @@ -1,63 +1,67 @@ -# Applying migrations during rolling updates +# Aplicando migrations durante rolling updates -Rolling updates keep old and new application instances running at the same -time. This makes database changes more delicate than in a single-server -deployment: both application versions must work with the same database while -the deployment is in progress. +Rolling updates mantêm instâncias antigas e novas da aplicação rodando ao +mesmo tempo. Isso torna as mudanças no banco de dados mais delicadas do que +em um deploy em um único servidor: as duas versões da aplicação precisam +funcionar com o mesmo banco de dados enquanto o deploy está em andamento. -The safe rule is: +A regra segura é: -1. Apply database changes that are compatible with the current production - code. -2. Deploy code that starts using these database changes. -3. Remove obsolete database structures only after every old application - instance is gone. +1. Aplique mudanças no banco de dados que sejam compatíveis com o código + atual de produção. +2. Faça o deploy do código que passa a usar essas mudanças no banco de + dados. +3. Remova estruturas obsoletas do banco de dados só depois que todas as + instâncias antigas da aplicação tiverem saído. -This is often called the expand and contract pattern. First expand the -schema so both versions can use it. Then move the application code. Finally -contract the schema in a later deployment. +Isso costuma ser chamado de padrão expand and contract. Primeiro expanda o +schema para que as duas versões possam usá-lo. Depois atualize o código da +aplicação. Por fim, contraia o schema em um deploy posterior. -## Why this matters +## Por que isso importa -During a rolling update, requests may be served by different versions of the -application: +Durante um rolling update, as requisições podem ser atendidas por versões +diferentes da aplicação: -- old code that does not know about the new schema; -- new code that expects the new schema; -- background workers that may lag behind web instances; -- scheduled commands that may run during deployment. +- código antigo, que não conhece o novo schema; +- código novo, que espera o novo schema; +- workers em segundo plano, que podem ficar atrás das instâncias web; +- comandos agendados, que podem rodar durante o deploy. -If a migration drops or renames a column before all old instances stop using -it, old code fails. If code that requires a new column is deployed before -the column exists, new code fails. The migration plan must keep every -intermediate state valid. +Se uma migration remove ou renomeia uma coluna antes que todas as instâncias +antigas parem de usá-la, o código antigo falha. Se o código que exige uma +coluna nova vai para produção antes de a coluna existir, o código novo +falha. O plano de migrations precisa manter válido cada estado +intermediário. -## Deployment flow +## Fluxo de deploy -Use this flow for changes that must not interrupt production traffic: +Use este fluxo para mudanças que não podem interromper o tráfego de +produção: -1. Create a migration that only adds compatible schema. -2. Apply this migration to production while the current application version - is still running. -3. Deploy the new application version with a rolling update. -4. Verify that all instances and workers run the new version. -5. In a later release, apply cleanup migrations that remove old columns, - indexes, tables, or compatibility code. +1. Crie uma migration que apenas adiciona schema compatível. +2. Aplique essa migration em produção enquanto a versão atual da aplicação + ainda está rodando. +3. Faça o deploy da nova versão da aplicação com um rolling update. +4. Verifique se todas as instâncias e workers rodam a nova versão. +5. Em uma release posterior, aplique as migrations de limpeza que removem + colunas, índices, tabelas ou código de compatibilidade antigos. -For Yii applications, run migrations with the same command you use in -regular deployments, for example: +Em aplicações Yii, rode as migrations com o mesmo comando que você usa nos +deploys normais, por exemplo: ```shell ./yii migrate ``` -Run migrations from a single deployment job or one dedicated console -container. Do not let every rolling application instance run migrations on -startup. +Rode as migrations a partir de um único job de deploy ou de um container de +console dedicado. Não deixe cada instância do rolling update rodar +migrations na inicialização. -## Adding a column +## Adicionando uma coluna -Adding a nullable column is usually compatible with old code: +Adicionar uma coluna que aceita nulo normalmente é compatível com o código +antigo: ```php public function up(MigrationBuilder $b): void @@ -68,123 +72,133 @@ public function up(MigrationBuilder $b): void } ``` -Then deploy code that writes and reads `display_name`. +Depois, faça o deploy do código que grava e lê `display_name`. -If the column must eventually be required: +Se a coluna precisar ser obrigatória no futuro: -1. Add it as nullable. -2. Deploy code that writes it for new and updated rows. -3. Backfill existing rows in batches. -4. Add a `NOT NULL` constraint in a later migration. +1. Adicione-a como coluna que aceita nulo. +2. Faça o deploy do código que a preenche em linhas novas e atualizadas. +3. Preencha as linhas existentes em lotes. +4. Adicione uma restrição `NOT NULL` em uma migration posterior. -Do not add a `NOT NULL` column without a database default while old code -still inserts rows without that column. +Não adicione uma coluna `NOT NULL` sem um valor padrão no banco de dados +enquanto o código antigo ainda insere linhas sem essa coluna. -## Renaming a column +## Renomeando uma coluna -Renaming is not compatible because old code uses the old name and new code -uses the new name. Use a multi-release change instead: +Renomear não é compatível, porque o código antigo usa o nome antigo e o +código novo usa o nome novo. Em vez disso, faça a mudança ao longo de várias +releases: -1. Add the new column. -2. Backfill it from the old column. -3. Deploy code that writes both columns and reads the new column with a - fallback to the old one. -4. Wait until all old code is gone. -5. Deploy code that uses only the new column. -6. Drop the old column in a later cleanup migration. +1. Adicione a nova coluna. +2. Preencha-a a partir da coluna antiga. +3. Faça o deploy do código que grava nas duas colunas e lê a nova coluna, + com fallback para a antiga. +4. Espere até que todo o código antigo tenha saído. +5. Faça o deploy do código que usa só a nova coluna. +6. Remova a coluna antiga em uma migration de limpeza posterior. -The same approach works for moving data to a different table. +A mesma abordagem funciona para mover dados para outra tabela. -## Changing a column type +## Mudando o tipo de uma coluna -Changing a column type in place may lock the table or break either the old -or new code. Prefer a new column: +Mudar o tipo de uma coluna no lugar pode travar a tabela ou quebrar o código +antigo ou o novo. Prefira uma coluna nova: -1. Add a column with the target type. -2. Backfill it in batches. -3. Deploy code that writes both columns. -4. Deploy code that reads the new column. -5. Drop the old column after all code uses the new one. +1. Adicione uma coluna com o tipo desejado. +2. Preencha-a em lotes. +3. Faça o deploy do código que grava nas duas colunas. +4. Faça o deploy do código que lê a nova coluna. +5. Remova a coluna antiga depois que todo o código usar a nova. -For small tables, an in-place type change may be acceptable. For production -tables with traffic, verify locking behavior on the exact database engine -and version before applying it. +Em tabelas pequenas, mudar o tipo no lugar pode ser aceitável. Em tabelas de +produção com tráfego, verifique o comportamento de locks no motor e na +versão exatos do banco de dados antes de aplicar a mudança. -## Dropping columns and tables +## Removendo colunas e tabelas -Dropping is a cleanup step, not the first step: +Remover é uma etapa de limpeza, não a primeira etapa: -1. Deploy code that no longer reads or writes the column or table. -2. Confirm that old application instances, workers, and scheduled commands - are stopped. -3. Confirm that no external reporting or maintenance scripts depend on it. -4. Drop it in a separate migration. +1. Faça o deploy do código que não lê nem grava mais a coluna ou a tabela. +2. Confirme que as instâncias antigas da aplicação, os workers e os comandos + agendados pararam. +3. Confirme que nenhum relatório externo ou script de manutenção depende + dela. +4. Remova-a em uma migration separada. -This makes rollback safer. If you need to roll back application code before -cleanup, the old schema is still available. +Isso torna o rollback mais seguro. Se você precisar fazer rollback do código +da aplicação antes da limpeza, o schema antigo ainda está disponível. -## Adding indexes and constraints +## Adicionando índices e restrições -Indexes and constraints may be logically compatible but operationally risky -because they can lock tables. +Índices e restrições podem ser logicamente compatíveis, mas arriscados na +operação, porque podem travar tabelas. -For indexes: +Para índices: -- use online index creation when the database supports it; -- for PostgreSQL, consider `CREATE INDEX CONCURRENTLY` from a migration or - command that is not wrapped in a transaction; -- for MySQL and MariaDB, check whether the operation can use online DDL for - your table and engine. +- use criação de índice online quando o banco de dados suportar; +- no PostgreSQL, considere `CREATE INDEX CONCURRENTLY` em uma migration ou + comando que não esteja dentro de uma transação; +- no MySQL e no MariaDB, verifique se a operação pode usar online DDL para a + sua tabela e o seu motor. -For constraints: +Para restrições: -- clean invalid data before adding the constraint; -- add the constraint only after deployed code preserves it; -- for PostgreSQL, consider adding foreign keys and check constraints as `NOT - VALID`, then validating them separately. +- limpe os dados inválidos antes de adicionar a restrição; +- adicione a restrição só depois que o código em produção a respeitar; +- no PostgreSQL, considere adicionar chaves estrangeiras e check constraints + como `NOT VALID` e validá-las separadamente depois. -Keep long-running index creation and validation separate from unrelated -schema changes so it is easier to monitor and retry them. +Mantenha a criação de índices e as validações demoradas separadas de +mudanças de schema não relacionadas, para facilitar o monitoramento e novas +tentativas. -## Data migrations +## Migrations de dados -Data migrations that touch many rows should be safe to run while the -application is live: +Migrations de dados que mexem em muitas linhas precisam ser seguras para +rodar com a aplicação no ar: -- make them idempotent so rerunning them does not corrupt data; -- process rows in small batches; -- avoid depending on current application service or entity logic because - that logic changes over time; -- prefer forward-compatible values that both old and new code can handle; -- store progress when a backfill is too large for a single migration run. +- torne-as idempotentes, para que rodar de novo não corrompa os dados; +- processe as linhas em lotes pequenos; +- evite depender da lógica atual de serviços ou entidades da aplicação, + porque essa lógica muda com o tempo; +- prefira valores compatíveis com o futuro, que tanto o código antigo quanto + o novo consigam tratar; +- guarde o progresso quando um preenchimento for grande demais para uma + única execução de migration. -For very large backfills, use a console command or background job after the -schema migration. The schema migration should prepare the database; the -background process should move the data gradually. +Para preenchimentos muito grandes, use um comando de console ou um job em +segundo plano depois da migration de schema. A migration de schema deve +preparar o banco de dados; o processo em segundo plano deve mover os dados +aos poucos. -## Reverting +## Revertendo -In production rolling deployments, reverting a destructive migration is -often harder than deploying a corrective migration. Treat `down()` methods -for destructive operations as a local-development convenience, not as the -main production rollback plan. +Em deploys com rolling update em produção, reverter uma migration destrutiva +costuma ser mais difícil do que fazer o deploy de uma migration +corretiva. Trate os métodos `down()` de operações destrutivas como uma +conveniência para o desenvolvimento local, não como o principal plano de +rollback em produção. -A practical rollback plan is: +Um plano de rollback prático é: -- before cleanup, roll back code only because old schema is still present; -- after cleanup, deploy a new forward migration that restores the required - structure or compatibility; -- restore from backup only when data was actually lost and no forward repair - is possible. +- antes da limpeza, faça rollback apenas do código, porque o schema antigo + ainda existe; +- depois da limpeza, faça o deploy de uma nova migration que restaure a + estrutura ou a compatibilidade necessária; +- restaure um backup só quando dados foram realmente perdidos e nenhum + reparo por uma nova migration é possível. ## Checklist -Before applying a production migration, verify that: - -- the current production code works after the migration; -- the new code works before and after all instances are updated; -- old workers and scheduled commands are covered; -- inserts and updates keep required columns valid in every deployment phase; -- long-running schema operations will not block production traffic - unexpectedly; -- cleanup happens in a separate release after the rollout is complete. +Antes de aplicar uma migration em produção, verifique que: + +- o código atual de produção funciona depois da migration; +- o código novo funciona antes e depois de todas as instâncias serem + atualizadas; +- workers antigos e comandos agendados foram considerados; +- inserts e updates mantêm as colunas obrigatórias válidas em todas as fases + do deploy; +- operações de schema demoradas não vão bloquear o tráfego de produção de + forma inesperada; +- a limpeza acontece em uma release separada, depois que o rollout terminou. diff --git a/src/pt-BR/cookbook/disabling-csrf-protection.md b/src/pt-BR/cookbook/disabling-csrf-protection.md index 245fefd4..669e4439 100644 --- a/src/pt-BR/cookbook/disabling-csrf-protection.md +++ b/src/pt-BR/cookbook/disabling-csrf-protection.md @@ -1,44 +1,45 @@ -# Disabling CSRF protection +# Desativando a proteção CSRF -## What is CSRF protection? +## O que é a proteção CSRF? -Cross-Site Request Forgery (CSRF) protection is a security mechanism that -prevents malicious websites from making unauthorized requests on behalf of -authenticated users. Yii3 includes built-in CSRF protection through the -`Yiisoft\Yii\Web\Middleware\CsrfTokenMiddleware` middleware. +A proteção contra Cross-Site Request Forgery (CSRF) é um mecanismo de +segurança que impede sites maliciosos de fazer requisições não autorizadas +em nome de usuários autenticados. O Yii3 inclui proteção CSRF nativa por +meio do middleware `Yiisoft\Yii\Web\Middleware\CsrfTokenMiddleware`. -For a comprehensive understanding of CSRF attacks and protection mechanisms, -see the [Security best -practices](../guide/security/best-practices.md#avoiding-csrf) section in the -main guide. +Para entender a fundo os ataques CSRF e os mecanismos de proteção, veja a +seção [Boas práticas de +segurança](../guide/security/best-practices.md#evitando-csrf) do guia +principal. -## When to disable CSRF protection +## Quando desativar a proteção CSRF -While CSRF protection should generally remain enabled for web applications, -there are specific scenarios where you might need to disable it: +Embora a proteção CSRF deva, em geral, continuar ativada em aplicações web, +há cenários específicos em que você pode precisar desativá-la: -### When external systems cannot provide CSRF tokens +### Quando sistemas externos não conseguem fornecer tokens CSRF -When building APIs or handling automated requests from external systems, -CSRF protection can interfere with legitimate requests since these systems -cannot provide valid CSRF tokens: +Ao construir APIs ou tratar requisições automatizadas de sistemas externos, +a proteção CSRF pode atrapalhar requisições legítimas, já que esses sistemas +não conseguem fornecer tokens CSRF válidos: -- **Third-party integrations**: External services cannot provide valid CSRF - tokens -- **Mobile applications**: Native mobile apps typically don't use cookies or - sessions in the same way as web browsers -- **Server-to-server communication**: API endpoints designed for - machine-to-machine communication -- **Payment processors**: PayPal, Stripe, and other payment systems send - webhook notifications -- **Version control systems**: GitHub, GitLab webhooks for CI/CD pipelines -- **Social media platforms**: Twitter, Facebook webhook notifications -- **Communication services**: Slack, Discord bot integrations +- **Integrações de terceiros**: serviços externos não conseguem fornecer + tokens CSRF válidos +- **Aplicativos móveis**: apps móveis nativos normalmente não usam cookies + ou sessões da mesma forma que os navegadores +- **Comunicação entre servidores**: endpoints de API projetados para + comunicação máquina a máquina +- **Processadores de pagamento**: PayPal, Stripe e outros sistemas de + pagamento enviam notificações por webhook +- **Sistemas de controle de versão**: webhooks do GitHub e do GitLab para + pipelines de CI/CD +- **Redes sociais**: notificações por webhook do Twitter e do Facebook +- **Serviços de comunicação**: integrações com bots do Slack e do Discord -## How to disable CSRF protection +## Como desativar a proteção CSRF -First, you need to remove CSRF middleware from your main application -middleware list in `config/web/di/application.php`: +Primeiro, remova o middleware de CSRF da lista principal de middlewares da +aplicação em `config/web/di/application.php`: ```php return [ @@ -50,13 +51,12 @@ return [ [ ErrorCatcher::class, SessionMiddleware::class, - CsrfTokenMiddleware::class, // <- Remove this line + CsrfTokenMiddleware::class, // <- Remova esta linha ``` -Now, if you need to leave CSRF on for specific routes or route groups, you -can do so by adding the `CsrfTokenMiddleware` middleware to the router -configuration in `config/common/routes.php`. For a group that would be the -following: +Agora, se você precisar manter o CSRF ativo para rotas ou grupos de rotas +específicos, adicione o middleware `CsrfTokenMiddleware` na configuração do +router em `config/common/routes.php`. Para um grupo, fica assim: ```php return [ @@ -65,7 +65,7 @@ return [ ->routes( ``` -For a single route, you can add the middleware directly to the route: +Para uma única rota, você pode adicionar o middleware diretamente nela: ```php Route::methods([Method::GET, Method::POST], '/say[/{test}]') @@ -75,31 +75,34 @@ Route::methods([Method::GET, Method::POST], '/say[/{test}]') ``` -## Security considerations +## Considerações de segurança -When disabling CSRF protection, keep these security considerations in mind: +Ao desativar a proteção CSRF, tenha em mente estas considerações de +segurança: -### Alternative authentication methods +### Métodos alternativos de autenticação -For API endpoints, implement proper authentication mechanisms: +Para endpoints de API, implemente mecanismos de autenticação adequados: -- **API keys**: Require API keys for authentication -- **Bearer tokens**: Use JWT or similar token-based authentication -- **OAuth 2.0**: Implement OAuth 2.0 for third-party access -- **IP whitelisting**: Restrict access to known IP addresses for webhooks +- **Chaves de API**: exija chaves de API para autenticação +- **Bearer tokens**: use JWT ou autenticação similar baseada em token +- **OAuth 2.0**: implemente OAuth 2.0 para acesso de terceiros +- **Lista de IPs permitidos**: restrinja o acesso de webhooks a endereços IP + conhecidos -### Request validation +### Validação da requisição -Implement additional validation for requests without CSRF protection: +Implemente validação adicional para requisições sem proteção CSRF: -- **Signature verification**: Verify webhook signatures (e.g., GitHub's - X-Hub-Signature) -- **Timestamp validation**: Check request timestamps to prevent replay - attacks -- **Rate limiting**: Implement rate limiting to prevent abuse -- **Input validation**: Strictly validate all input parameters +- **Verificação de assinatura**: verifique assinaturas de webhooks (por + exemplo, o X-Hub-Signature do GitHub) +- **Validação de timestamp**: confira o timestamp das requisições para + evitar ataques de replay +- **Rate limiting**: implemente limite de requisições para evitar abuso +- **Validação de entrada**: valide rigorosamente todos os parâmetros de + entrada -### Example: Webhook signature verification +### Exemplo: verificação de assinatura de webhook ```php getHeaderLine('X-Webhook-Signature'); $payload = (string) $request->getBody(); $expectedSignature = hash_hmac('sha256', $payload, $this->webhookSecret); @@ -122,32 +125,32 @@ final class WebhookController throw new \RuntimeException('Invalid webhook signature'); } - // Process webhook payload + // Processa o payload do webhook // ... } } ``` -## Best practices - -1. **Minimize exposure**: Only disable CSRF protection where absolutely - necessary -2. **Use HTTPS**: Always use HTTPS for API endpoints and webhooks -3. **Monitor logs**: Log all requests to API endpoints for security - monitoring -4. **Regular security audits**: Periodically review your API endpoints and - their security measures -5. **Documentation**: Clearly document which endpoints have CSRF protection - disabled and why - -## Conclusion - -While CSRF protection is crucial for web applications, there are legitimate -scenarios where it needs to be disabled, particularly for external APIs and -webhooks. When disabling CSRF protection, always implement alternative -security measures and follow security best practices to maintain the overall -security of your application. - -Remember that disabling CSRF protection increases security risks, so careful -consideration and proper implementation of alternative security measures are -essential. +## Boas práticas + +1. **Minimize a exposição**: desative a proteção CSRF apenas onde for + realmente necessário +2. **Use HTTPS**: sempre use HTTPS para endpoints de API e webhooks +3. **Monitore os logs**: registre em log todas as requisições aos endpoints + de API para monitoramento de segurança +4. **Auditorias de segurança regulares**: revise periodicamente seus + endpoints de API e as medidas de segurança deles +5. **Documentação**: documente claramente quais endpoints têm a proteção + CSRF desativada e por quê + +## Conclusão + +Embora a proteção CSRF seja essencial para aplicações web, há cenários +legítimos em que ela precisa ser desativada, principalmente para APIs +externas e webhooks. Ao desativá-la, sempre implemente medidas de segurança +alternativas e siga as boas práticas de segurança para manter a segurança +geral da sua aplicação. + +Lembre-se de que desativar a proteção CSRF aumenta os riscos de segurança, +então é essencial avaliar com cuidado e implementar corretamente as medidas +de segurança alternativas. diff --git a/src/pt-BR/cookbook/making-http-requests.md b/src/pt-BR/cookbook/making-http-requests.md index e36a4f46..594d41ab 100644 --- a/src/pt-BR/cookbook/making-http-requests.md +++ b/src/pt-BR/cookbook/making-http-requests.md @@ -1,26 +1,26 @@ -# Making HTTP requests +# Fazendo requisições HTTP -Yii doesn't include its own HTTP client implementation. Use a client that -implements [PSR-18](https://www.php-fig.org/psr/psr-18/) and depend on PSR -interfaces in your application code. +O Yii não inclui uma implementação própria de cliente HTTP. Use um cliente +que implemente a [PSR-18](https://www.php-fig.org/psr/psr-18/) e dependa das +interfaces PSR no código da sua aplicação. -This recipe uses [Guzzle](https://docs.guzzlephp.org/) as the HTTP -client. Guzzle provides a PSR-18 client and uses PSR-7 messages. +Esta receita usa o [Guzzle](https://docs.guzzlephp.org/) como cliente +HTTP. O Guzzle fornece um cliente PSR-18 e usa mensagens PSR-7. -## Installation +## Instalação -Install Guzzle: +Instale o Guzzle: ```shell composer require guzzlehttp/guzzle ``` -The package installs the PSR HTTP interfaces and `guzzlehttp/psr7`, which -provides PSR-7 messages and PSR-17 factories. +O pacote instala as interfaces HTTP da PSR e o `guzzlehttp/psr7`, que +fornece mensagens PSR-7 e factories PSR-17. -## Configure the container +## Configure o container -Create `config/common/di/http-client.php`: +Crie `config/common/di/http-client.php`: ```php **Toolbox URL**. -If the copied URL has `origin`, keep the `origin` parameter and its value in your links. +O PhpStorm suporta URLs do Toolbox que usam o protocolo `jetbrains://`. Para obter o valor de `project` e o formato do caminho, +clique com o botão direito em um arquivo do projeto na janela Project e selecione **Copy Path/Reference** > **Toolbox URL**. +Se a URL copiada tiver `origin`, mantenha o parâmetro `origin` e o valor dele nos seus links. -On Linux, check that Toolbox registered the protocol handler: +No Linux, verifique se o Toolbox registrou o handler do protocolo: ```shell xdg-mime query default x-scheme-handler/jetbrains ``` -The command should print a Toolbox or JetBrains daemon desktop file, for -example `jetbrainsd.desktop`. +O comando deve imprimir um arquivo desktop do Toolbox ou do daemon da +JetBrains, por exemplo `jetbrainsd.desktop`. -PhpStorm should be running with the project open when you click stack trace -links. +O PhpStorm deve estar rodando com o projeto aberto quando você clicar nos +links do stack trace. -## Configure error trace links +## Configure os links do stack trace -The Yii application template configures -`Yiisoft\ErrorHandler\Renderer\HtmlRenderer` in -`config/common/di/error-handler.php`. It reads a `traceLink` parameter and -uses it for stack trace file links. +O template de aplicação do Yii configura o +`Yiisoft\ErrorHandler\Renderer\HtmlRenderer` em +`config/common/di/error-handler.php`. Ele lê um parâmetro `traceLink` e o +usa nos links de arquivos do stack trace. -Add the parameter to `config/common/params.php`: +Adicione o parâmetro em `config/common/params.php`: ```php 'jetbrains://phpstorm/navigate/reference?project=my-app&path={file}:{line}', - // Other parameters. + // Outros parâmetros. ]; ``` -Replace `my-app` with the `project` value from the Toolbox URL. If the -Toolbox URL uses `origin`, keep `origin` in the link template and use its -value. +Substitua `my-app` pelo valor de `project` da URL do Toolbox. Se a URL do +Toolbox usar `origin`, mantenha `origin` no template do link e use o valor +dele. -After that, open a debug error page and click a file link in the stack -trace. +Depois disso, abra uma página de erro em modo debug e clique em um link de +arquivo no stack trace. -## Map Docker paths to host paths +## Mapeie os caminhos do Docker para os caminhos do host -When the application runs in Docker, stack traces usually contain container -paths such as `/app/src/...`. PhpStorm needs the matching host path. +Quando a aplicação roda no Docker, os stack traces geralmente contêm +caminhos do container, como `/app/src/...`. O PhpStorm precisa do caminho +correspondente no host. -Set `APP_HOST_PATH` in `docker/dev/override.env` to the project path on the -host machine. Set `APP_IDE_PROJECT` to the `project` value from a Toolbox -URL. If the URL uses `origin`, store the `origin` value instead and use -`origin` in the final URL template: +Defina `APP_HOST_PATH` em `docker/dev/override.env` com o caminho do projeto +na máquina host. Defina `APP_IDE_PROJECT` com o valor de `project` de uma +URL do Toolbox. Se a URL usar `origin`, guarde o valor de `origin` e use +`origin` no template final da URL: ```dotenv APP_HOST_PATH=/home/user/projects/my-app APP_IDE_PROJECT=my-app ``` -`docker/dev/override.env` is for developer-specific settings and shouldn't -be committed. See [Override env -files](../guide/tutorial/docker.md#override-env-files) for details. +O `docker/dev/override.env` é para configurações específicas de cada +desenvolvedor e não deve ser commitado. Veja [Arquivos env de +override](../guide/tutorial/docker.md#arquivos-env-de-override) para mais +detalhes. -In the application parameters, expose these environment values as -`$params['app']['hostPath']` and `$params['app']['ideProject']`. +Nos parâmetros da aplicação, exponha esses valores de ambiente como +`$params['app']['hostPath']` e `$params['app']['ideProject']`. -With the default application template, `/app/src/Web/HomePage/Action.php` -will be linked as `/home/user/projects/my-app/src/Web/HomePage/Action.php`. +Com o template de aplicação padrão, `/app/src/Web/HomePage/Action.php` será +linkado como `/home/user/projects/my-app/src/Web/HomePage/Action.php`. -## Configure `HtmlRenderer` manually +## Configure o `HtmlRenderer` manualmente -If your application doesn't have the template's `error-handler.php` -configuration, configure `HtmlRenderer` directly: +Se a sua aplicação não tiver a configuração `error-handler.php` do template, +configure o `HtmlRenderer` diretamente: ```php [!NOTE] -> Such isolation is suitable for complex systems. If your project domain is basically create/read/update/delete -> for a set of records with not much complex logic, it makes no sense to apply a complex solution to a simple problem. -> The individual concepts of domain design below could be applied separately, so make sure to check these even if your -> project isn't that complicated. +> Esse isolamento é adequado para sistemas complexos. Se o domínio do seu projeto é basicamente criar/ler/atualizar/excluir +> um conjunto de registros sem muita lógica complexa, não faz sentido aplicar uma solução complexa a um problema simples. +> Os conceitos individuais de design de domínio abaixo podem ser aplicados separadamente, então vale conferi-los mesmo que o seu +> projeto não seja tão complicado. ## Bounded context -It's nearly impossible to build a model that solves multiple problems that -aren't too complicated by itself. Therefore, it's a good practice to divide -the domain into several use-cases and have a separate model for each -use-case. Such separated models are called "bounded contexts." +É quase impossível construir um modelo que resolva vários problemas sem que +ele mesmo fique complicado demais. Por isso, é uma boa prática dividir o +domínio em vários casos de uso e ter um modelo separado para cada um. Esses +modelos separados são chamados de "bounded contexts". -## Building blocks +## Blocos de construção -There are various building blocks that are typically used when describing -domain models. It isn't mandatory to use them all. +Existem vários blocos de construção normalmente usados para descrever +modelos de domínio. Não é obrigatório usar todos. -### Entity +### Entidade -Entity is a uniquely identifiable object such as user, product, payment, -etc. When comparing them, you're checking ID, not the attribute values. If -there are two objects with different attributes but the same ID, they're -considered being the same thing. +Entidade é um objeto identificável de forma única, como um usuário, um +produto, um pagamento etc. Ao comparar entidades, você verifica o ID, não os +valores dos atributos. Se dois objetos têm atributos diferentes, mas o mesmo +ID, eles são considerados a mesma coisa. ### Value object -Value object describes an object by its characteristics. For example, a -price that consists of value and currency. When comparing such objects, -you're checking actual values. If they match, an object is considered to be -the same. +Um value object descreve um objeto por suas características. Por exemplo, um +preço composto por valor e moeda. Ao comparar esses objetos, você verifica +os valores de fato. Se eles coincidem, os objetos são considerados iguais. -### Aggregate +### Agregado -Aggregate is a set of domain objects such as entities and value objects and -additional data that could be treated as a single unit. It usually -represents a compound object from a domain model such as shop order or HR -person dossier. +Agregado é um conjunto de objetos de domínio, como entidades e value +objects, e dados adicionais que podem ser tratados como uma única +unidade. Ele geralmente representa um objeto composto do modelo de domínio, +como um pedido de loja ou o dossiê de uma pessoa no RH. -One of the components of an aggregate is called a root. The root identifies -an aggregate as a whole and should be used to access it. +Um dos componentes de um agregado é chamado de raiz. A raiz identifica o +agregado como um todo e deve ser usada para acessá-lo. -### Domain event +### Evento de domínio -An aggregate, while processed, may raise events. For example, when order is -confirmed, `OrderConfirmed` event would be risen so other parts of the -system may react on these. +Um agregado, ao ser processado, pode disparar eventos. Por exemplo, quando +um pedido é confirmado, o evento `OrderConfirmed` é disparado para que +outras partes do sistema possam reagir a ele. ### Data transfer object -Data transfer object or DTO is an object whose only purpose is to hold data -as it is. It's commonly used to pass data between different services. +Data transfer object, ou DTO, é um objeto cujo único propósito é guardar +dados como estão. Ele é comumente usado para passar dados entre diferentes +serviços. -### Service +### Serviço -Service is a class that contains a standalone operation within the context -of your domain model. See "[service components](service.md)". +Serviço é uma classe que contém uma operação independente dentro do contexto +do seu modelo de domínio. Veja "[componentes de serviço](service.md)". -### Repository +### Repositório -The repository task is to abstract away how domain objects are -obtained. These are usually separated into two parts: an interface that -stays in the domain layer and an implementation that's situated in the -infrastructure layer. In such a way, domain doesn't care how data is -obtained and saved and may be focused around the complicated business logic -instead. +A tarefa do repositório é abstrair como os objetos de domínio são +obtidos. Ele geralmente é dividido em duas partes: uma interface, que fica +na camada de domínio, e uma implementação, que fica na camada de +infraestrutura. Dessa forma, o domínio não se importa com como os dados são +obtidos e salvos e pode se concentrar na lógica de negócio complicada. -Repository is usually implemented as a service. +O repositório geralmente é implementado como um serviço. -### Instantiating building blocks +### Instanciando os blocos de construção -Entity, value object, aggregate, and domain events aren't services and -shouldn't be instantiated through DI container. Using `new` is the way to -go with these. +Entidades, value objects, agregados e eventos de domínio não são serviços e +não devem ser instanciados pelo container de DI. Use `new` para criá-los. -## References +## Referências -- [BoundedContext by Martin +- [BoundedContext, por Martin Fowler](https://martinfowler.com/bliki/BoundedContext.html) -- [ValueObject by Martin +- [ValueObject, por Martin Fowler](https://martinfowler.com/bliki/ValueObject.html) -- [Aggregate by Marting +- [Aggregate, por Martin Fowler](https://martinfowler.com/bliki/DDD_Aggregate.html) diff --git a/src/pt-BR/cookbook/organizing-code/service.md b/src/pt-BR/cookbook/organizing-code/service.md index 0baee5d5..efd1506d 100644 --- a/src/pt-BR/cookbook/organizing-code/service.md +++ b/src/pt-BR/cookbook/organizing-code/service.md @@ -1,9 +1,9 @@ -# Service components +# Componentes de serviço -Application may get complicated, so it makes sense to extract focused parts -of business logic or infrastructure into service components. They're -typically injected into other components or action handlers. It's usually -done via autowiring: +A aplicação pode ficar complicada, então faz sentido extrair partes focadas +da lógica de negócio ou da infraestrutura para componentes de serviço. Eles +normalmente são injetados em outros componentes ou em action handlers. Isso +geralmente é feito por autowiring: ```php public function actionIndex(CurrentRoute $route, MyService $myService): ResponseInterface @@ -17,9 +17,9 @@ public function actionIndex(CurrentRoute $route, MyService $myService): Response } ``` -Yii3 doesn't technically imply any limitations on how you build services. In -general, there's no need to extend from a base class or implement a certain -interface: +Tecnicamente, o Yii3 não impõe nenhuma limitação sobre como você constrói +serviços. Em geral, não é preciso estender uma classe base nem implementar +uma interface específica: ```php final readonly class MyService @@ -37,29 +37,31 @@ final readonly class MyService } ``` -Services either perform a task or return data. They're created once, put -into a DI container and then could be used multiple times. Because of that, -it's a good idea to keep your services stateless that's both service itself -and any of its dependencies shouldn't hold state. You can ensure it by using -`readonly` PHP keyword at class level. +Serviços executam uma tarefa ou retornam dados. Eles são criados uma vez, +colocados em um container de DI e então podem ser usados várias vezes. Por +isso, é uma boa ideia manter seus serviços sem estado: nem o próprio serviço +nem qualquer uma de suas dependências devem guardar estado. Você pode +garantir isso usando a palavra-chave `readonly` do PHP no nível da classe. -## Service dependencies and configuration +## Dependências e configuração de serviços -Services should always define all their dependencies on other services via -`__construct()`. It both allows you to use a service right away after it's -created and serves as an indicator of a service doing too much if there are -too many dependencies. +Serviços devem sempre declarar todas as suas dependências de outros serviços +via `__construct()`. Isso permite usar o serviço logo depois de criado e +também serve como indicador de que o serviço faz coisas demais, quando há +dependências demais. -- After the service is created, it shouldn't be re-configured in runtime. -- DI container instance usually **shouldn't** be injected as a - dependency. Prefer concrete interfaces. -- In case of complicated or "heavy" initialization, try to postpone it until - the service method is called. +- Depois de criado, o serviço não deve ser reconfigurado em tempo de + execução. +- A instância do container de DI geralmente **não deve** ser injetada como + dependência. Prefira interfaces concretas. +- Em caso de inicialização complicada ou "pesada", tente adiá-la até que o + método do serviço seja chamado. -The same is valid for configuration values. They should be provided as a -constructor argument. Related values could be grouped together into value -objects. For example, database connection usually requires DSN string, -username and password. These three could be combined into Dsn class: +O mesmo vale para valores de configuração. Eles devem ser fornecidos como +argumento do construtor. Valores relacionados podem ser agrupados em value +objects. Por exemplo, uma conexão com banco de dados geralmente exige a +string DSN, o nome de usuário e a senha. Esses três podem ser combinados em +uma classe Dsn: ```php final readonly class Dsn @@ -77,15 +79,15 @@ final readonly class Dsn private function isValidDsn(string $dsn): bool { - // check DSN validity + // verifica se o DSN é válido } } ``` -## Service methods +## Métodos de serviço -Service method usually does something. It could be a simple thing repeated -exactly, but usually it depends on the context. For example: +Um método de serviço geralmente faz alguma coisa. Pode ser algo simples +repetido exatamente igual, mas normalmente depende do contexto. Por exemplo: ```php final readonly class PostPersister @@ -103,17 +105,17 @@ final readonly class PostPersister } ``` -There's a service that is saving posts into permanent storage such as a -database. An object allowing communication with a concrete storage is always -the same, so it's injected using constructor while the post saved could -vary, so it's passed as a method argument. +Aqui há um serviço que salva posts em um armazenamento permanente, como um +banco de dados. O objeto que permite a comunicação com um armazenamento +concreto é sempre o mesmo, então é injetado pelo construtor, enquanto o post +salvo pode variar, então é passado como argumento do método. -## Is everything a service? +## Tudo é um serviço? -Often it makes sense to choose another class type to place your code -into. Check: +Muitas vezes faz sentido escolher outro tipo de classe para colocar seu +código. Confira: -- Repository +- Repositório - Widget - [Middleware](middleware.md) -- Entity +- Entidade diff --git a/src/pt-BR/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md b/src/pt-BR/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md index 8ee871aa..2abfb31b 100644 --- a/src/pt-BR/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md +++ b/src/pt-BR/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md @@ -1,35 +1,36 @@ -# Structuring code by use-case with vertical slices +# Estruturando o código por caso de uso com vertical slices -When building an application, it's important to organize the code in a way -that makes it easy to understand, support, and scale. One popular approach -is to structure the code by use-case with vertical slices. +Ao construir uma aplicação, é importante organizar o código de forma que ele +seja fácil de entender, manter e escalar. Uma abordagem popular é estruturar +o código por caso de uso com vertical slices. -Vertical slices are self-contained pieces of functionality that cover the -entire stack, from the user interface to the data access layer. Developer -organizes each slice around a specific use case, such as creating a new user -or updating a product. +Vertical slices são partes autocontidas de funcionalidade que cobrem toda a +stack, da interface do usuário à camada de acesso a dados. O desenvolvedor +organiza cada slice em torno de um caso de uso específico, como criar um +novo usuário ou atualizar um produto. -When structuring code classically by type (such as models, views, -controllers, helpers, etc.), it can be easy to lose sight of the bigger -picture and how different pieces of code interact to support specific -features or use cases. This can lead to code duplication, tight coupling, -and poor maintainability as the application grows. +Ao estruturar o código da forma clássica, por tipo (models, views, +controllers, helpers etc.), é fácil perder de vista o quadro geral e como as +diferentes partes do código interagem para atender funcionalidades ou casos +de uso específicos. Isso pode levar a duplicação de código, acoplamento +forte e manutenção difícil à medida que a aplicação cresce. -On the other hand, structuring code by use-case makes developers focus on a -specific feature or workflow and understand how different pieces of code -work together to support that feature. This approach also helps to keep -related code together in a single directory, making it easier to navigate -and support. Vertical slicing also encourages the use of domain-driven -design concepts, such as entities, repositories, and services, which can -help to promote good separation of concerns and modularity. +Por outro lado, estruturar o código por caso de uso faz os desenvolvedores +focarem em uma funcionalidade ou fluxo específico e entenderem como as +diferentes partes do código trabalham juntas para atendê-lo. Essa abordagem +também ajuda a manter o código relacionado junto, em um único diretório, o +que facilita a navegação e a manutenção. O vertical slicing também incentiva +o uso de conceitos de domain-driven design, como entidades, repositórios e +serviços, que ajudam a promover uma boa separação de responsabilidades e +modularidade. -Additionally, structuring code by use-case can make it easier to test and -debug the application since use-case namespace encapsulates each feature or -workflow in its own directory with clear boundaries and well-defined -interfaces. +Além disso, estruturar o código por caso de uso pode facilitar os testes e o +debug da aplicação, já que o namespace do caso de uso encapsula cada +funcionalidade ou fluxo em seu próprio diretório, com limites claros e +interfaces bem definidas. -Here's an example directory structure for a PHP application organized using -vertical slices: +Veja um exemplo de estrutura de diretórios de uma aplicação PHP organizada +com vertical slices: ``` src/ @@ -68,14 +69,14 @@ src/ | | ├── RssBuilder.php ``` -Each vertical slice has its own directory, which has code associated with -the use case. +Cada vertical slice tem seu próprio diretório, que contém o código associado +ao caso de uso. -The use-case subdirectories and their respective classes are organized by -type within each directory, omitting a directory if there's a single class -of the type. If code is shared between multiple use-cases, it's moved one -level up such as `Model` or `Service`. +Os subdiretórios de caso de uso e suas respectivas classes são organizados +por tipo dentro de cada diretório, omitindo o diretório quando há uma única +classe daquele tipo. Se um código é compartilhado entre vários casos de uso, +ele sobe um nível, como em `Model` ou `Service`. -## References +## Referências -- [Application structure overview](../../guide/structure/overview.md) +- [Visão geral da estrutura da aplicação](../../guide/structure/overview.md) diff --git a/src/pt-BR/cookbook/preface.md b/src/pt-BR/cookbook/preface.md index 83dd31c7..adefb14c 100644 --- a/src/pt-BR/cookbook/preface.md +++ b/src/pt-BR/cookbook/preface.md @@ -1,4 +1,4 @@ -# Preface +# Prefácio O Yii é um framework PHP de alto desempenho, baseado em pacotes, para desenvolver aplicações modernas. O nome Yii (pronuncia-se `Yee` ou `[ji:]`) @@ -11,27 +11,28 @@ arquitetura e do suporte sofisticado a cache, ele é especialmente indicado para aplicações de grande porte, como portais, sistemas de gerenciamento de conteúdo, e-commerce, APIs REST etc. -With comprehensive documentation and an enthusiastic user community, Yii can -significantly reduce your development time in the long run. +Com uma documentação abrangente e uma comunidade de usuários entusiasmada, o +Yii pode reduzir bastante o seu tempo de desenvolvimento a longo prazo. -## What's the book about +## Sobre o que é este livro -This book is for you if you're familiar with Yii3, building Yii -applications, and read the official Yii3 guide. It covers fundamentally -important development concepts, application architecture approaches, -integrating third party services with Yii3, etc. +Este livro é para você se já conhece o Yii3, constrói aplicações Yii e leu o +guia oficial do Yii3. Ele cobre conceitos de desenvolvimento fundamentais, +abordagens de arquitetura de aplicações, integração de serviços de terceiros +com o Yii3 etc. -The book consists of individual recipes gathered from Yii experts that you -can apply in your applications. These go by topic, but you are free to read -them in any order as there is no dependency between them. +O livro é formado por receitas individuais reunidas por especialistas em +Yii, que você pode aplicar nas suas aplicações. Elas são organizadas por +tema, mas você pode lê-las em qualquer ordem, já que não há dependência +entre elas. -## Prerequisites +## Pré-requisitos -- You should have Yii3 installed. -- You should be familiar with the framework basics and the official guide. +- Você deve ter o Yii3 instalado. +- Você deve conhecer o básico do framework e o guia oficial. -## How to participate +## Como participar -If you've found any errata, wrong information, want to improve something or -have a good recipe, create an issue or make a pull request in [the book -GitHub repository](https://github.com/yiisoft/docs). +Se você encontrou alguma errata ou informação errada, quer melhorar algo ou +tem uma boa receita, crie uma issue ou abra um pull request no [repositório +do livro no GitHub](https://github.com/yiisoft/docs). diff --git a/src/pt-BR/cookbook/sentry-integration.md b/src/pt-BR/cookbook/sentry-integration.md index b2d4685f..28e56813 100644 --- a/src/pt-BR/cookbook/sentry-integration.md +++ b/src/pt-BR/cookbook/sentry-integration.md @@ -1,56 +1,57 @@ -# Sentry integration +# Integração com o Sentry -## What is Sentry +## O que é o Sentry -[Sentry](https://sentry.io/) is a tool for monitoring and debugging application stability and performance. -Sentry gives you access to the events that you send there from your application. +O [Sentry](https://sentry.io/) é uma ferramenta para monitorar e depurar a estabilidade e o desempenho de aplicações. +O Sentry dá acesso aos eventos que você envia para ele a partir da sua aplicação. -Most often, Sentry is used for monitoring errors (exceptions). You can -enrich errors with context to better understand the problem: - Request -arguments - Tags for grouping exceptions - Environment state: environment -variables, application state, and other global attributes +Na maioria das vezes, o Sentry é usado para monitorar erros (exceções). +Você pode enriquecer os erros com contexto para entender melhor o problema: +- Argumentos da requisição - Tags para agrupar exceções - Estado do +ambiente: variáveis de ambiente, estado da aplicação e outros atributos +globais -You can find the full list of features on the official website: +Você encontra a lista completa de funcionalidades no site oficial: https://sentry.io/welcome/ -## Installation +## Instalação -### Install the package +### Instale o pacote -Install the required package `yiisoft/yii-sentry` with the following -command: +Instale o pacote necessário `yiisoft/yii-sentry` com o seguinte comando: ```shell composer require yiisoft/yii-sentry --prefer-dist ``` -### Install an HTTP driver +### Instale um driver HTTP -The [`getsentry/sentry-php`](https://github.com/getsentry/sentry-php) -library requires the `php-http/httplug` package and any HTTP driver. In the -example below we’ll use the Guzzle adapter. +A biblioteca +[`getsentry/sentry-php`](https://github.com/getsentry/sentry-php) exige o +pacote `php-http/httplug` e algum driver HTTP. No exemplo abaixo, vamos +usar o adaptador do Guzzle. -> You can find the list of all adapters on [this page](https://docs.php-http.org/en/latest/clients.html#clients-adapters). +> Você encontra a lista de todos os adaptadores [nesta página](https://docs.php-http.org/en/latest/clients.html#clients-adapters). -To install the packages, run the following command: +Para instalar os pacotes, execute o seguinte comando: ```shell composer require php-http/httplug php-http/guzzle7-adapter --prefer-dist ``` -## Configuration +## Configuração -### Get and store the token +### Obtenha e guarde o token -Next, configure the application. +Em seguida, configure a aplicação. -First, register at [Sentry](https://sentry.io) and create a project. +Primeiro, cadastre-se no [Sentry](https://sentry.io) e crie um projeto. -Then, in the project settings on the “General Settings” tab, find the -“Security Token” field and copy its value. +Depois, nas configurações do projeto, na aba “General Settings”, encontre o +campo “Security Token” e copie o valor dele. -Now put this token into the package configuration. By default, the config is located at `config/packages/yiisoft/yii-sentry/config/params.php`. -Set the copied token as the value of the array element at `yiisoft/yii-sentry` => `options` => `dsn`. Example: +Agora coloque esse token na configuração do pacote. Por padrão, a configuração fica em `config/packages/yiisoft/yii-sentry/config/params.php`. +Defina o token copiado como valor do elemento do array em `yiisoft/yii-sentry` => `options` => `dsn`. Exemplo: ```diff 'yiisoft/yii-sentry' => [ @@ -62,12 +63,11 @@ Set the copied token as the value of the array element at `yiisoft/yii-sentry` = ], ``` -### Configure the HTTP client +### Configure o cliente HTTP -After installing the HTTP client, configure it. +Depois de instalar o cliente HTTP, configure-o. -Create the file `config/common/sentry.php` and put the following code into -it: +Crie o arquivo `config/common/sentry.php` e coloque nele o seguinte código: ```php setTitle('Users'); ``` -Create `src/Web/Users/Index/Action.php`: +Crie `src/Web/Users/Index/Action.php`: ```php get(ApplicationParams::class); echo $params->name; ``` -In real integrations, prefer getting your own application services instead -of framework infrastructure. For example, expose `InvoiceSender`, -`ReportBuilder`, or `CatalogImporter` from Yii and call that service from -the host application. +Em integrações reais, prefira obter os serviços da sua própria aplicação em +vez da infraestrutura do framework. Por exemplo, exponha `InvoiceSender`, +`ReportBuilder` ou `CatalogImporter` a partir do Yii e chame esse serviço na +aplicação hospedeira. -## Keep boundaries explicit +## Mantenha os limites explícitos -Avoid mixing request lifecycles. Let the host application continue to own -its HTTP request and response. Let Yii provide services that do not assume -Yii is handling the current request. +Evite misturar ciclos de vida de requisição. Deixe a aplicação hospedeira +continuar dona da requisição e da resposta HTTP. Deixe o Yii fornecer +serviços que não pressupõem que o Yii está tratando a requisição atual. -Good candidates for reuse: +Bons candidatos para reaproveitamento: -- domain services; -- repositories and database connections; -- mailers and notification services; +- serviços de domínio; +- repositórios e conexões com banco de dados; +- mailers e serviços de notificação; - loggers; -- validators; -- queue producers; -- command-like application services. +- validadores; +- produtores de fila; +- serviços de aplicação no estilo de comandos. -Avoid pulling in Yii actions, middleware stacks, sessions, CSRF middleware, -or view rendering unless the host application explicitly delegates that -whole responsibility to Yii. +Evite trazer actions, pilhas de middlewares, sessões, middleware de CSRF ou +renderização de views do Yii, a menos que a aplicação hospedeira delegue +explicitamente essa responsabilidade inteira ao Yii. -## Configuration groups +## Grupos de configuração -The default application template separates configuration by group: +O template de aplicação padrão separa a configuração por grupo: -- `di` is shared by web and console entry points; -- `di-console` is console-specific and includes `di` in the template; -- `di-web` is web-specific and includes `di`; -- `params-console` and `params-web` extend common `params`. +- `di` é compartilhado pelos pontos de entrada web e de console; +- `di-console` é específico do console e inclui `di` no template; +- `di-web` é específico da web e inclui `di`; +- `params-console` e `params-web` estendem o `params` comum. -Choose the smallest group that contains the services you need. If the host -application only needs domain services, keep those definitions in -`config/common/di/*.php` so both Yii and the third-party app can use them -without web-only dependencies. +Escolha o menor grupo que contém os serviços de que você precisa. Se a +aplicação hospedeira só precisa de serviços de domínio, mantenha essas +definições em `config/common/di/*.php` para que tanto o Yii quanto a +aplicação de terceiros possam usá-las sem dependências exclusivas da web. -After changing `config/configuration.php`, rebuild the merge plan: +Depois de alterar `config/configuration.php`, reconstrua o merge plan: ```shell composer yii-config-rebuild ``` -## Error handling and logging +## Tratamento de erros e logs -The host application should remain responsible for top-level error -handling. Catch exceptions at the integration boundary when the host app -needs to convert them into its own response or error format. +A aplicação hospedeira deve continuar responsável pelo tratamento de erros +de nível mais alto. Capture as exceções na fronteira da integração quando a +aplicação hospedeira precisar convertê-las na sua própria resposta ou +formato de erro. -Yii services can still use `Psr\Log\LoggerInterface`. Configure the Yii -logger to write to the same destination as the host application or bridge -both applications to the same PSR-3 logger. +Os serviços do Yii ainda podem usar `Psr\Log\LoggerInterface`. Configure o +logger do Yii para gravar no mesmo destino da aplicação hospedeira ou +conecte as duas aplicações ao mesmo logger PSR-3. -## Long-running host processes +## Processos hospedeiros de longa duração -If the third-party application is a worker, daemon, or event-loop server, -avoid mutable shared state in services. Yii services resolved from the -container are shared by default, so design them as stateless services or -create a fresh container for each isolated job when stateful dependencies -are unavoidable. +Se a aplicação de terceiros for um worker, um daemon ou um servidor com +event loop, evite estado mutável compartilhado nos serviços. Os serviços do +Yii obtidos do container são compartilhados por padrão, então projete-os +como serviços sem estado ou crie um container novo para cada job isolado +quando dependências com estado forem inevitáveis. diff --git a/src/pt-BR/cookbook/working-on-windows.md b/src/pt-BR/cookbook/working-on-windows.md index a89a91f7..c482e356 100644 --- a/src/pt-BR/cookbook/working-on-windows.md +++ b/src/pt-BR/cookbook/working-on-windows.md @@ -1,14 +1,15 @@ -# Working on Windows +# Trabalhando no Windows -Yii applications usually run on Linux in production. On Windows, choose a -local workflow that stays close to that environment and keeps filesystem -performance predictable. +Aplicações Yii geralmente rodam no Linux em produção. No Windows, escolha um +fluxo de trabalho local que fique próximo desse ambiente e mantenha o +desempenho do sistema de arquivos previsível. -## Recommended setup: WSL +## Configuração recomendada: WSL -Use [Windows Subsystem for Linux](https://learn.microsoft.com/windows/wsl/) -with a Linux distribution such as Ubuntu. Install PHP, Composer, Git, and -Make inside WSL, then clone the project into the Linux filesystem: +Use o [Windows Subsystem for +Linux](https://learn.microsoft.com/windows/wsl/) com uma distribuição Linux +como o Ubuntu. Instale PHP, Composer, Git e Make dentro do WSL e depois +clone o projeto no sistema de arquivos do Linux: ```shell cd ~ @@ -17,19 +18,22 @@ cd my-app composer install ``` -Keep the project under the WSL filesystem, for example -`/home/user/projects/my-app`. Avoid working from a mounted Windows path such -as `/mnt/c/Users/user/projects/my-app`; it is much slower for Composer, -tests, and tools that read many small files. +Mantenha o projeto no sistema de arquivos do WSL, por exemplo +`/home/user/projects/my-app`. Evite trabalhar a partir de um caminho montado +do Windows, como `/mnt/c/Users/user/projects/my-app`; ele é muito mais lento +para o Composer, os testes e as ferramentas que leem muitos arquivos +pequenos. -You can open the project from Windows editors through the WSL -integration. In PhpStorm, open the project from the WSL filesystem. In VS -Code, use the WSL extension and open the folder from inside the WSL session. +Você pode abrir o projeto em editores do Windows por meio da integração com +o WSL. No PhpStorm, abra o projeto a partir do sistema de arquivos do +WSL. No VS Code, use a extensão WSL e abra a pasta de dentro da sessão do +WSL. -## Docker with WSL +## Docker com WSL -Docker Desktop with the WSL backend is also a good Windows setup. Keep the -project in the WSL filesystem and run Docker commands from WSL: +O Docker Desktop com o backend WSL também é uma boa configuração no +Windows. Mantenha o projeto no sistema de arquivos do WSL e rode os comandos +do Docker a partir do WSL: ```shell make build @@ -38,47 +42,50 @@ make yii make test ``` -This keeps bind mounts fast and gives containers Linux paths that match the -tooling used by the Yii application templates. +Isso mantém os bind mounts rápidos e dá aos containers caminhos Linux que +batem com as ferramentas usadas pelos templates de aplicação do Yii. -If you need IDE links from debug stack traces, set `APP_HOST_PATH` to the -project path that your IDE can open. +Se você precisar de links para a IDE nos stack traces de debug, defina +`APP_HOST_PATH` com o caminho do projeto que a sua IDE consegue abrir. ## Git Bash -[Git for Windows](https://git-scm.com/downloads/win) installs Git Bash and -common Unix tools. It can be enough when you want to run the application -directly on Windows without WSL or Docker. +O [Git for Windows](https://git-scm.com/downloads/win) instala o Git Bash e +ferramentas Unix comuns. Ele pode bastar quando você quer rodar a aplicação +diretamente no Windows, sem WSL nem Docker. -Use this option when your project does not depend on Linux-only extensions -or shell scripts. Check the same commands you expect contributors to use: +Use esta opção quando o seu projeto não depende de extensões ou scripts de +shell exclusivos do Linux. Teste os mesmos comandos que você espera que os +contribuidores usem: ```shell composer install composer test ``` -If the project uses `make`, Git for Windows includes a Bash environment, but -`make` availability depends on your local installation. Install it -separately when needed. +Se o projeto usa `make`, o Git for Windows inclui um ambiente Bash, mas a +disponibilidade do `make` depende da sua instalação local. Instale-o +separadamente quando necessário. -## PowerShell and CMD +## PowerShell e CMD -PowerShell and CMD can run PHP and Composer, but they differ from the common -Linux server environment in quoting, environment variables, paths, and shell -utilities. Use them for simple commands only. +O PowerShell e o CMD conseguem rodar PHP e Composer, mas diferem do ambiente +comum de servidores Linux em aspas, variáveis de ambiente, caminhos e +utilitários de shell. Use-os apenas para comandos simples. -For regular Yii development on Windows, prefer WSL or Docker with WSL. +Para o desenvolvimento regular com Yii no Windows, prefira o WSL ou o Docker +com WSL. -## Choosing a workflow +## Escolhendo um fluxo de trabalho -Use WSL when you want the closest local match to a Linux server and do not -need containers for every service. +Use o WSL quando quiser o ambiente local mais parecido com um servidor Linux +e não precisar de containers para cada serviço. -Use Docker with WSL when you want the application, database, and other -services described by Compose files. +Use o Docker com WSL quando quiser a aplicação, o banco de dados e outros +serviços descritos em arquivos do Compose. -Use Git Bash for small projects or quick checks that run directly on -Windows. +Use o Git Bash para projetos pequenos ou verificações rápidas que rodam +diretamente no Windows. -Use PowerShell or CMD when the command is known to be platform-neutral. +Use o PowerShell ou o CMD quando se sabe que o comando é independente de +plataforma. From f13097a055d80c6e2d6353ea1405d2a1dbd1e45d Mon Sep 17 00:00:00 2001 From: Yuri Neves Date: Fri, 23 Oct 2026 14:18:15 -0300 Subject: [PATCH 08/11] Translate internals to Brazilian Portuguese --- .../po/pt-BR/internals_000-packages.md.po | 90 ++++--- .../po/pt-BR/internals_001-yii-values.md.po | 90 +++---- .../pt-BR/internals_002-issue-workflow.md.po | 34 +-- .../po/pt-BR/internals_003-roadmap.md.po | 224 ++++++++-------- .../po/pt-BR/internals_004-namespaces.md.po | 36 +-- .../internals_005-development-tool.md.po | 43 +++- .../internals_006-git-commit-messages.md.po | 27 +- .../po/pt-BR/internals_007-exceptions.md.po | 30 +-- .../po/pt-BR/internals_008-interfaces.md.po | 22 +- .../internals_009-design-decisions.md.po | 72 +++--- .../po/pt-BR/internals_010-code-style.md.po | 192 ++++++++------ .../internals_011-error-correction.md.po | 8 +- .../po/pt-BR/internals_012-tests.md.po | 26 +- .../po/pt-BR/internals_013-code-review.md.po | 44 ++-- .../po/pt-BR/internals_014-docs.md.po | 184 ++++++++++---- .../po/pt-BR/internals_015-phpstorm.md.po | 55 ++-- .../internals_016-security-workflow.md.po | 63 +++-- .../po/pt-BR/internals_017-tags.md.po | 53 ++-- .../po/pt-BR/internals_018-widgets.md.po | 49 ++-- .../pt-BR/internals_019-view-code-style.md.po | 38 ++- .../pt-BR/internals_020-package-release.md.po | 56 ++-- .../internals_021-changelog-upgrade.md.po | 61 +++-- .../pt-BR/internals_022-config-groups.md.po | 96 ++++--- .../pt-BR/internals_023-github-actions.md.po | 26 +- src/pt-BR/internals/000-packages.md | 103 ++++---- src/pt-BR/internals/001-yii-values.md | 115 +++++---- src/pt-BR/internals/002-issue-workflow.md | 33 +-- src/pt-BR/internals/003-roadmap.md | 239 +++++++++--------- src/pt-BR/internals/004-namespaces.md | 20 +- src/pt-BR/internals/005-development-tool.md | 37 +-- .../internals/006-git-commit-messages.md | 22 +- src/pt-BR/internals/007-exceptions.md | 26 +- src/pt-BR/internals/008-interfaces.md | 12 +- src/pt-BR/internals/009-design-decisions.md | 126 ++++----- src/pt-BR/internals/010-code-style.md | 152 +++++------ src/pt-BR/internals/011-error-correction.md | 8 +- src/pt-BR/internals/012-tests.md | 35 +-- src/pt-BR/internals/013-code-review.md | 46 ++-- src/pt-BR/internals/014-docs.md | 169 ++++++------- src/pt-BR/internals/015-phpstorm.md | 50 ++-- src/pt-BR/internals/016-security-workflow.md | 82 +++--- src/pt-BR/internals/017-tags.md | 56 ++-- src/pt-BR/internals/018-widgets.md | 44 ++-- src/pt-BR/internals/019-view-code-style.md | 28 +- src/pt-BR/internals/020-package-release.md | 64 ++--- src/pt-BR/internals/021-changelog-upgrade.md | 41 +-- src/pt-BR/internals/022-config-groups.md | 88 +++---- src/pt-BR/internals/023-github-actions.md | 18 +- 48 files changed, 1750 insertions(+), 1483 deletions(-) diff --git a/_translations/po/pt-BR/internals_000-packages.md.po b/_translations/po/pt-BR/internals_000-packages.md.po index fdee20da..77881865 100644 --- a/_translations/po/pt-BR/internals_000-packages.md.po +++ b/_translations/po/pt-BR/internals_000-packages.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2025-12-24 08:02+0000\n" "PO-Revision-Date: 2025-12-24 08:02+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -18,126 +18,126 @@ msgstr "" #. type: Bullet: ' - ' #: ../src/en/guide/start/databases.md ../src/en/internals/000-packages.md msgid "..." -msgstr "" +msgstr "..." #. type: Title # #: ../src/en/internals/000-packages.md #, no-wrap msgid "000 — Packages" -msgstr "" +msgstr "000 — Pacotes" #. type: Plain text #: ../src/en/internals/000-packages.md msgid "Yii3 team divided the framework into several packages that conform to the following agreements." -msgstr "" +msgstr "O time do Yii3 dividiu o framework em vários pacotes que seguem os acordos abaixo." #. type: Plain text #: ../src/en/internals/000-packages.md msgid "For all packages, the GitHub repository name exactly matches the Packagist package name." -msgstr "" +msgstr "Em todos os pacotes, o nome do repositório no GitHub corresponde exatamente ao nome do pacote no Packagist." #. type: Plain text #: ../src/en/internals/000-packages.md msgid "For a full list of packages and their building status, see [status page at yiiframework.com](https://www.yiiframework.com/status/3.0)." -msgstr "" +msgstr "Para ver a lista completa de pacotes e o status de build de cada um, consulte a [página de status em yiiframework.com](https://www.yiiframework.com/status/3.0)." #. type: Title ## #: ../src/en/internals/000-packages.md #, no-wrap msgid "Yii-specific packages (framework and extensions)" -msgstr "" +msgstr "Pacotes específicos do Yii (framework e extensões)" #. type: Bullet: '- ' #: ../src/en/internals/000-packages.md msgid "named `yiisoft/yii-something` or more specific: `yii-type-something` e.g.:" -msgstr "" +msgstr "nomeados como `yiisoft/yii-something` ou de forma mais específica: `yii-type-something`, por exemplo:" #. type: Bullet: ' - ' #: ../src/en/internals/000-packages.md msgid "modules: `yii-module-users`, `yii-module-pages`" -msgstr "" +msgstr "módulos: `yii-module-users`, `yii-module-pages`" #. type: Bullet: ' - ' #: ../src/en/internals/000-packages.md msgid "themes: `yii-theme-adminlte`, `yii-theme-hyde`" -msgstr "" +msgstr "temas: `yii-theme-adminlte`, `yii-theme-hyde`" #. type: Bullet: ' - ' #: ../src/en/internals/000-packages.md msgid "widgets: `yii-widget-datepicker`" -msgstr "" +msgstr "widgets: `yii-widget-datepicker`" #. type: Bullet: '- ' #: ../src/en/internals/000-packages.md msgid "titled as \"Yii Framework ...\"" -msgstr "" +msgstr "intitulados como \"Yii Framework ...\"" #. type: Bullet: '- ' #: ../src/en/internals/000-packages.md msgid "may have any dependencies and Yii-specific code" -msgstr "" +msgstr "podem ter quaisquer dependências e código específico do Yii" #. type: Title ## #: ../src/en/internals/000-packages.md #, no-wrap msgid "General purpose packages (libraries)" -msgstr "" +msgstr "Pacotes de uso geral (bibliotecas)" #. type: Bullet: '- ' #: ../src/en/internals/000-packages.md msgid "you can use these independently of Yii Framework" -msgstr "" +msgstr "você pode usá-los independentemente do Yii Framework" #. type: Bullet: '- ' #: ../src/en/internals/000-packages.md msgid "named as `yiisoft/something` without yii-prefix" -msgstr "" +msgstr "nomeados como `yiisoft/something`, sem o prefixo yii" #. type: Bullet: '- ' #: ../src/en/internals/000-packages.md msgid "titled as \"Yii ...\"" -msgstr "" +msgstr "intitulados como \"Yii ...\"" #. type: Bullet: '- ' #: ../src/en/internals/000-packages.md msgid "must not have dependencies on any Yii-specific packages" -msgstr "" +msgstr "não podem ter dependências de nenhum pacote específico do Yii" #. type: Bullet: '- ' #: ../src/en/internals/000-packages.md msgid "should have as fewer dependencies as possible" -msgstr "" +msgstr "devem ter o menor número possível de dependências" #. type: Title ## #: ../src/en/internals/000-packages.md #, no-wrap msgid "Configs and defaults" -msgstr "" +msgstr "Configurações e padrões" #. type: Plain text #: ../src/en/internals/000-packages.md msgid "The following applies to both Yii-specific packages and general purpose packages:" -msgstr "" +msgstr "O que segue se aplica tanto aos pacotes específicos do Yii quanto aos pacotes de uso geral:" #. type: Bullet: '- ' #: ../src/en/internals/000-packages.md msgid "Package may have `config` directory with Yii-specific defaults." -msgstr "" +msgstr "O pacote pode ter um diretório `config` com padrões específicos do Yii." #. type: Bullet: '- ' #: ../src/en/internals/000-packages.md msgid "Package may have \"config-plugin\" in \"extra\" section of `composer.json`." -msgstr "" +msgstr "O pacote pode ter \"config-plugin\" na seção \"extra\" do `composer.json`." #. type: Bullet: '- ' #: ../src/en/internals/000-packages.md msgid "Package mustn't have dependencies in `require` section of `composer.json` that are used in `config` only." -msgstr "" +msgstr "O pacote não pode ter, na seção `require` do `composer.json`, dependências usadas apenas em `config`." #. type: Bullet: '- ' #: ../src/en/internals/000-packages.md msgid "You should namespace parameters with `vendor/package-name`:" -msgstr "" +msgstr "Você deve colocar os parâmetros sob o namespace `vendor/package-name`:" #. type: Fenced code block (php) #: ../src/en/internals/000-packages.md @@ -150,87 +150,93 @@ msgid "" " ],\n" "];\n" msgstr "" +"return [\n" +" 'vendor/package-name' => [\n" +" 'param1' => 1,\n" +" 'param2' => 2,\n" +" ],\n" +"];\n" #. type: Title ## #: ../src/en/internals/000-packages.md #, no-wrap msgid "Versions" -msgstr "" +msgstr "Versões" #. type: Plain text #: ../src/en/internals/000-packages.md msgid "All packages follow [SemVer](https://semver.org/) versioning:" -msgstr "" +msgstr "Todos os pacotes seguem o versionamento [SemVer](https://semver.org/):" #. type: Bullet: '- ' #: ../src/en/internals/000-packages.md msgid "`x.*.*` - incompatible API changes." -msgstr "" +msgstr "`x.*.*` - mudanças incompatíveis na API." #. type: Bullet: '- ' #: ../src/en/internals/000-packages.md msgid "`*.x.*` - add functionality (backwards-compatible)." -msgstr "" +msgstr "`*.x.*` - adição de funcionalidades (compatível com versões anteriores)." #. type: Bullet: '- ' #: ../src/en/internals/000-packages.md msgid "`*.*.x` - bug fixes (backwards-compatible)." -msgstr "" +msgstr "`*.*.x` - correções de bugs (compatível com versões anteriores)." #. type: Plain text #: ../src/en/internals/000-packages.md msgid "The first stable version should be 1.0.0." -msgstr "" +msgstr "A primeira versão estável deve ser 1.0.0." #. type: Plain text #: ../src/en/internals/000-packages.md msgid "Each package version number doesn't depend on any other package version or framework name/version, only on its own public contract. The framework as a whole has the \"Yii3\" name." -msgstr "" +msgstr "O número de versão de cada pacote não depende da versão de nenhum outro pacote nem do nome/versão do framework, apenas do seu próprio contrato público. O framework como um todo tem o nome \"Yii3\"." #. type: Plain text #: ../src/en/internals/000-packages.md msgid "It's alright to use packages with different major versions together, as long as they're compatible." -msgstr "" +msgstr "Não há problema em usar juntos pacotes com versões major diferentes, desde que sejam compatíveis." #. type: Title ## #: ../src/en/internals/000-packages.md #, no-wrap msgid "PHP versions support" -msgstr "" +msgstr "Suporte a versões do PHP" #. type: Plain text #: ../src/en/internals/000-packages.md msgid "The support of PHP versions supported for a package depends on [PHP versions life cycle](https://www.php.net/supported-versions.php)." -msgstr "" +msgstr "O suporte às versões do PHP em um pacote depende do [ciclo de vida das versões do PHP](https://www.php.net/supported-versions.php)." #. type: Bullet: '- ' #: ../src/en/internals/000-packages.md msgid "Package versions with active support MUST support all PHP versions that have active support." -msgstr "" +msgstr "Versões de pacotes com suporte ativo DEVEM suportar todas as versões do PHP que têm suporte ativo." #. type: Bullet: '- ' #: ../src/en/internals/000-packages.md msgid "Both packages and application templates MUST have supported versions that receive bug and security fixes. These SHOULD correspond to PHP versions receiving security fixes." -msgstr "" +msgstr "Tanto os pacotes quanto os templates de aplicação DEVEM ter versões suportadas que recebem correções de bugs e de segurança. Essas versões DEVERIAM corresponder às versões do PHP que recebem correções de segurança." #. type: Bullet: '- ' #: ../src/en/internals/000-packages.md msgid "Packages and application templates MIGHT have supported versions that work with unsupported PHP versions." -msgstr "" +msgstr "Pacotes e templates de aplicação PODEM ter versões suportadas que funcionam com versões do PHP sem suporte." #. type: Bullet: '- ' #: ../src/en/internals/000-packages.md msgid "Bumping the minimal PHP version in a package or an application template is a minor change." -msgstr "" +msgstr "Aumentar a versão mínima do PHP em um pacote ou template de aplicação é uma mudança minor." #. type: Title ## #: ../src/en/internals/000-packages.md #, no-wrap msgid "composer.json" -msgstr "" +msgstr "composer.json" #. type: Plain text #: ../src/en/internals/000-packages.md #, no-wrap msgid "A logical OR operator in version ranges MUST use double pipe (`||`). For example: `\"yiisoft/arrays\": \"^1.0 || ^2.0\"`. \n" -msgstr "" +msgstr "Um operador lógico OU em intervalos de versão DEVE usar pipe duplo (`||`). Por exemplo: `\"yiisoft/arrays\": \"^1.0 || ^2.0\"`. \n" diff --git a/_translations/po/pt-BR/internals_001-yii-values.md.po b/_translations/po/pt-BR/internals_001-yii-values.md.po index 4517234d..b804715f 100644 --- a/_translations/po/pt-BR/internals_001-yii-values.md.po +++ b/_translations/po/pt-BR/internals_001-yii-values.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2025-12-24 08:02+0000\n" "PO-Revision-Date: 2025-12-24 08:02+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,224 +19,224 @@ msgstr "" #: ../src/en/internals/001-yii-values.md #, no-wrap msgid "001 — Yii goal and values" -msgstr "" +msgstr "001 — Objetivo e valores do Yii" #. type: Title ## #: ../src/en/internals/001-yii-values.md #, no-wrap msgid "Goal" -msgstr "" +msgstr "Objetivo" #. type: Plain text #: ../src/en/internals/001-yii-values.md msgid "The Yii project aims to build and support _practical_ and _helpful_ tools and community." -msgstr "" +msgstr "O projeto Yii tem como objetivo construir e manter ferramentas e uma comunidade _práticas_ e _úteis_." #. type: Title ## #: ../src/en/internals/001-yii-values.md #, no-wrap msgid "Values" -msgstr "" +msgstr "Valores" #. type: Plain text #: ../src/en/internals/001-yii-values.md msgid "The values we express in our work support the goal. We try to" -msgstr "" +msgstr "Os valores que expressamos em nosso trabalho apoiam esse objetivo. Procuramos" #. type: Title ## #: ../src/en/internals/001-yii-values.md #, no-wrap msgid "Be practical" -msgstr "" +msgstr "Ser práticos" #. type: Bullet: ' - ' #: ../src/en/internals/001-yii-values.md msgid "[High performance](#high-performance)" -msgstr "" +msgstr "[Alto desempenho](#alto-desempenho)" #. type: Bullet: ' - ' #: ../src/en/internals/001-yii-values.md msgid "[Sensible defaults and flexibility](#sensible-defaults-and-flexibility)" -msgstr "" +msgstr "[Padrões sensatos e flexibilidade](#padroes-sensatos-e-flexibilidade)" #. type: Bullet: ' - ' #: ../src/en/internals/001-yii-values.md msgid "[Be practice-oriented](#be-practice-oriented)" -msgstr "" +msgstr "[Ser orientado à prática](#ser-orientado-a-pratica)" #. type: Title ## #: ../src/en/internals/001-yii-values.md #, no-wrap msgid "Be helpful" -msgstr "" +msgstr "Ser úteis" #. type: Bullet: ' - ' #: ../src/en/internals/001-yii-values.md msgid "[Be simple](#be-simple)" -msgstr "" +msgstr "[Ser simples](#ser-simples)" #. type: Bullet: ' - ' #: ../src/en/internals/001-yii-values.md msgid "[Be explicit](#be-explicit)" -msgstr "" +msgstr "[Ser explícito](#ser-explicito)" #. type: Bullet: ' - ' #: ../src/en/internals/001-yii-values.md msgid "[Be consistent](#be-consistent)" -msgstr "" +msgstr "[Ser consistente](#ser-consistente)" #. type: Title ### #: ../src/en/internals/001-yii-values.md #, no-wrap msgid "High performance" -msgstr "" +msgstr "Alto desempenho" #. type: Plain text #: ../src/en/internals/001-yii-values.md msgid "Performance is a necessary condition of practicality. Software shouldn't waste machine resources or human resources." -msgstr "" +msgstr "Desempenho é uma condição necessária para a praticidade. O software não deve desperdiçar recursos de máquina nem recursos humanos." #. type: Title ### #: ../src/en/internals/001-yii-values.md #, no-wrap msgid "Sensible defaults and flexibility" -msgstr "" +msgstr "Padrões sensatos e flexibilidade" #. type: Plain text #: ../src/en/internals/001-yii-values.md msgid "We prefer sensible defaults and conventions that users can customize. We seek a balance between flexibility, discipline and simplicity that meets common needs." -msgstr "" +msgstr "Preferimos padrões e convenções sensatos que os usuários possam personalizar. Buscamos um equilíbrio entre flexibilidade, disciplina e simplicidade que atenda às necessidades comuns." #. type: Title ### #: ../src/en/internals/001-yii-values.md #, no-wrap msgid "Be practice-oriented" -msgstr "" +msgstr "Ser orientado à prática" #. type: Plain text #: ../src/en/internals/001-yii-values.md msgid "We prefer practice to theory. For example:" -msgstr "" +msgstr "Preferimos a prática à teoria. Por exemplo:" #. type: Bullet: '- ' #: ../src/en/internals/001-yii-values.md msgid "Solutions for known use cases should avoid excess complexity by providing only necessary flexibility." -msgstr "" +msgstr "Soluções para casos de uso conhecidos devem evitar complexidade excessiva, oferecendo apenas a flexibilidade necessária." #. type: Bullet: '- ' #: ../src/en/internals/001-yii-values.md msgid "Standard implementations should take practical use into account." -msgstr "" +msgstr "Implementações padrão devem levar em conta o uso prático." #. type: Bullet: '- ' #: ../src/en/internals/001-yii-values.md msgid "Experience is at least as useful as theory in guiding design." -msgstr "" +msgstr "A experiência é pelo menos tão útil quanto a teoria para orientar o design." #. type: Bullet: '- ' #: ../src/en/internals/001-yii-values.md msgid "Context is critical in determining appropriateness." -msgstr "" +msgstr "O contexto é fundamental para determinar o que é adequado." #. type: Plain text #: ../src/en/internals/001-yii-values.md msgid "This value guides technical decisions as well as community activity. Consideration of how software features help users should guide development. Community-wise, we value any helpful contribution, be it a pull request or an answer in the forum." -msgstr "" +msgstr "Esse valor orienta tanto as decisões técnicas quanto a atividade da comunidade. O desenvolvimento deve ser guiado pela forma como os recursos do software ajudam os usuários. Na comunidade, valorizamos qualquer contribuição útil, seja um pull request ou uma resposta no fórum." #. type: Plain text #: ../src/en/internals/001-yii-values.md msgid "When the other principles conflict, we choose a solution that's more helpful to the community." -msgstr "" +msgstr "Quando os outros princípios entram em conflito, escolhemos a solução mais útil para a comunidade." #. type: Title ### #: ../src/en/internals/001-yii-values.md #, no-wrap msgid "Be simple" -msgstr "" +msgstr "Ser simples" #. type: Plain text #: ../src/en/internals/001-yii-values.md msgid "Solutions should be simple and expressive:" -msgstr "" +msgstr "As soluções devem ser simples e expressivas:" #. type: Bullet: '- ' #: ../src/en/internals/001-yii-values.md msgid "We use as much complexity as needed and no more." -msgstr "" +msgstr "Usamos tanta complexidade quanto necessário, e não mais." #. type: Bullet: '- ' #: ../src/en/internals/001-yii-values.md msgid "We avoid ugly solutions unless there is no alternative." -msgstr "" +msgstr "Evitamos soluções feias, a menos que não haja alternativa." #. type: Bullet: '- ' #: ../src/en/internals/001-yii-values.md msgid "Fewer rules are better than more rules." -msgstr "" +msgstr "Menos regras é melhor do que mais regras." #. type: Title ### #: ../src/en/internals/001-yii-values.md #, no-wrap msgid "Be Explicit" -msgstr "" +msgstr "Ser explícito" #. type: Plain text #: ../src/en/internals/001-yii-values.md msgid "We prefer explicit, obvious solutions and code. Solutions should clearly express exactly what they do. For example:" -msgstr "" +msgstr "Preferimos soluções e código explícitos e óbvios. As soluções devem expressar claramente o que fazem. Por exemplo:" #. type: Bullet: '- ' #: ../src/en/internals/001-yii-values.md msgid "A straightforward solution is better than an abstract one unless the abstraction has a practical purpose." -msgstr "" +msgstr "Uma solução direta é melhor do que uma abstrata, a menos que a abstração tenha um propósito prático." #. type: Bullet: '- ' #: ../src/en/internals/001-yii-values.md msgid "Loud fails are better than silent fails or masking errors." -msgstr "" +msgstr "Falhas ruidosas são melhores do que falhas silenciosas ou erros mascarados." #. type: Bullet: '- ' #: ../src/en/internals/001-yii-values.md msgid "Explicit casts are better than PHP type juggling, type hints are good." -msgstr "" +msgstr "Conversões explícitas são melhores do que a conversão automática de tipos do PHP; type hints são bons." #. type: Bullet: '- ' #: ../src/en/internals/001-yii-values.md msgid "No magic unless necessary." -msgstr "" +msgstr "Nada de mágica, a menos que seja necessário." #. type: Title ### #: ../src/en/internals/001-yii-values.md #, no-wrap msgid "Be consistent" -msgstr "" +msgstr "Ser consistente" #. type: Plain text #: ../src/en/internals/001-yii-values.md msgid "We try to be consistent in:" -msgstr "" +msgstr "Procuramos ser consistentes em:" #. type: Bullet: '- ' #: ../src/en/internals/001-yii-values.md msgid "Code style" -msgstr "" +msgstr "Estilo de código" #. type: Bullet: '- ' #: ../src/en/internals/001-yii-values.md msgid "Naming" -msgstr "" +msgstr "Nomenclatura" #. type: Bullet: '- ' #: ../src/en/internals/001-yii-values.md msgid "Design" -msgstr "" +msgstr "Design" #. type: Bullet: '- ' #: ../src/en/internals/001-yii-values.md msgid "Structure" -msgstr "" +msgstr "Estrutura" #. type: Bullet: '- ' #: ../src/en/internals/001-yii-values.md msgid "Values and goals" -msgstr "" +msgstr "Valores e objetivos" diff --git a/_translations/po/pt-BR/internals_002-issue-workflow.md.po b/_translations/po/pt-BR/internals_002-issue-workflow.md.po index 5b8fca50..596a7acb 100644 --- a/_translations/po/pt-BR/internals_002-issue-workflow.md.po +++ b/_translations/po/pt-BR/internals_002-issue-workflow.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2025-12-24 10:12+0000\n" "PO-Revision-Date: 2025-12-24 10:12+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,77 +19,77 @@ msgstr "" #: ../src/internals/002-issue-workflow.md #, no-wrap msgid "002 — Issue workflow" -msgstr "" +msgstr "002 — Fluxo de issues" #. type: Plain text #: ../src/internals/002-issue-workflow.md msgid "The process of handing incoming issues is the following:" -msgstr "" +msgstr "O processo de tratamento das issues recebidas é o seguinte:" #. type: Plain text #: ../src/internals/002-issue-workflow.md msgid "![Issue workflow schema](/images/internals/002-issue-workflow.svg)" -msgstr "" +msgstr "![Esquema do fluxo de issues](/images/internals/002-issue-workflow.svg)" #. type: Title ## #: ../src/internals/002-issue-workflow.md #, no-wrap msgid "Roles" -msgstr "" +msgstr "Papéis" #. type: Plain text #: ../src/internals/002-issue-workflow.md msgid "We've many roles:" -msgstr "" +msgstr "Temos vários papéis:" #. type: Bullet: '- ' #: ../src/internals/002-issue-workflow.md msgid "Process managers - initially triage issues and manage labels." -msgstr "" +msgstr "Gerentes de processo - fazem a triagem inicial das issues e gerenciam os labels." #. type: Bullet: '- ' #: ../src/internals/002-issue-workflow.md msgid "Decision makers - participate in discussions moving them to resolutions." -msgstr "" +msgstr "Tomadores de decisão - participam das discussões, levando-as a uma resolução." #. type: Bullet: '- ' #: ../src/internals/002-issue-workflow.md msgid "Bug hunters - verifying bugs." -msgstr "" +msgstr "Caçadores de bugs - verificam os bugs." #. type: Bullet: '- ' #: ../src/internals/002-issue-workflow.md msgid "Contributors - create code for pull requests." -msgstr "" +msgstr "Contribuidores - escrevem o código dos pull requests." #. type: Bullet: '- ' #: ../src/internals/002-issue-workflow.md msgid "Code reviewers - review pull requests." -msgstr "" +msgstr "Revisores de código - revisam os pull requests." #. type: Plain text #: ../src/internals/002-issue-workflow.md msgid "A single person may take one or more roles in the issue-resolving process." -msgstr "" +msgstr "Uma mesma pessoa pode assumir um ou mais papéis no processo de resolução de issues." #. type: Title ## #: ../src/internals/002-issue-workflow.md #, no-wrap msgid "Labels" -msgstr "" +msgstr "Labels" #. type: Plain text #: ../src/internals/002-issue-workflow.md msgid "We label issues to mark many things: current status, issue type, component affected. Status labels speak for themselves." -msgstr "" +msgstr "Usamos labels nas issues para marcar várias coisas: status atual, tipo da issue, componente afetado. Os labels de status falam por si." #. type: Title ## #: ../src/internals/002-issue-workflow.md #, no-wrap msgid "Milestones" -msgstr "" +msgstr "Milestones" #. type: Plain text #: ../src/internals/002-issue-workflow.md msgid "Issues aren't assigned to milestones unless they're critical or there is a likely good pull request exists." -msgstr "" +msgstr "As issues não são atribuídas a milestones, a menos que sejam críticas ou que provavelmente exista um bom pull request para elas." diff --git a/_translations/po/pt-BR/internals_003-roadmap.md.po b/_translations/po/pt-BR/internals_003-roadmap.md.po index 309d4855..dd9183fe 100644 --- a/_translations/po/pt-BR/internals_003-roadmap.md.po +++ b/_translations/po/pt-BR/internals_003-roadmap.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-01-10 15:51+0000\n" "PO-Revision-Date: 2026-01-10 15:51+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -25,574 +25,574 @@ msgstr "Documentação" #: ../src/cookbook/sentry-integration.md ../src/internals/003-roadmap.md #, no-wrap msgid "Console" -msgstr "" +msgstr "Console" #. type: Title # #: ../src/internals/003-roadmap.md #, no-wrap msgid "003 — Roadmap" -msgstr "" +msgstr "003 — Roadmap" #. type: Plain text #: ../src/internals/003-roadmap.md msgid "We want Yii 3 to:" -msgstr "" +msgstr "Queremos que o Yii 3:" #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "Not limit a developer to choosing architecture. Allow anything from \"classic\" MVC to DDD." -msgstr "" +msgstr "Não limite o desenvolvedor na escolha da arquitetura. Permita qualquer coisa, do MVC \"clássico\" ao DDD." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "Be based on the best practices such as SOLID, GRASP, etc. and teach them to the community." -msgstr "" +msgstr "Seja baseado em boas práticas como SOLID, GRASP etc. e as ensine à comunidade." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "Keep the most good things from Yii 2." -msgstr "" +msgstr "Mantenha a maior parte das coisas boas do Yii 2." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "Be more open to the global PHP community and infrastructure." -msgstr "" +msgstr "Seja mais aberto à comunidade e à infraestrutura PHP global." #. type: Title ## #: ../src/internals/003-roadmap.md #, no-wrap msgid "PSRs compliance" -msgstr "" +msgstr "Conformidade com PSRs" #. type: Plain text #: ../src/internals/003-roadmap.md msgid "PSR compliance helps with customizability, the ability to use general PHP libraries and implement fewer wrappers. Here's the list of PSRs we want to implement." -msgstr "" +msgstr "A conformidade com PSRs ajuda na personalização, permite usar bibliotecas PHP gerais e implementar menos wrappers. Aqui está a lista de PSRs que queremos implementar." #. type: Title ### #: ../src/internals/003-roadmap.md #, no-wrap msgid "PSR-3 Logger" -msgstr "" +msgstr "PSR-3 Logger" #. type: Plain text #: ../src/internals/003-roadmap.md msgid "Implemented as a [separate package that isn't dependent on a framework](https://github.com/yiisoft/log)." -msgstr "" +msgstr "Implementado como um [pacote separado que não depende de um framework](https://github.com/yiisoft/log)." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Framework packages should depend on interface only." -msgstr "" +msgstr "[x] Os pacotes do framework devem depender apenas da interface." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Split drivers into packages." -msgstr "" +msgstr "[x] Separar os drivers em pacotes." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Clean-up code." -msgstr "" +msgstr "[x] Limpar o código." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] [Fix email target](https://github.com/yiisoft/log-target-email)." -msgstr "" +msgstr "[x] [Corrigir o destino de e-mail](https://github.com/yiisoft/log-target-email)." #. type: Title ### #: ../src/internals/003-roadmap.md #, no-wrap msgid "PSR-4 Autoloading" -msgstr "" +msgstr "PSR-4 Autoloading" #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Autoloading is fine already." -msgstr "" +msgstr "[x] O autoloading já está bom." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Document on how it works." -msgstr "" +msgstr "[x] Documentar como funciona." #. type: Title ### #: ../src/internals/003-roadmap.md #, no-wrap msgid "PSR-7 HTTP message" -msgstr "" +msgstr "PSR-7 HTTP message" #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Remove our own implementation. At least for now." -msgstr "" +msgstr "[x] Remover nossa própria implementação. Pelo menos por enquanto." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Framework packages should depend on interfaces only." -msgstr "" +msgstr "[x] Os pacotes do framework devem depender apenas de interfaces." #. type: Title ### #: ../src/internals/003-roadmap.md #, no-wrap msgid "PSR-11 Container" -msgstr "" +msgstr "PSR-11 Container" #. type: Plain text #: ../src/internals/003-roadmap.md msgid "Implemented as a [separate package that isn't dependent on a framework](https://github.com/yiisoft/di)." -msgstr "" +msgstr "Implementado como um [pacote separado que não depende de um framework](https://github.com/yiisoft/di)." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Framework packages shouldn't use container directly. One should be able to instantiate everything manually." -msgstr "" +msgstr "[x] Os pacotes do framework não devem usar o container diretamente. Deve ser possível instanciar tudo manualmente." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Finish refactoring." -msgstr "" +msgstr "[x] Terminar a refatoração." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Remove all framework-specific implementations from the package. Move to a framework." -msgstr "" +msgstr "[x] Remover do pacote todas as implementações específicas do framework. Movê-las para o framework." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] [Implement autoloader fallback](https://github.com/yiisoft/di/issues/88)" -msgstr "" +msgstr "[x] [Implementar fallback para o autoloader](https://github.com/yiisoft/di/issues/88)" #. type: Title ### #: ../src/internals/003-roadmap.md #, no-wrap msgid "PSR-12 Code style" -msgstr "" +msgstr "PSR-12 Code style" #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Make sure the code follows it." -msgstr "" +msgstr "[x] Garantir que o código o siga." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Automate fixing style before release." -msgstr "" +msgstr "[x] Automatizar a correção de estilo antes do release." #. type: Title ### #: ../src/internals/003-roadmap.md #, no-wrap msgid "PSR-14 Event dispatcher" -msgstr "" +msgstr "PSR-14 Event dispatcher" #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] [Implement as a separate library](https://github.com/yiisoft/event-dispatcher)." -msgstr "" +msgstr "[x] [Implementar como uma biblioteca separada](https://github.com/yiisoft/event-dispatcher)." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Use in other packages." -msgstr "" +msgstr "[x] Usar em outros pacotes." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Polish." -msgstr "" +msgstr "[x] Polir." #. type: Title ### #: ../src/internals/003-roadmap.md #, no-wrap msgid "PSR-15 HTTP handlers" -msgstr "" +msgstr "PSR-15 HTTP handlers" #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Rewrite HTTP flow to PSR-7 request-response + formatting response via emitter." -msgstr "" +msgstr "[x] Reescrever o fluxo HTTP para requisição-resposta PSR-7 + formatação da resposta via emitter." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Offer SAPI emitter out of the box." -msgstr "" +msgstr "[x] Oferecer um emitter SAPI pronto para uso." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Make it possible to use alternative emitters such as RoadRunner." -msgstr "" +msgstr "[x] Possibilitar o uso de emitters alternativos, como o RoadRunner." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Support middleware." -msgstr "" +msgstr "[x] Suportar middleware." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Implement filters as middleware:" -msgstr "" +msgstr "[x] Implementar filtros como middleware:" #. type: Bullet: ' - ' #: ../src/internals/003-roadmap.md msgid "[x] [Rate limiting](https://github.com/yiisoft/yii-web/issues/63)" -msgstr "" +msgstr "[x] [Limitação de taxa](https://github.com/yiisoft/yii-web/issues/63)" #. type: Bullet: ' - ' #: ../src/internals/003-roadmap.md msgid "[x] [Authentication](https://github.com/yiisoft/yii-web/issues/114)" -msgstr "" +msgstr "[x] [Autenticação](https://github.com/yiisoft/yii-web/issues/114)" #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Re-implement router w/ middleware support for route groups." -msgstr "" +msgstr "[x] Reimplementar o router com suporte a middleware para grupos de rotas." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Filters should be middlewares." -msgstr "" +msgstr "[x] Filtros devem ser middlewares." #. type: Title ### #: ../src/internals/003-roadmap.md #, no-wrap msgid "PSR-16 Simple cache" -msgstr "" +msgstr "PSR-16 Simple cache" #. type: Plain text #: ../src/internals/003-roadmap.md msgid "Implemented as a [separate package that isn't dependent on a framework](https://github.com/yiisoft/cache)." -msgstr "" +msgstr "Implementado como um [pacote separado que não depende de um framework](https://github.com/yiisoft/cache)." #. type: Title ### #: ../src/internals/003-roadmap.md #, no-wrap msgid "PSR-17 HTTP factories" -msgstr "" +msgstr "PSR-17 HTTP factories" #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Use PSR factories." -msgstr "" +msgstr "[x] Usar as factories PSR." #. type: Title ### #: ../src/internals/003-roadmap.md #, no-wrap msgid "PSR-18 HTTP client" -msgstr "" +msgstr "PSR-18 HTTP client" #. type: Title ## #: ../src/internals/003-roadmap.md #, no-wrap msgid "Stricter types" -msgstr "" +msgstr "Tipos mais estritos" #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Make sure type hinting is used everywhere." -msgstr "" +msgstr "[x] Garantir que type hints sejam usados em todo lugar." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Make sure types are as definitive as possible. Avoid varying types if possible." -msgstr "" +msgstr "[x] Garantir que os tipos sejam o mais definidos possível. Evitar tipos variáveis sempre que possível." #. type: Title ## #: ../src/internals/003-roadmap.md #, no-wrap msgid "Single application template" -msgstr "" +msgstr "Template de aplicação único" #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Drop basic/advanced." -msgstr "" +msgstr "[x] Abandonar basic/advanced." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Create a [single application template that works out of the box](https://github.com/yiisoft/app)." -msgstr "" +msgstr "[x] Criar um [template de aplicação único que funcione de imediato](https://github.com/yiisoft/app)." #. type: Title ## #: ../src/internals/003-roadmap.md #, no-wrap msgid "Router" -msgstr "" +msgstr "Router" #. type: Plain text #: ../src/internals/003-roadmap.md msgid "Implemented as a [separate package that isn't dependent on a framework](https://github.com/yiisoft/router)." -msgstr "" +msgstr "Implementado como um [pacote separado que não depende de um framework](https://github.com/yiisoft/router)." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] DSL for configuration." -msgstr "" +msgstr "[x] DSL para configuração." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Ability to route to any callable." -msgstr "" +msgstr "[x] Possibilidade de rotear para qualquer callable." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Named routes." -msgstr "" +msgstr "[x] Rotas nomeadas." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Route groups w/ middleware support." -msgstr "" +msgstr "[x] Grupos de rotas com suporte a middleware." #. type: Title ## #: ../src/internals/003-roadmap.md #, no-wrap msgid "Best practices and SOLID compliance of all classes/packages" -msgstr "" +msgstr "Boas práticas e conformidade com SOLID em todas as classes/pacotes" #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Make sure interfaces follow the \"interface segregation\" principle." -msgstr "" +msgstr "[x] Garantir que as interfaces sigam o princípio de \"segregação de interfaces\"." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Don't use public properties." -msgstr "" +msgstr "[x] Não usar propriedades públicas." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Don't use `init()`." -msgstr "" +msgstr "[x] Não usar `init()`." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Don't inherit from `BaseObject` or `Component`. Remove these." -msgstr "" +msgstr "[x] Não herdar de `BaseObject` ou `Component`. Removê-los." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] No globals." -msgstr "" +msgstr "[x] Nada de globais." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] No static calls except helpers that are final." -msgstr "" +msgstr "[x] Nada de chamadas estáticas, exceto helpers finais." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Prefer throwing exceptions to fixing input." -msgstr "" +msgstr "[x] Preferir lançar exceções a corrigir a entrada." #. type: Title ## #: ../src/internals/003-roadmap.md #, no-wrap msgid "Development toolkit" -msgstr "" +msgstr "Kit de ferramentas de desenvolvimento" #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Release command line tool" -msgstr "" +msgstr "[x] Ferramenta de linha de comando para release" #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Development command line tool (symlinks packages into usable application)" -msgstr "" +msgstr "[x] Ferramenta de linha de comando para desenvolvimento (cria symlinks dos pacotes em uma aplicação utilizável)" #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Separate web and console application" -msgstr "" +msgstr "[x] Separar aplicação web e aplicação de console" #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Possibly eliminate base application (still needed)" -msgstr "" +msgstr "[x] Possivelmente eliminar a aplicação base (ainda é necessária)" #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Create an interface for the console (using Symfony one)" -msgstr "" +msgstr "[x] Criar uma interface para o console (usando a do Symfony)" #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Implementation may be one of the popular ones (using Symfony one)" -msgstr "" +msgstr "[x] A implementação pode ser uma das populares (usando a do Symfony)" #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Ensure application can add commands via config" -msgstr "" +msgstr "[x] Garantir que a aplicação possa adicionar comandos via configuração" #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[ ] Follow best practices." -msgstr "" +msgstr "[ ] Seguir boas práticas." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[ ] Don't use the \"MVC\" term." -msgstr "" +msgstr "[ ] Não usar o termo \"MVC\"." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[ ] Upgrading from Yii 2." -msgstr "" +msgstr "[ ] Upgrade a partir do Yii 2." #. type: Title ## #: ../src/internals/003-roadmap.md #, no-wrap msgid "RBAC" -msgstr "" +msgstr "RBAC" #. type: Plain text #: ../src/internals/003-roadmap.md msgid "RBAC is implemented as [a framework-independent package](https://github.com/yiisoft/rbac)." -msgstr "" +msgstr "O RBAC é implementado como [um pacote independente de framework](https://github.com/yiisoft/rbac)." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Make sure it follows best practices." -msgstr "" +msgstr "[x] Garantir que siga boas práticas." #. type: Title ## #: ../src/internals/003-roadmap.md #, no-wrap msgid "View" -msgstr "" +msgstr "View" #. type: Plain text #: ../src/internals/003-roadmap.md msgid "View is implemented as [framework-independent package](https://github.com/yiisoft/view)." -msgstr "" +msgstr "A view é implementada como [pacote independente de framework](https://github.com/yiisoft/view)." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Finish refactoring ([see issues](https://github.com/yiisoft/view/issues))." -msgstr "" +msgstr "[x] Terminar a refatoração ([veja as issues](https://github.com/yiisoft/view/issues))." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Port widgets." -msgstr "" +msgstr "[x] Portar os widgets." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Rethink and implement active form widgets." -msgstr "" +msgstr "[x] Repensar e implementar os widgets de active form." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Implement caching widgets." -msgstr "" +msgstr "[x] Implementar widgets de cache." #. type: Title ## #: ../src/internals/003-roadmap.md #, no-wrap msgid "Data abstractions and grid" -msgstr "" +msgstr "Abstrações de dados e grid" #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Finish [data abstractions](https://github.com/yiisoft/data)." -msgstr "" +msgstr "[x] Terminar as [abstrações de dados](https://github.com/yiisoft/data)." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Port sort, use data abstractions. Should be part of [yii-dataview](https://github.com/yiisoft/yii-dataview)." -msgstr "" +msgstr "[x] Portar a ordenação, usando abstrações de dados. Deve fazer parte do [yii-dataview](https://github.com/yiisoft/yii-dataview)." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Port paging, use data abstractions. Should be part of [yii-dataview](https://github.com/yiisoft/yii-dataview)." -msgstr "" +msgstr "[x] Portar a paginação, usando abstrações de dados. Deve fazer parte do [yii-dataview](https://github.com/yiisoft/yii-dataview)." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Port grid, use data abstractions. Should be part of [yii-dataview](https://github.com/yiisoft/yii-dataview)." -msgstr "" +msgstr "[x] Portar o grid, usando abstrações de dados. Deve fazer parte do [yii-dataview](https://github.com/yiisoft/yii-dataview)." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Port list, use data abstractions. Should be part of [yii-dataview](https://github.com/yiisoft/yii-dataview)." -msgstr "" +msgstr "[x] Portar a lista, usando abstrações de dados. Deve fazer parte do [yii-dataview](https://github.com/yiisoft/yii-dataview)." #. type: Title ## #: ../src/internals/003-roadmap.md #, no-wrap msgid "Validators" -msgstr "" +msgstr "Validadores" #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Finish [the main package](https://github.com/yiisoft/validator) redesign" -msgstr "" +msgstr "[x] Terminar o redesign do [pacote principal](https://github.com/yiisoft/validator)" #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Port necessary validators" -msgstr "" +msgstr "[x] Portar os validadores necessários" #. type: Title ## #: ../src/internals/003-roadmap.md #, no-wrap msgid "Debug toolbar" -msgstr "" +msgstr "Debug toolbar" #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Port debug toolbar." -msgstr "" +msgstr "[x] Portar a debug toolbar." #. type: Title ## #: ../src/internals/003-roadmap.md #, no-wrap msgid "Gii" -msgstr "" +msgstr "Gii" #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Port Gii." -msgstr "" +msgstr "[x] Portar o Gii." #. type: Title ## #: ../src/internals/003-roadmap.md #, no-wrap msgid "Infrastructure" -msgstr "" +msgstr "Infraestrutura" #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Cover [config](https://github.com/yiisoft/config) with tests." -msgstr "" +msgstr "[x] Cobrir o [config](https://github.com/yiisoft/config) com testes." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Release stable [config](https://github.com/yiisoft/config)." -msgstr "" +msgstr "[x] Lançar uma versão estável do [config](https://github.com/yiisoft/config)." #. type: Title ## #: ../src/internals/003-roadmap.md ../src/internals/022-config-groups.md #, no-wrap msgid "Others" -msgstr "" +msgstr "Outros" #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] [Decide on namespaces](https://forum.yiiframework.com/t/lowercase-or-camelcase-namespaces/124983/52)." -msgstr "" +msgstr "[x] [Decidir sobre os namespaces](https://forum.yiiframework.com/t/lowercase-or-camelcase-namespaces/124983/52)." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] [Clean up error handler](https://github.com/yiisoft/yii2/issues/14348). Make sure the error handler catches fatals and is using response." -msgstr "" +msgstr "[x] [Limpar o error handler](https://github.com/yiisoft/yii2/issues/14348). Garantir que o error handler capture erros fatais e use a resposta." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] Make validators independent of models to allow reusing them in handlers." -msgstr "" +msgstr "[x] Tornar os validadores independentes dos models para permitir reutilizá-los em handlers." #. type: Bullet: '- ' #: ../src/internals/003-roadmap.md msgid "[x] [Split IdentityInterface](https://github.com/yiisoft/yii2/issues/13825)." -msgstr "" +msgstr "[x] [Dividir a IdentityInterface](https://github.com/yiisoft/yii2/issues/13825)." diff --git a/_translations/po/pt-BR/internals_004-namespaces.md.po b/_translations/po/pt-BR/internals_004-namespaces.md.po index b53766f2..9569903d 100644 --- a/_translations/po/pt-BR/internals_004-namespaces.md.po +++ b/_translations/po/pt-BR/internals_004-namespaces.md.po @@ -8,60 +8,54 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2025-12-24 08:02+0000\n" "PO-Revision-Date: 2025-12-24 08:02+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/en/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md -#: ../src/en/guide/concept/autoloading.md -#: ../src/en/guide/security/best-practices.md -#: ../src/en/guide/structure/domain.md -#: ../src/en/guide/tutorial/console-applications.md -#: ../src/en/internals/004-namespaces.md ../src/en/internals/007-exceptions.md -#: ../src/en/internals/008-interfaces.md +#: ../src/en/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md ../src/en/guide/concept/autoloading.md ../src/en/guide/security/best-practices.md ../src/en/guide/structure/domain.md ../src/en/guide/tutorial/console-applications.md ../src/en/internals/004-namespaces.md ../src/en/internals/007-exceptions.md ../src/en/internals/008-interfaces.md #, no-wrap msgid "References" -msgstr "" +msgstr "Referências" #. type: Title # #: ../src/en/internals/004-namespaces.md #, no-wrap msgid "004 — Namespaces" -msgstr "" +msgstr "004 — Namespaces" #. type: Plain text #: ../src/en/internals/004-namespaces.md msgid "Package namespace rules are the following:" -msgstr "" +msgstr "As regras de namespace dos pacotes são as seguintes:" #. type: Bullet: '1. ' #: ../src/en/internals/004-namespaces.md msgid "PascalCase is used for namespace parts." -msgstr "" +msgstr "As partes do namespace usam PascalCase." #. type: Bullet: '2. ' #: ../src/en/internals/004-namespaces.md msgid "Root vendor namespace is `Yiisoft`." -msgstr "" +msgstr "O namespace raiz do vendor é `Yiisoft`." #. type: Bullet: '3. ' #: ../src/en/internals/004-namespaces.md msgid "Package name parts are used in namespace." -msgstr "" +msgstr "As partes do nome do pacote são usadas no namespace." #. type: Bullet: '4. ' #: ../src/en/internals/004-namespaces.md msgid "Adjective is added to a noun and is a single part." -msgstr "" +msgstr "Um adjetivo é unido ao substantivo e forma uma única parte." #. type: Plain text #: ../src/en/internals/004-namespaces.md msgid "Some examples:" -msgstr "" +msgstr "Alguns exemplos:" #. type: Plain text #: ../src/en/internals/004-namespaces.md @@ -74,8 +68,14 @@ msgid "" "| yiisoft/db-mysql | Yiisoft\\Db\\Mysql |\n" "| yiisoft/friendly-exception | Yiisoft\\FriendlyException |\n" msgstr "" +"| Pacote | Namespace |\n" +"|----------------------------|---------------------------|\n" +"| yiisoft/yii-web | Yiisoft\\Yii\\Web |\n" +"| yiisoft/di | Yiisoft\\Di |\n" +"| yiisoft/db-mysql | Yiisoft\\Db\\Mysql |\n" +"| yiisoft/friendly-exception | Yiisoft\\FriendlyException |\n" #. type: Bullet: '- ' #: ../src/en/internals/004-namespaces.md msgid "[International forum discussion](https://forum.yiiframework.com/t/use-yiisoft-as-a-root-namespace-instead-of-yii-for-yii-3-packages/125734)" -msgstr "" +msgstr "[Discussão no fórum internacional](https://forum.yiiframework.com/t/use-yiisoft-as-a-root-namespace-instead-of-yii-for-yii-3-packages/125734)" diff --git a/_translations/po/pt-BR/internals_005-development-tool.md.po b/_translations/po/pt-BR/internals_005-development-tool.md.po index 45eddbd0..2646f725 100644 --- a/_translations/po/pt-BR/internals_005-development-tool.md.po +++ b/_translations/po/pt-BR/internals_005-development-tool.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2025-12-24 08:02+0000\n" "PO-Revision-Date: 2025-12-24 08:02+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,12 +19,12 @@ msgstr "" #: ../src/en/internals/005-development-tool.md #, no-wrap msgid "005 — Yii development tool" -msgstr "" +msgstr "005 — Ferramenta de desenvolvimento do Yii" #. type: Plain text #: ../src/en/internals/005-development-tool.md msgid "For Yii3, the number of packages increased significantly to achieve more reusability and independent releases. To ease development of the framework itself, we've created a special tool available from [yiisoft/yii-dev-tool](https://github.com/yiisoft/yii-dev-tool)." -msgstr "" +msgstr "No Yii3, o número de pacotes aumentou bastante para permitir mais reuso e releases independentes. Para facilitar o desenvolvimento do próprio framework, criamos uma ferramenta especial, disponível em [yiisoft/yii-dev-tool](https://github.com/yiisoft/yii-dev-tool)." #. type: Fenced code block #: ../src/en/internals/005-development-tool.md @@ -56,28 +56,53 @@ msgid "" " status Show git status of packages\n" " update Update packages\n" msgstr "" +"$ ./yii-dev\n" +" _ _ _ _\n" +" | | | |(_)(_) Development Tool\n" +" | |_| || || |\n" +" \\__, ||_||_| for Yii 3.0\n" +" |___/\n" +"\n" +"This tool helps with setting up a development environment for Yii 3 packages.\n" +"\n" +"Usage:\n" +" command [options] [arguments]\n" +"\n" +"Options:\n" +" -h, --help Display this help message\n" +"\n" +"Available commands:\n" +" checkout-branch Creates, if not exists, and checkout a git branch\n" +" commit Add and commit changes into each package repository\n" +" install Install packages\n" +" lint Check packages according to PSR12 standard\n" +" pull Pull changes from package repositories\n" +" push Push changes into package repositories\n" +" replicate Copy files specified in replicate.php into each package\n" +" status Show git status of packages\n" +" update Update packages\n" #. type: Plain text #: ../src/en/internals/005-development-tool.md msgid "There are many commands available. The most important ones are `install` and `update`. What it does is:" -msgstr "" +msgstr "Há muitos comandos disponíveis. Os mais importantes são `install` e `update`. O que eles fazem:" #. type: Bullet: '1. ' #: ../src/en/internals/005-development-tool.md msgid "Install/update all packages listed in [`packages.php`](https://github.com/yiisoft/yii-dev-tool/blob/master/packages.php) or individual package from that list if specified." -msgstr "" +msgstr "Instalam/atualizam todos os pacotes listados em [`packages.php`](https://github.com/yiisoft/yii-dev-tool/blob/master/packages.php) ou um pacote específico dessa lista, se informado." #. type: Bullet: '2. ' #: ../src/en/internals/005-development-tool.md msgid "For every package installed check `vendor` directory for packages listed in `packages.php`. If there is any, replace the package directory with a symlink to another package source." -msgstr "" +msgstr "Para cada pacote instalado, verificam no diretório `vendor` se há pacotes listados em `packages.php`. Se houver, substituem o diretório do pacote por um symlink para o código-fonte do outro pacote." #. type: Plain text #: ../src/en/internals/005-development-tool.md msgid "As a result, you will have many packages using each other, so there is no need to `git push` and `composer install` / `composer update` during development." -msgstr "" +msgstr "Como resultado, você terá muitos pacotes usando uns aos outros, sem precisar de `git push` e `composer install` / `composer update` durante o desenvolvimento." #. type: Plain text #: ../src/en/internals/005-development-tool.md msgid "A [detailed example](https://github.com/yiisoft/yii-dev-tool#usage-example) of using the tool is available in its README." -msgstr "" +msgstr "Um [exemplo detalhado](https://github.com/yiisoft/yii-dev-tool#usage-example) de uso da ferramenta está disponível no README dela." diff --git a/_translations/po/pt-BR/internals_006-git-commit-messages.md.po b/_translations/po/pt-BR/internals_006-git-commit-messages.md.po index e003bf1e..ad343a12 100644 --- a/_translations/po/pt-BR/internals_006-git-commit-messages.md.po +++ b/_translations/po/pt-BR/internals_006-git-commit-messages.md.po @@ -8,16 +8,15 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2025-12-24 08:02+0000\n" "PO-Revision-Date: 2025-12-24 08:02+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/en/guide/runtime/request.md ../src/en/guide/runtime/response.md -#: ../src/en/internals/006-git-commit-messages.md +#: ../src/en/guide/runtime/request.md ../src/en/guide/runtime/response.md ../src/en/internals/006-git-commit-messages.md #, no-wrap msgid "Body" msgstr "Corpo" @@ -26,50 +25,50 @@ msgstr "Corpo" #: ../src/en/internals/006-git-commit-messages.md #, no-wrap msgid "006 — Git commit messages" -msgstr "" +msgstr "006 — Mensagens de commit do Git" #. type: Title ## #: ../src/en/internals/006-git-commit-messages.md #, no-wrap msgid "Subject line" -msgstr "" +msgstr "Linha de assunto" #. type: Bullet: '- ' #: ../src/en/internals/006-git-commit-messages.md msgid "Use `#123` to reference issue by number" -msgstr "" +msgstr "Use `#123` para referenciar uma issue pelo número" #. type: Bullet: '- ' #: ../src/en/internals/006-git-commit-messages.md msgid "Use imperative mood that's `Fix`, not `Fixed`" -msgstr "" +msgstr "Use o modo imperativo, ou seja, `Fix`, e não `Fixed`" #. type: Bullet: '- ' #: ../src/en/internals/006-git-commit-messages.md msgid "Don't add a period at the end" -msgstr "" +msgstr "Não coloque ponto final" #. type: Bullet: '- ' #: ../src/en/internals/006-git-commit-messages.md msgid "Use `[skip ci]` if there is no need to run unit tests" -msgstr "" +msgstr "Use `[skip ci]` se não houver necessidade de rodar os testes unitários" #. type: Bullet: '- ' #: ../src/en/internals/006-git-commit-messages.md msgid "Start with a capital letter" -msgstr "" +msgstr "Comece com letra maiúscula" #. type: Bullet: '- ' #: ../src/en/internals/006-git-commit-messages.md msgid "Limit to 50 characters" -msgstr "" +msgstr "Limite a 50 caracteres" #. type: Plain text #: ../src/en/internals/006-git-commit-messages.md msgid "Use the message body **if** you need an extra explanation. Explain why, not how." -msgstr "" +msgstr "Use o corpo da mensagem **se** precisar de uma explicação extra. Explique o porquê, não o como." #. type: Bullet: '- ' #: ../src/en/internals/006-git-commit-messages.md msgid "Limit line length to 72 characters" -msgstr "" +msgstr "Limite o tamanho das linhas a 72 caracteres" diff --git a/_translations/po/pt-BR/internals_007-exceptions.md.po b/_translations/po/pt-BR/internals_007-exceptions.md.po index 2fdf70c1..bcb25445 100644 --- a/_translations/po/pt-BR/internals_007-exceptions.md.po +++ b/_translations/po/pt-BR/internals_007-exceptions.md.po @@ -8,62 +8,56 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2025-12-24 08:02+0000\n" "PO-Revision-Date: 2025-12-24 08:02+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/en/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md -#: ../src/en/guide/concept/autoloading.md -#: ../src/en/guide/security/best-practices.md -#: ../src/en/guide/structure/domain.md -#: ../src/en/guide/tutorial/console-applications.md -#: ../src/en/internals/004-namespaces.md ../src/en/internals/007-exceptions.md -#: ../src/en/internals/008-interfaces.md +#: ../src/en/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md ../src/en/guide/concept/autoloading.md ../src/en/guide/security/best-practices.md ../src/en/guide/structure/domain.md ../src/en/guide/tutorial/console-applications.md ../src/en/internals/004-namespaces.md ../src/en/internals/007-exceptions.md ../src/en/internals/008-interfaces.md #, no-wrap msgid "References" -msgstr "" +msgstr "Referências" #. type: Title # #: ../src/en/internals/007-exceptions.md #, no-wrap msgid "007 — Exceptions" -msgstr "" +msgstr "007 — Exceções" #. type: Bullet: '- ' #: ../src/en/internals/007-exceptions.md msgid "Throw exceptions instead of returning an error code." -msgstr "" +msgstr "Lance exceções em vez de retornar um código de erro." #. type: Bullet: '- ' #: ../src/en/internals/007-exceptions.md msgid "Exception class name must be suffixed with `Exception`." -msgstr "" +msgstr "O nome da classe de exceção deve ter o sufixo `Exception`." #. type: Bullet: '- ' #: ../src/en/internals/007-exceptions.md msgid "Use grammatically correct error messages including ending punctuation, that's most exceptions must end with a period." -msgstr "" +msgstr "Use mensagens de erro gramaticalmente corretas, incluindo a pontuação final, ou seja, a maioria das exceções deve terminar com ponto." #. type: Bullet: '- ' #: ../src/en/internals/007-exceptions.md msgid "`\\InvalidArgumentException` must be used directly. There should be no exceptions inherited from it." -msgstr "" +msgstr "`\\InvalidArgumentException` deve ser usada diretamente. Não deve haver exceções herdadas dela." #. type: Bullet: '- ' #: ../src/en/internals/007-exceptions.md msgid "`\\InvalidArgumentException` must never be caught." -msgstr "" +msgstr "`\\InvalidArgumentException` nunca deve ser capturada." #. type: Bullet: '- ' #: ../src/en/internals/007-exceptions.md msgid "[International community discussion and poll](https://forum.yiiframework.com/t/naming-exceptions/126613/6)" -msgstr "" +msgstr "[Discussão e enquete na comunidade internacional](https://forum.yiiframework.com/t/naming-exceptions/126613/6)" #. type: Bullet: '- ' #: ../src/en/internals/007-exceptions.md msgid "[Russian community discussion and poll](https://yiiframework.ru/forum/viewtopic.php?f=39&t=51290)" -msgstr "" +msgstr "[Discussão e enquete na comunidade russa](https://yiiframework.ru/forum/viewtopic.php?f=39&t=51290)" diff --git a/_translations/po/pt-BR/internals_008-interfaces.md.po b/_translations/po/pt-BR/internals_008-interfaces.md.po index 57afaa12..5e5ec5c3 100644 --- a/_translations/po/pt-BR/internals_008-interfaces.md.po +++ b/_translations/po/pt-BR/internals_008-interfaces.md.po @@ -8,42 +8,36 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2025-12-24 08:02+0000\n" "PO-Revision-Date: 2025-12-24 08:02+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/en/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md -#: ../src/en/guide/concept/autoloading.md -#: ../src/en/guide/security/best-practices.md -#: ../src/en/guide/structure/domain.md -#: ../src/en/guide/tutorial/console-applications.md -#: ../src/en/internals/004-namespaces.md ../src/en/internals/007-exceptions.md -#: ../src/en/internals/008-interfaces.md +#: ../src/en/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md ../src/en/guide/concept/autoloading.md ../src/en/guide/security/best-practices.md ../src/en/guide/structure/domain.md ../src/en/guide/tutorial/console-applications.md ../src/en/internals/004-namespaces.md ../src/en/internals/007-exceptions.md ../src/en/internals/008-interfaces.md #, no-wrap msgid "References" -msgstr "" +msgstr "Referências" #. type: Title # #: ../src/en/internals/008-interfaces.md #, no-wrap msgid "008 — Interfaces" -msgstr "" +msgstr "008 — Interfaces" #. type: Bullet: '- ' #: ../src/en/internals/008-interfaces.md msgid "Interface name should be suffixed with `Interface`." -msgstr "" +msgstr "O nome da interface deve ter o sufixo `Interface`." #. type: Bullet: '- ' #: ../src/en/internals/008-interfaces.md msgid "[International community discussion and poll](https://forum.yiiframework.com/t/naming-interfaces/126612/5)" -msgstr "" +msgstr "[Discussão e enquete na comunidade internacional](https://forum.yiiframework.com/t/naming-interfaces/126612/5)" #. type: Bullet: '- ' #: ../src/en/internals/008-interfaces.md msgid "[Russian community discussion and poll](https://yiiframework.ru/forum/viewtopic.php?f=39&t=51289)" -msgstr "" +msgstr "[Discussão e enquete na comunidade russa](https://yiiframework.ru/forum/viewtopic.php?f=39&t=51289)" diff --git a/_translations/po/pt-BR/internals_009-design-decisions.md.po b/_translations/po/pt-BR/internals_009-design-decisions.md.po index 1e9b7fda..468d8dac 100644 --- a/_translations/po/pt-BR/internals_009-design-decisions.md.po +++ b/_translations/po/pt-BR/internals_009-design-decisions.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2025-12-24 08:02+0000\n" "PO-Revision-Date: 2025-12-24 08:02+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,177 +19,177 @@ msgstr "" #: ../src/en/internals/009-design-decisions.md #, no-wrap msgid "009 — Design Decisions" -msgstr "" +msgstr "009 — Decisões de design" #. type: Plain text #: ../src/en/internals/009-design-decisions.md msgid "In this document, we list important design decisions taken during Yii3 development." -msgstr "" +msgstr "Neste documento, listamos decisões de design importantes tomadas durante o desenvolvimento do Yii3." #. type: Title ## #: ../src/en/internals/009-design-decisions.md #, no-wrap msgid "Remove magic properties" -msgstr "" +msgstr "Remover propriedades mágicas" #. type: Plain text #: ../src/en/internals/009-design-decisions.md msgid "Magic properties in Yii 2 were an interesting idea that allowed a developer to start with public property and then seamlessly migrate to using getter/setter called via magic methods without changing the code." -msgstr "" +msgstr "As propriedades mágicas do Yii 2 eram uma ideia interessante: permitiam ao desenvolvedor começar com uma propriedade pública e depois migrar de forma transparente para getter/setter chamados via métodos mágicos, sem mudar o código." #. type: Plain text #: ../src/en/internals/009-design-decisions.md msgid "The main reason for removal in Yii 3 is that it resulted in using public properties everywhere, thus lack of encapsulation and code fragility." -msgstr "" +msgstr "O principal motivo da remoção no Yii 3 é que isso levava ao uso de propriedades públicas em todo lugar, resultando em falta de encapsulamento e código frágil." #. type: Title ## #: ../src/en/internals/009-design-decisions.md #, no-wrap msgid "Remove the service locator" -msgstr "" +msgstr "Remover o service locator" #. type: Plain text #: ../src/en/internals/009-design-decisions.md msgid "Service locator both Yii 1 and Yii 2 was convenient but was also abused a lot. Although a dependency injection container was available in Yii 2, service locator was generally preferred to cause both a dependency on the service locator itself, high coupling, hard to test code." -msgstr "" +msgstr "O service locator, tanto no Yii 1 quanto no Yii 2, era conveniente, mas também muito abusado. Embora o Yii 2 tivesse um container de injeção de dependência, o service locator costumava ser preferido, o que causava dependência do próprio service locator, alto acoplamento e código difícil de testar." #. type: Plain text #: ../src/en/internals/009-design-decisions.md msgid "Yii 3 relies on dependency injection only lowering coupling significantly and making code way more testable." -msgstr "" +msgstr "O Yii 3 usa apenas injeção de dependência, o que reduz bastante o acoplamento e torna o código muito mais testável." #. type: Title ## #: ../src/en/internals/009-design-decisions.md #, no-wrap msgid "Extract general packages" -msgstr "" +msgstr "Extrair pacotes de uso geral" #. type: Plain text #: ../src/en/internals/009-design-decisions.md msgid "Yii 1 and Yii 2 were fully closed communities. All the code we had wasn't useful outside Yii, and most of the \"external\" code wasn't useful in Yii without wrappers. It was noted many times by communities external to Yii that many parts of Yii are well-designed and unique, and they'd use these if these were available as standalone packages." -msgstr "" +msgstr "O Yii 1 e o Yii 2 eram comunidades totalmente fechadas. Todo o código que tínhamos não era útil fora do Yii, e a maior parte do código \"externo\" não era útil no Yii sem wrappers. Comunidades de fora do Yii comentaram muitas vezes que várias partes do Yii são bem projetadas e únicas, e que as usariam se estivessem disponíveis como pacotes independentes." #. type: Plain text #: ../src/en/internals/009-design-decisions.md msgid "As part of Yii 3 packages such as cache, RBAC, view, etc. were extracted into framework-independent packages. Benefits are:" -msgstr "" +msgstr "Como parte do Yii 3, pacotes como cache, RBAC, view etc. foram extraídos para pacotes independentes de framework. Os benefícios são:" #. type: Bullet: '- ' #: ../src/en/internals/009-design-decisions.md msgid "Increased usage and contribution" -msgstr "" +msgstr "Mais uso e mais contribuições" #. type: Bullet: '- ' #: ../src/en/internals/009-design-decisions.md msgid "Yii team could delegate maintenance" -msgstr "" +msgstr "O time do Yii pode delegar a manutenção" #. type: Bullet: '- ' #: ../src/en/internals/009-design-decisions.md msgid "Independent releases are possible" -msgstr "" +msgstr "Releases independentes passam a ser possíveis" #. type: Title ## #: ../src/en/internals/009-design-decisions.md #, no-wrap msgid "Adopt PSRs" -msgstr "" +msgstr "Adotar PSRs" #. type: Plain text #: ../src/en/internals/009-design-decisions.md msgid "The team adopted some PSRs in Yii 2, such as PSR-4 and PSR-2. Interfaces in general weren't, although Yii is part of PHP-FIG. Mainly because when Yii 2 was released, these were either in the making or not adopted enough." -msgstr "" +msgstr "O time adotou algumas PSRs no Yii 2, como a PSR-4 e a PSR-2. As interfaces, em geral, não foram adotadas, embora o Yii faça parte do PHP-FIG. Principalmente porque, quando o Yii 2 foi lançado, elas ainda estavam em elaboração ou não tinham adoção suficiente." #. type: Plain text #: ../src/en/internals/009-design-decisions.md msgid "Yii3 benefits from PSRs since there are nowadays many ready-to-use libraries that one can get via Composer: cache backends, middleware, loggers, DI containers, etc." -msgstr "" +msgstr "O Yii3 se beneficia das PSRs, já que hoje existem muitas bibliotecas prontas para uso que você instala via Composer: backends de cache, middlewares, loggers, containers de DI etc." #. type: Plain text #: ../src/en/internals/009-design-decisions.md msgid "By implementing PSRs in general packages, we allow these to be used in more projects, thus raising the contribution level." -msgstr "" +msgstr "Ao implementar PSRs nos pacotes de uso geral, permitimos que eles sejam usados em mais projetos, aumentando o nível de contribuição." #. type: Title ## #: ../src/en/internals/009-design-decisions.md #, no-wrap msgid "Improve DI container" -msgstr "" +msgstr "Melhorar o container de DI" #. type: Plain text #: ../src/en/internals/009-design-decisions.md msgid "The problem with the Yii 2 container was that it's tailored to be used with Yii 2 components. API isn't well-designed to be used with general PHP classes." -msgstr "" +msgstr "O problema do container do Yii 2 era que ele foi feito sob medida para os componentes do Yii 2. A API não foi bem projetada para uso com classes PHP em geral." #. type: Plain text #: ../src/en/internals/009-design-decisions.md msgid "In Yii3, we ensured that container can be used to conveniently configure any PHP class." -msgstr "" +msgstr "No Yii3, garantimos que o container possa ser usado para configurar qualquer classe PHP de forma conveniente." #. type: Plain text #: ../src/en/internals/009-design-decisions.md msgid "That should result in the absence of Yii-specific wrapper packages and more direct usages of Composer packages." -msgstr "" +msgstr "Isso deve resultar na ausência de pacotes wrapper específicos do Yii e em mais uso direto de pacotes do Composer." #. type: Title ## #: ../src/en/internals/009-design-decisions.md #, no-wrap msgid "Adopt strict types" -msgstr "" +msgstr "Adotar strict types" #. type: Plain text #: ../src/en/internals/009-design-decisions.md msgid "Strict types were introduced because:" -msgstr "" +msgstr "Os strict types foram introduzidos porque:" #. type: Bullet: '- ' #: ../src/en/internals/009-design-decisions.md msgid "PHP 7 is now mainstream" -msgstr "" +msgstr "O PHP 7 agora é o padrão do mercado" #. type: Bullet: '- ' #: ../src/en/internals/009-design-decisions.md msgid "While they solve no significant Yii 2 problems, they help to avoid many day-to-day development issues" -msgstr "" +msgstr "Embora não resolvam nenhum problema significativo do Yii 2, ajudam a evitar muitos problemas do dia a dia de desenvolvimento" #. type: Title ## #: ../src/en/internals/009-design-decisions.md #, no-wrap msgid "Adopt SemVer" -msgstr "" +msgstr "Adotar SemVer" #. type: Plain text #: ../src/en/internals/009-design-decisions.md msgid "Yii 2 has its own version policy. Problems:" -msgstr "" +msgstr "O Yii 2 tem sua própria política de versões. Problemas:" #. type: Bullet: '- ' #: ../src/en/internals/009-design-decisions.md msgid "It wasn't standard" -msgstr "" +msgstr "Não era um padrão" #. type: Bullet: '- ' #: ../src/en/internals/009-design-decisions.md msgid "Composer relies on SemVer" -msgstr "" +msgstr "O Composer se baseia em SemVer" #. type: Bullet: '- ' #: ../src/en/internals/009-design-decisions.md msgid "It's hard to support a framework built on top of packages if the versioning policy isn't strict" -msgstr "" +msgstr "É difícil manter um framework construído sobre pacotes se a política de versionamento não for rígida" #. type: Title ## #: ../src/en/internals/009-design-decisions.md #, no-wrap msgid "Prevent validators mutating data" -msgstr "" +msgstr "Impedir que validadores alterem dados" #. type: Plain text #: ../src/en/internals/009-design-decisions.md msgid "In Yii 1 and Yii 2, validators such as \"date\" were mutating data. It was confusing for a validation process not initially meant to mutate data it validates." -msgstr "" +msgstr "No Yii 1 e no Yii 2, validadores como \"date\" alteravam os dados. Era confuso que um processo de validação, que a princípio não deveria alterar os dados que valida, fizesse isso." #. type: Plain text #: ../src/en/internals/009-design-decisions.md msgid "[See related discussion](https://forum.yiiframework.com/t/saving-or-killing-non-validation-in-validators/126086)." -msgstr "" +msgstr "[Veja a discussão relacionada](https://forum.yiiframework.com/t/saving-or-killing-non-validation-in-validators/126086)." diff --git a/_translations/po/pt-BR/internals_010-code-style.md.po b/_translations/po/pt-BR/internals_010-code-style.md.po index e9421fe1..996d6064 100644 --- a/_translations/po/pt-BR/internals_010-code-style.md.po +++ b/_translations/po/pt-BR/internals_010-code-style.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-09-25 14:35+0000\n" "PO-Revision-Date: 2026-09-25 14:35+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,124 +19,123 @@ msgstr "" #: ../src/guide/databases/db-migrations.md ../src/internals/010-code-style.md #, no-wrap msgid "Strings" -msgstr "" +msgstr "Strings" #. type: Title # #: ../src/internals/010-code-style.md #, no-wrap msgid "010 — Code style" -msgstr "" +msgstr "010 — Estilo de código" #. type: Plain text #: ../src/internals/010-code-style.md msgid "Code formatting used in Yii 3 packages is based on [PER Coding Style 3.0](https://www.php-fig.org/per/coding-style/) with extra rules added on top of it." -msgstr "" +msgstr "A formatação de código usada nos pacotes do Yii 3 é baseada no [PER Coding Style 3.0](https://www.php-fig.org/per/coding-style/) com regras extras adicionadas por cima." #. type: Title ### -#: ../src/internals/010-code-style.md ../src/internals/017-tags.md -#: ../src/internals/018-widgets.md +#: ../src/internals/010-code-style.md ../src/internals/017-tags.md ../src/internals/018-widgets.md #, no-wrap msgid "Names" -msgstr "" +msgstr "Nomes" #. type: Bullet: '- ' #: ../src/internals/010-code-style.md msgid "Use English only." -msgstr "" +msgstr "Use apenas inglês." #. type: Bullet: '- ' #: ../src/internals/010-code-style.md msgid "Use camelCase notation, including abbreviations (e.g., `enableIdn`)." -msgstr "" +msgstr "Use a notação camelCase, inclusive em abreviações (por exemplo, `enableIdn`)." #. type: Bullet: '- ' #: ../src/internals/010-code-style.md msgid "Use the shortest possible, but an explanatory name." -msgstr "" +msgstr "Use o nome mais curto possível, mas que seja explicativo." #. type: Bullet: '- ' #: ../src/internals/010-code-style.md msgid "Never trim or abbreviate a name." -msgstr "" +msgstr "Nunca corte ou abrevie um nome." #. type: Bullet: '- ' #: ../src/internals/010-code-style.md msgid "Postfix classes, interfaces, traits and variables, which is a [collection](https://en.wikipedia.org/wiki/Collection_(abstract_data_type)), with `Collection`." -msgstr "" +msgstr "Adicione o sufixo `Collection` a classes, interfaces, traits e variáveis que sejam uma [coleção](https://en.wikipedia.org/wiki/Collection_(abstract_data_type))." #. type: Bullet: '- ' #: ../src/internals/010-code-style.md msgid "Postfix middleware classes with `Middleware`." -msgstr "" +msgstr "Adicione o sufixo `Middleware` às classes de middleware." #. type: Title ## #: ../src/internals/010-code-style.md #, no-wrap msgid "Types" -msgstr "" +msgstr "Tipos" #. type: Bullet: '- ' #: ../src/internals/010-code-style.md msgid "Declare [argument and return types](https://www.php.net/manual/en/migration70.new-features.php) where possible." -msgstr "" +msgstr "Declare [tipos de argumento e de retorno](https://www.php.net/manual/en/migration70.new-features.php) sempre que possível." #. type: Bullet: '- ' #: ../src/internals/010-code-style.md msgid "[Use types for properties](https://wiki.php.net/rfc/typed_properties_v2)." -msgstr "" +msgstr "[Use tipos nas propriedades](https://wiki.php.net/rfc/typed_properties_v2)." #. type: Bullet: '- ' #: ../src/internals/010-code-style.md msgid "Use strict typing. Avoid mixed and union types where possible except compatible types such as `string|Stringable`." -msgstr "" +msgstr "Use tipagem estrita. Evite tipos mixed e union sempre que possível, exceto tipos compatíveis como `string|Stringable`." #. type: Title ## #: ../src/internals/010-code-style.md #, no-wrap msgid "Comments" -msgstr "" +msgstr "Comentários" #. type: Plain text #: ../src/internals/010-code-style.md msgid "Inline comments are to be avoided unless code couldn't be understood without them. A good example is a workaround for a bug in a certain PHP version." -msgstr "" +msgstr "Evite comentários inline, a menos que o código não possa ser entendido sem eles. Um bom exemplo é um contorno para um bug em determinada versão do PHP." #. type: Plain text #: ../src/internals/010-code-style.md msgid "Method comment is necessary except it adds nothing to what method name and signature already has." -msgstr "" +msgstr "O comentário de método é necessário, exceto quando não acrescenta nada ao que o nome e a assinatura do método já dizem." #. type: Plain text #: ../src/internals/010-code-style.md msgid "Class comment should describe the purpose of the class." -msgstr "" +msgstr "O comentário de classe deve descrever o propósito da classe." #. type: Plain text #: ../src/internals/010-code-style.md msgid "See [PHPDoc](014-docs.md#phpdoc)." -msgstr "" +msgstr "Veja [PHPDoc](014-docs.md#phpdoc)." #. type: Title ## #: ../src/internals/010-code-style.md #, no-wrap msgid "Formatting" -msgstr "" +msgstr "Formatação" #. type: Title ### #: ../src/internals/010-code-style.md #, no-wrap msgid "Line length" -msgstr "" +msgstr "Tamanho da linha" #. type: Plain text #: ../src/internals/010-code-style.md msgid "The maximum line length is 120 characters." -msgstr "" +msgstr "O tamanho máximo da linha é de 120 caracteres." #. type: Plain text #: ../src/internals/010-code-style.md msgid "When a function or method call exceeds the limit, split arguments into separate lines:" -msgstr "" +msgstr "Quando uma chamada de função ou método excede o limite, separe os argumentos em linhas distintas:" #. type: Fenced code block (php) #: ../src/internals/010-code-style.md @@ -147,17 +146,21 @@ msgid "" " $result->getErrorMessagesIndexedByPath(),\n" ");\n" msgstr "" +"$this->assertSame(\n" +" ['' => ['Value must be no less than 5.']],\n" +" $result->getErrorMessagesIndexedByPath(),\n" +");\n" #. type: Title ### #: ../src/internals/010-code-style.md #, no-wrap msgid "No alignment" -msgstr "" +msgstr "Sem alinhamento" #. type: Plain text #: ../src/internals/010-code-style.md msgid "Property, variable and constant value assignments shouldn't be aligned. The same applies to phpdoc tags. The reason is that aligned statements often cause larger diff and even conflicts." -msgstr "" +msgstr "Atribuições de valores a propriedades, variáveis e constantes não devem ser alinhadas. O mesmo vale para as tags phpdoc. O motivo é que instruções alinhadas costumam gerar diffs maiores e até conflitos." #. type: Fenced code block (php) #: ../src/internals/010-code-style.md @@ -182,17 +185,35 @@ msgid "" " }\n" "}\n" msgstr "" +"final class X\n" +"{\n" +" const A = 'test';\n" +" const BBB = 'test';\n" +" \n" +" private int $property = 42;\n" +" private int $test = 123;\n" +" \n" +" /**\n" +" * @param int $number Just a number.\n" +" * @param array $options Well... options!\n" +" */\n" +" public function doIt(int $number, array $options): void\n" +" {\n" +" $test = 123;\n" +" $anotherTest = 123;\n" +" }\n" +"}\n" #. type: Title ### #: ../src/internals/010-code-style.md #, no-wrap msgid "Chain calls" -msgstr "" +msgstr "Chamadas encadeadas" #. type: Plain text #: ../src/internals/010-code-style.md msgid "Chained calls should be formatted for better readability. If it's a long chain that doesn't fit the line length of 120 characters, then each call should on a new line:" -msgstr "" +msgstr "Chamadas encadeadas devem ser formatadas para melhor legibilidade. Se for uma cadeia longa que não cabe no limite de 120 caracteres por linha, cada chamada deve ficar em uma nova linha:" #. type: Fenced code block (php) #: ../src/internals/010-code-style.md @@ -205,136 +226,141 @@ msgid "" " ->withAuthor($author)\n" " ->withDeadline($deadline);\n" msgstr "" +"$object\n" +" ->withName('test')\n" +" ->withValue(87)\n" +" ->withStatus(Status::NEW)\n" +" ->withAuthor($author)\n" +" ->withDeadline($deadline);\n" #. type: Plain text #: ../src/internals/010-code-style.md msgid "If it's a short chain, it's alright for it to be on a single line:" -msgstr "" +msgstr "Se for uma cadeia curta, não há problema em deixá-la em uma única linha:" #. type: Fenced code block (php) #: ../src/internals/010-code-style.md #, no-wrap msgid "$object = $object->withName('test');\n" -msgstr "" +msgstr "$object = $object->withName('test');\n" #. type: Bullet: '- ' #: ../src/internals/010-code-style.md msgid "When no variables involved, use `'Hello!'`" -msgstr "" +msgstr "Quando não houver variáveis envolvidas, use `'Hello!'`" #. type: Bullet: '- ' #: ../src/internals/010-code-style.md msgid "To get variables into string prefer `\"Hello, $username!\"`" -msgstr "" +msgstr "Para inserir variáveis na string, prefira `\"Hello, $username!\"`" #. type: Title ## #: ../src/internals/010-code-style.md #, no-wrap msgid "Classes and interfaces" -msgstr "" +msgstr "Classes e interfaces" #. type: Title ### #: ../src/internals/010-code-style.md #, no-wrap msgid "Final by default" -msgstr "" +msgstr "Final por padrão" #. type: Plain text #: ../src/internals/010-code-style.md msgid "Classes should be `final` by default." -msgstr "" +msgstr "As classes devem ser `final` por padrão." #. type: Title ### #: ../src/internals/010-code-style.md #, no-wrap msgid "Private by default" -msgstr "" +msgstr "Private por padrão" #. type: Plain text #: ../src/internals/010-code-style.md msgid "Constants, properties and methods should be private by default." -msgstr "" +msgstr "Constantes, propriedades e métodos devem ser private por padrão." #. type: Title ### #: ../src/internals/010-code-style.md #, no-wrap msgid "Composition over inheritance" -msgstr "" +msgstr "Composição em vez de herança" #. type: Plain text #: ../src/internals/010-code-style.md msgid "Prefer [composition to inheritance](../guide/concept/di-container.md)." -msgstr "" +msgstr "Prefira [composição a herança](../guide/concept/di-container.md)." #. type: Title ### #: ../src/internals/010-code-style.md #, no-wrap msgid "Property, constant and method order" -msgstr "" +msgstr "Ordem de propriedades, constantes e métodos" #. type: Plain text #: ../src/internals/010-code-style.md msgid "Order should be the following:" -msgstr "" +msgstr "A ordem deve ser a seguinte:" #. type: Bullet: '- ' #: ../src/internals/010-code-style.md msgid "Constants" -msgstr "" +msgstr "Constantes" #. type: Bullet: '- ' #: ../src/internals/010-code-style.md msgid "Properties" -msgstr "" +msgstr "Propriedades" #. type: Title ## -#: ../src/internals/010-code-style.md ../src/internals/017-tags.md -#: ../src/internals/018-widgets.md +#: ../src/internals/010-code-style.md ../src/internals/017-tags.md ../src/internals/018-widgets.md #, no-wrap msgid "Methods" -msgstr "" +msgstr "Métodos" #. type: Plain text #: ../src/internals/010-code-style.md msgid "Within each category, items should be sorted by visibility:" -msgstr "" +msgstr "Dentro de cada categoria, os itens devem ser ordenados por visibilidade:" #. type: Bullet: '- ' #: ../src/internals/010-code-style.md msgid "public" -msgstr "" +msgstr "public" #. type: Bullet: '- ' #: ../src/internals/010-code-style.md msgid "protected" -msgstr "" +msgstr "protected" #. type: Bullet: '- ' #: ../src/internals/010-code-style.md msgid "private" -msgstr "" +msgstr "private" #. type: Title ### #: ../src/internals/010-code-style.md #, no-wrap msgid "Abstract classes" -msgstr "" +msgstr "Classes abstratas" #. type: Plain text #: ../src/internals/010-code-style.md msgid "Abstract classes *shouldn't* be prefixed or postfixed with `Abstract`." -msgstr "" +msgstr "Classes abstratas *não devem* ter o prefixo ou sufixo `Abstract`." #. type: Title #### #: ../src/internals/010-code-style.md #, no-wrap msgid "Immutable methods" -msgstr "" +msgstr "Métodos imutáveis" #. type: Plain text #: ../src/internals/010-code-style.md msgid "Immutable method convention is the following:" -msgstr "" +msgstr "A convenção para métodos imutáveis é a seguinte:" #. type: Fenced code block (php) #: ../src/internals/010-code-style.md @@ -347,27 +373,33 @@ msgid "" " return $new; \n" "}\n" msgstr "" +"public function withName(string $name): self\n" +"{\n" +" $new = clone $this;\n" +" $new->name = $name;\n" +" return $new; \n" +"}\n" #. type: Bullet: '1. ' #: ../src/internals/010-code-style.md msgid "Cloned object name is `$new`." -msgstr "" +msgstr "O nome do objeto clonado é `$new`." #. type: Bullet: '2. ' #: ../src/internals/010-code-style.md msgid "Return type is `self`." -msgstr "" +msgstr "O tipo de retorno é `self`." #. type: Title #### #: ../src/internals/010-code-style.md #, no-wrap msgid "Boolean check methods" -msgstr "" +msgstr "Métodos de verificação booleana" #. type: Plain text #: ../src/internals/010-code-style.md msgid "Methods that are there to check if something is true should be named like the following:" -msgstr "" +msgstr "Métodos que servem para verificar se algo é verdadeiro devem ser nomeados assim:" #. type: Fenced code block (php) #: ../src/internals/010-code-style.md @@ -377,28 +409,31 @@ msgid "" "public function hasName(): bool;\n" "public function canDoIt(): bool;\n" msgstr "" +"public function isDeleted(): bool;\n" +"public function hasName(): bool;\n" +"public function canDoIt(): bool;\n" #. type: Title #### #: ../src/internals/010-code-style.md #, no-wrap msgid "Flags in methods " -msgstr "" +msgstr "Flags em métodos " #. type: Plain text #: ../src/internals/010-code-style.md msgid "Boolean flags in methods are better to be avoided. It's a sign the method may be doing too much, and there should be two methods instead of one." -msgstr "" +msgstr "É melhor evitar flags booleanas em métodos. Elas são um sinal de que o método pode estar fazendo coisas demais e de que deveria haver dois métodos em vez de um." #. type: Fenced code block (php) #: ../src/internals/010-code-style.md #, no-wrap msgid "public function login(bool $refreshPage = true): void;\n" -msgstr "" +msgstr "public function login(bool $refreshPage = true): void;\n" #. type: Plain text #: ../src/internals/010-code-style.md msgid "It is better to be two methods:" -msgstr "" +msgstr "É melhor que sejam dois métodos:" #. type: Fenced code block (php) #: ../src/internals/010-code-style.md @@ -407,17 +442,19 @@ msgid "" "public function login(): void;\n" "public function refreshPage(): void;\n" msgstr "" +"public function login(): void;\n" +"public function refreshPage(): void;\n" #. type: Title ## #: ../src/internals/010-code-style.md #, no-wrap msgid "Variables" -msgstr "" +msgstr "Variáveis" #. type: Plain text #: ../src/internals/010-code-style.md msgid "Add an underscore (`_`) prefix for unused variables. For example:" -msgstr "" +msgstr "Adicione o prefixo sublinhado (`_`) em variáveis não usadas. Por exemplo:" #. type: Fenced code block (php) #: ../src/internals/010-code-style.md @@ -427,17 +464,20 @@ msgid "" " echo $key;\n" "}\n" msgstr "" +"foreach ($items as $key => $_value) {\n" +" echo $key;\n" +"}\n" #. type: Title ## #: ../src/internals/010-code-style.md #, no-wrap msgid "Imports" -msgstr "" +msgstr "Imports" #. type: Plain text #: ../src/internals/010-code-style.md msgid "Prefer importing classes and functions to using fully qualified names:" -msgstr "" +msgstr "Prefira importar classes e funções a usar nomes totalmente qualificados:" #. type: Fenced code block (php) #: ../src/internals/010-code-style.md @@ -450,24 +490,30 @@ msgid "" "\n" "use function is_iterable;\n" msgstr "" +"use Yiisoft\\Arrays\\ArrayHelper;\n" +"use Yiisoft\\Validator\\DataSetInterface;\n" +"use Yiisoft\\Validator\\HasValidationErrorMessage;\n" +"use Yiisoft\\Validator\\Result;\n" +"\n" +"use function is_iterable;\n" #. type: Title ## #: ../src/internals/010-code-style.md #, no-wrap msgid "Additional conventions" -msgstr "" +msgstr "Convenções adicionais" #. type: Bullet: '- ' #: ../src/internals/010-code-style.md msgid "[Namespaces](004-namespaces.md)" -msgstr "" +msgstr "[Namespaces](004-namespaces.md)" #. type: Bullet: '- ' #: ../src/internals/010-code-style.md msgid "[Exceptions](007-exceptions.md)" -msgstr "" +msgstr "[Exceções](007-exceptions.md)" #. type: Bullet: '- ' #: ../src/internals/010-code-style.md msgid "[Interfaces](008-interfaces.md)" -msgstr "" +msgstr "[Interfaces](008-interfaces.md)" diff --git a/_translations/po/pt-BR/internals_011-error-correction.md.po b/_translations/po/pt-BR/internals_011-error-correction.md.po index a6e07f4c..a413d3c0 100644 --- a/_translations/po/pt-BR/internals_011-error-correction.md.po +++ b/_translations/po/pt-BR/internals_011-error-correction.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2025-12-24 08:02+0000\n" "PO-Revision-Date: 2025-12-24 08:02+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,9 +19,9 @@ msgstr "" #: ../src/en/internals/011-error-correction.md #, no-wrap msgid "011 — Error correction" -msgstr "" +msgstr "011 — Correção de erros" #. type: Plain text #: ../src/en/internals/011-error-correction.md msgid "If it's unambiguous within a class what the developer who incorrectly used the class meant, it's OK to correct the error. Otherwise, the error MUST NOT be corrected." -msgstr "" +msgstr "Se, dentro de uma classe, não houver ambiguidade sobre o que o desenvolvedor que usou a classe de forma incorreta quis dizer, não há problema em corrigir o erro. Caso contrário, o erro NÃO DEVE ser corrigido." diff --git a/_translations/po/pt-BR/internals_012-tests.md.po b/_translations/po/pt-BR/internals_012-tests.md.po index aa05b977..a14be574 100644 --- a/_translations/po/pt-BR/internals_012-tests.md.po +++ b/_translations/po/pt-BR/internals_012-tests.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2025-12-24 08:02+0000\n" "PO-Revision-Date: 2025-12-24 08:02+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,54 +19,54 @@ msgstr "" #: ../src/en/internals/012-tests.md #, no-wrap msgid "012 — Tests" -msgstr "" +msgstr "012 — Testes" #. type: Plain text #: ../src/en/internals/012-tests.md msgid "For each package, we're adding unit-tests that are run via [PHPUnit](https://phpunit.de/). When designing tests, the following guidelines should be taken into account." -msgstr "" +msgstr "Para cada pacote, adicionamos testes unitários executados com o [PHPUnit](https://phpunit.de/). Ao projetar os testes, leve em conta as diretrizes a seguir." #. type: Bullet: '- ' #: ../src/en/internals/012-tests.md msgid "Test class should be marked as `final` by default." -msgstr "" +msgstr "A classe de teste deve ser marcada como `final` por padrão." #. type: Bullet: '- ' #: ../src/en/internals/012-tests.md msgid "`@test` annotation must not be used, prefix methods with `test`." -msgstr "" +msgstr "A anotação `@test` não deve ser usada; use o prefixo `test` nos métodos." #. type: Bullet: '- ' #: ../src/en/internals/012-tests.md msgid "The test method name must reflect the purpose of the test." -msgstr "" +msgstr "O nome do método de teste deve refletir o propósito do teste." #. type: Bullet: '- ' #: ../src/en/internals/012-tests.md msgid "\"should\" must not be used in the test method name." -msgstr "" +msgstr "\"should\" não deve ser usado no nome do método de teste." #. type: Bullet: '- ' #: ../src/en/internals/012-tests.md msgid "If necessary, the test method phpdoc may describe the desired behavior." -msgstr "" +msgstr "Se necessário, o phpdoc do método de teste pode descrever o comportamento esperado." #. type: Bullet: '- ' #: ../src/en/internals/012-tests.md msgid "The test must follow AAA: first arrange the necessary preconditions, then act, then assert expected results." -msgstr "" +msgstr "O teste deve seguir o AAA: primeiro prepare (arrange) as pré-condições necessárias, depois aja (act) e, por fim, verifique (assert) os resultados esperados." #. type: Bullet: '- ' #: ../src/en/internals/012-tests.md msgid "There must be one test case per test method that's a single AAA." -msgstr "" +msgstr "Deve haver um caso de teste por método de teste, ou seja, um único AAA." #. type: Bullet: '- ' #: ../src/en/internals/012-tests.md msgid "Test must use public API. Private properties or methods shouldn't be accessed, assumptions on internals of the class tested shouldn't be made." -msgstr "" +msgstr "O teste deve usar a API pública. Não se deve acessar propriedades ou métodos privados, nem fazer suposições sobre os detalhes internos da classe testada." #. type: Bullet: '- ' #: ../src/en/internals/012-tests.md msgid "Tests shouldn't rely on composer-config-plugin and DI container unless necessary." -msgstr "" +msgstr "Os testes não devem depender do composer-config-plugin nem do container de DI, a menos que seja necessário." diff --git a/_translations/po/pt-BR/internals_013-code-review.md.po b/_translations/po/pt-BR/internals_013-code-review.md.po index 933ec618..60c30b75 100644 --- a/_translations/po/pt-BR/internals_013-code-review.md.po +++ b/_translations/po/pt-BR/internals_013-code-review.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2025-12-24 08:02+0000\n" "PO-Revision-Date: 2025-12-24 08:02+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,101 +19,101 @@ msgstr "" #: ../src/en/internals/013-code-review.md #, no-wrap msgid "013 — Code review" -msgstr "" +msgstr "013 — Code review" #. type: Plain text #: ../src/en/internals/013-code-review.md msgid "Code reviews are essential for the success of the project and are as important as contributing code." -msgstr "" +msgstr "Code reviews são essenciais para o sucesso do projeto e tão importantes quanto contribuir com código." #. type: Plain text #: ../src/en/internals/013-code-review.md msgid "Reviews are handled via GitHub pull requests. When the request is ready for review, the \"status: code review\" label is added to it." -msgstr "" +msgstr "As revisões são feitas por meio de pull requests no GitHub. Quando o pull request está pronto para revisão, recebe o label \"status: code review\"." #. type: Plain text #: ../src/en/internals/013-code-review.md msgid "[A full list of pull requests that need review](https://github.com/search?q=org%3Ayiisoft+label%3A\"status%3Acode+review\"&state=open&type=Issues) is available at GitHub." -msgstr "" +msgstr "[A lista completa de pull requests que precisam de revisão](https://github.com/search?q=org%3Ayiisoft+label%3A\"status%3Acode+review\"&state=open&type=Issues) está disponível no GitHub." #. type: Title ## #: ../src/en/internals/013-code-review.md #, no-wrap msgid "Guidelines" -msgstr "" +msgstr "Diretrizes" #. type: Bullet: '- ' #: ../src/en/internals/013-code-review.md msgid "Check out the pull request branch, open the project in the IDE, get a big picture." -msgstr "" +msgstr "Faça checkout do branch do pull request, abra o projeto na IDE e tenha uma visão geral." #. type: Bullet: '- ' #: ../src/en/internals/013-code-review.md msgid "Does the pull request make sense overall?" -msgstr "" +msgstr "O pull request faz sentido como um todo?" #. type: Bullet: '- ' #: ../src/en/internals/013-code-review.md msgid "Run tests and/or application using code from the pull request. Are these OK?" -msgstr "" +msgstr "Rode os testes e/ou a aplicação usando o código do pull request. Está tudo certo?" #. type: Bullet: '- ' #: ../src/en/internals/013-code-review.md msgid "Read all lines of code in the pull request." -msgstr "" +msgstr "Leia todas as linhas de código do pull request." #. type: Bullet: '- ' #: ../src/en/internals/013-code-review.md msgid "Could it be done simpler?" -msgstr "" +msgstr "Daria para fazer de forma mais simples?" #. type: Bullet: '- ' #: ../src/en/internals/013-code-review.md msgid "Are there security issues?" -msgstr "" +msgstr "Há problemas de segurança?" #. type: Bullet: '- ' #: ../src/en/internals/013-code-review.md msgid "Are there performance issues?" -msgstr "" +msgstr "Há problemas de desempenho?" #. type: Bullet: '- ' #: ../src/en/internals/013-code-review.md msgid "When leaving comments, be polite." -msgstr "" +msgstr "Ao deixar comentários, seja educado." #. type: Bullet: '- ' #: ../src/en/internals/013-code-review.md msgid "Avoid code-formatting comments." -msgstr "" +msgstr "Evite comentários sobre formatação de código." #. type: Title ## #: ../src/en/internals/013-code-review.md #, no-wrap msgid "Mandatory parts" -msgstr "" +msgstr "Itens obrigatórios" #. type: Bullet: '- ' #: ../src/en/internals/013-code-review.md msgid "[ ] Tests that fail without code and pass with code." -msgstr "" +msgstr "[ ] Testes que falham sem o código e passam com ele." #. type: Bullet: '- ' #: ../src/en/internals/013-code-review.md msgid "[ ] Type hints." -msgstr "" +msgstr "[ ] Type hints." #. type: Bullet: '- ' #: ../src/en/internals/013-code-review.md msgid "[ ] `declare(strict_types=1)`." -msgstr "" +msgstr "[ ] `declare(strict_types=1)`." #. type: Bullet: '- ' #: ../src/en/internals/013-code-review.md msgid "[ ] Documentation: phpdoc, yiisoft/docs." -msgstr "" +msgstr "[ ] Documentação: phpdoc, yiisoft/docs." #. type: Bullet: '- ' #: ../src/en/internals/013-code-review.md msgid "[ ] Changelog entry (if package is stable)." -msgstr "" +msgstr "[ ] Entrada no changelog (se o pacote for estável)." diff --git a/_translations/po/pt-BR/internals_014-docs.md.po b/_translations/po/pt-BR/internals_014-docs.md.po index 06ad4e97..76ecd467 100644 --- a/_translations/po/pt-BR/internals_014-docs.md.po +++ b/_translations/po/pt-BR/internals_014-docs.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-05-05 22:22+0000\n" "PO-Revision-Date: 2026-05-05 22:22+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,101 +19,101 @@ msgstr "" #: ../src/internals/014-docs.md #, no-wrap msgid "014 — Documentation" -msgstr "" +msgstr "014 — Documentação" #. type: Plain text #: ../src/internals/014-docs.md msgid "Documentation is one of the most important parts of Yii." -msgstr "" +msgstr "A documentação é uma das partes mais importantes do Yii." #. type: Title ## #: ../src/internals/014-docs.md #, no-wrap msgid "Package documentation" -msgstr "" +msgstr "Documentação de pacotes" #. type: Plain text #: ../src/internals/014-docs.md msgid "Documentation for a package could either be in `README.md` or `docs/{language}/{type}` where `{language}` is a language code and `{type}` could be \"guide,\" \"cookbook\" or something else. Usually `docs` is there if the package usage or configuration isn't trivial or there's a need for translation." -msgstr "" +msgstr "A documentação de um pacote pode ficar no `README.md` ou em `docs/{language}/{type}`, onde `{language}` é um código de idioma e `{type}` pode ser \"guide\", \"cookbook\" ou outra coisa. Normalmente, `docs` existe quando o uso ou a configuração do pacote não é trivial ou quando há necessidade de tradução." #. type: Plain text #: ../src/internals/014-docs.md msgid "Some indicators that it's time to create `docs`:" -msgstr "" +msgstr "Alguns indícios de que é hora de criar `docs`:" #. type: Bullet: '1. ' #: ../src/internals/014-docs.md msgid "There is a need for translation." -msgstr "" +msgstr "Há necessidade de tradução." #. type: Bullet: '2. ' #: ../src/internals/014-docs.md msgid "Many topics exist. Each of these is big by itself." -msgstr "" +msgstr "Existem muitos tópicos, e cada um deles é grande por si só." #. type: Plain text #: ../src/internals/014-docs.md msgid "If the total length of readme is less than about 200 lines, it's fine to keep documentation in the readme." -msgstr "" +msgstr "Se o tamanho total do readme for menor que cerca de 200 linhas, não há problema em manter a documentação no readme." #. type: Title ## #: ../src/internals/014-docs.md #, no-wrap msgid "Definitive guide" -msgstr "" +msgstr "Guia definitivo" #. type: Plain text #: ../src/internals/014-docs.md msgid "The definitive guide, [yiisoft/docs/guide](https://github.com/yiisoft/docs/tree/master/guide/en) aims at covering usage of packages as a whole framework. Unlike package documentation, it isn't focused on a single package but is covering certain use-cases." -msgstr "" +msgstr "O guia definitivo, [yiisoft/docs/guide](https://github.com/yiisoft/docs/tree/master/guide/en) tem como objetivo cobrir o uso dos pacotes como um framework completo. Diferente da documentação dos pacotes, ele não se concentra em um único pacote, e sim em determinados casos de uso." #. type: Plain text #: ../src/internals/014-docs.md msgid "The guide should follow [Microsoft style guide](https://learn.microsoft.com/en-us/style-guide/welcome/)." -msgstr "" +msgstr "O guia deve seguir o [guia de estilo da Microsoft](https://learn.microsoft.com/en-us/style-guide/welcome/)." #. type: Title ### #: ../src/internals/014-docs.md #, no-wrap msgid "Translation" -msgstr "" +msgstr "Tradução" #. type: Plain text #: ../src/internals/014-docs.md #, no-wrap msgid "The definitive guide uses [po4a](https://github.com/mquinson/po4a) in GitHub Action for translations. \n" -msgstr "" +msgstr "O guia definitivo usa o [po4a](https://github.com/mquinson/po4a) em uma GitHub Action para as traduções. \n" #. type: Plain text #: ../src/internals/014-docs.md msgid "Translation algorithm:" -msgstr "" +msgstr "Algoritmo de tradução:" #. type: Bullet: '- ' #: ../src/internals/014-docs.md msgid "Install an application for working with `.po` translation files. For example, [Poedit](https://poedit.net/), [Lokalize](https://apps.kde.org/ru/lokalize/), [Gtranslator](https://wiki.gnome.org/Apps/Gtranslator) or another." -msgstr "" +msgstr "Instale uma aplicação para trabalhar com arquivos de tradução `.po`. Por exemplo, [Poedit](https://poedit.net/), [Lokalize](https://apps.kde.org/ru/lokalize/), [Gtranslator](https://wiki.gnome.org/Apps/Gtranslator) ou outra." #. type: Bullet: '- ' #: ../src/internals/014-docs.md msgid "Find file what you want to translate in `_translations/guide/{lang}`. Note that if the source file is in a subfolder, the subfolder name is appended to the file name and separated by an underscore, for example, for translating `guide/en/concept/aliases.md` file find `_translations/guide/{lang}/concept_aliases.md.po` file." -msgstr "" +msgstr "Encontre o arquivo que você quer traduzir em `_translations/guide/{lang}`. Observe que, se o arquivo original estiver em uma subpasta, o nome da subpasta é adicionado ao nome do arquivo, separado por um sublinhado. Por exemplo, para traduzir o arquivo `guide/en/concept/aliases.md`, procure o arquivo `_translations/guide/{lang}/concept_aliases.md.po`." #. type: Bullet: '- ' #: ../src/internals/014-docs.md msgid "Open the file with the `.po` extension in `Poedit` from the folder with the desired localization, for example `_translations/guide/ru/intro_what-is-yii.md.po`. If there is no localization yet, create an issue." -msgstr "" +msgstr "Abra o arquivo com extensão `.po` no `Poedit` a partir da pasta com a localização desejada, por exemplo `_translations/guide/ru/intro_what-is-yii.md.po`. Se ainda não existir a localização, crie uma issue." #. type: Bullet: '- ' #: ../src/internals/014-docs.md msgid "Translate necessary strings and push the changes" -msgstr "" +msgstr "Traduza as strings necessárias e faça push das alterações" #. type: Bullet: '- ' #: ../src/internals/014-docs.md msgid "Open a pull request to the main repository" -msgstr "" +msgstr "Abra um pull request para o repositório principal" #. type: Plain text #: ../src/internals/014-docs.md @@ -122,37 +122,39 @@ msgid "" "> [!CAUTION]\n" "> Do not change the translation in files in `/guide/{lang}` manually.\n" msgstr "" +"> [!CAUTION]\n" +"> Não altere manualmente a tradução nos arquivos em `/guide/{lang}`.\n" #. type: Plain text #: ../src/internals/014-docs.md msgid "If you have changed English and want to update translations:" -msgstr "" +msgstr "Se você alterou o texto em inglês e quer atualizar as traduções:" #. type: Bullet: '- ' #: ../src/internals/014-docs.md msgid "Pull updated branch after successful completion of workflow `Update docs translation` in GitHub Action" -msgstr "" +msgstr "Faça pull do branch atualizado depois que o workflow `Update docs translation` da GitHub Action terminar com sucesso" #. type: Bullet: '- ' #: ../src/internals/014-docs.md msgid "Update translation in `.po` files by `Poedit`" -msgstr "" +msgstr "Atualize a tradução nos arquivos `.po` com o `Poedit`" #. type: Bullet: '- ' #: ../src/internals/014-docs.md msgid "Push changes" -msgstr "" +msgstr "Faça push das alterações" #. type: Title ## #: ../src/internals/014-docs.md #, no-wrap msgid "Blocks" -msgstr "" +msgstr "Blocos" #. type: Plain text #: ../src/internals/014-docs.md msgid "Blocks are in the [GitHub Alerts format](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts):" -msgstr "" +msgstr "Os blocos usam o [formato GitHub Alerts](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts):" #. type: Fenced code block #: ../src/internals/014-docs.md @@ -173,11 +175,25 @@ msgid "" "> [!CAUTION]\n" "> Advises about risks or negative outcomes of certain actions.\n" msgstr "" +"> [!NOTE]\n" +"> Informação útil que os usuários devem saber, mesmo lendo o conteúdo por alto.\n" +"\n" +"> [!TIP]\n" +"> Conselho útil para fazer as coisas melhor ou com mais facilidade.\n" +"\n" +"> [!IMPORTANT]\n" +"> Informação essencial que os usuários precisam saber para alcançar o objetivo.\n" +"\n" +"> [!WARNING]\n" +"> Informação urgente que exige atenção imediata do usuário para evitar problemas.\n" +"\n" +"> [!CAUTION]\n" +"> Alerta sobre riscos ou consequências negativas de certas ações.\n" #. type: Plain text #: ../src/internals/014-docs.md msgid "When translating documentation, these Block indicators should not be translated. Keeps them intact as they are and only translate the block content. For translating the label for the block, each guide translation should have a `blocktypes.json` file containing the translations. The following shows an example for German:" -msgstr "" +msgstr "Ao traduzir a documentação, esses indicadores de bloco não devem ser traduzidos. Mantenha-os intactos e traduza apenas o conteúdo do bloco. Para traduzir o rótulo do bloco, cada tradução do guia deve ter um arquivo `blocktypes.json` com as traduções. Veja a seguir um exemplo para o alemão:" #. type: Fenced code block (json) #: ../src/internals/014-docs.md @@ -191,17 +207,24 @@ msgid "" " \"Caution\": \"Vorsicht\"\n" "}\n" msgstr "" +"{\n" +" \"Note\": \"Hinweis\",\n" +" \"Tip\": \"Tipp\",\n" +" \"Important\": \"Wichtig\",\n" +" \"Warning\": \"Achtung\",\n" +" \"Caution\": \"Vorsicht\"\n" +"}\n" #. type: Title ## #: ../src/internals/014-docs.md #, no-wrap msgid "PHPDoc" -msgstr "" +msgstr "PHPDoc" #. type: Plain text #: ../src/internals/014-docs.md msgid "PHPDoc mustn't be added if it doesn't add anything to what it describes. The following is a bad example:" -msgstr "" +msgstr "Não se deve adicionar PHPDoc se ele não acrescentar nada ao que descreve. Este é um mau exemplo:" #. type: Fenced code block (php) #: ../src/internals/014-docs.md @@ -237,21 +260,50 @@ msgid "" " }\n" "}\n" msgstr "" +"use Psr\\Log\\LoggerInterface;\n" +"\n" +"/**\n" +" * MyService class\n" +" */\n" +"final class MyService extends MyServiceBase\n" +"{\n" +" /**\n" +" * @var LoggerInterface logger \n" +" */\n" +" private LoggerInterface $logger;\n" +"\n" +" /**\n" +" * MyService constructor.\n" +" * @param LoggerInterface $logger\n" +" */\n" +" public function __construct(LoggerInterface $logger)\n" +" {\n" +" $this->logger = $logger;\n" +" }\n" +"\n" +" /**\n" +" * @inheritDoc\n" +" */\n" +" public function doit(): bool\n" +" {\n" +" return parent::doit(); \n" +" }\n" +"}\n" #. type: Plain text #: ../src/internals/014-docs.md msgid "PHPDoc, if present, should describe the purpose of the element it's added for." -msgstr "" +msgstr "O PHPDoc, quando presente, deve descrever o propósito do elemento ao qual foi adicionado." #. type: Plain text #: ../src/internals/014-docs.md msgid "Skip default values in PHPDoc when PHP already shows them in a parameter default, promoted property default, or property initializer. The declaration is the source of truth, and repeating the value in text can become outdated after code changes." -msgstr "" +msgstr "Omita valores padrão no PHPDoc quando o PHP já os mostra no valor padrão de um parâmetro, no valor padrão de uma propriedade promovida ou no inicializador de uma propriedade. A declaração é a fonte da verdade, e repetir o valor no texto pode ficar desatualizado após mudanças no código." #. type: Plain text #: ../src/internals/014-docs.md msgid "Example of incorrect code:" -msgstr "" +msgstr "Exemplo de código incorreto:" #. type: Fenced code block (php) #: ../src/internals/014-docs.md @@ -265,11 +317,18 @@ msgid "" ") {\n" "}\n" msgstr "" +"/**\n" +" * @param bool $skipOnEmpty Whether to skip validation when the value is empty. Defaults to true.\n" +" */\n" +"public function __construct(\n" +" private bool $skipOnEmpty = true,\n" +") {\n" +"}\n" #. type: Plain text #: ../src/internals/014-docs.md msgid "Example of a valid code:" -msgstr "" +msgstr "Exemplo de código válido:" #. type: Fenced code block (php) #: ../src/internals/014-docs.md @@ -283,11 +342,18 @@ msgid "" ") {\n" "}\n" msgstr "" +"/**\n" +" * @param bool $skipOnEmpty Whether to skip validation when the value is empty.\n" +" */\n" +"public function __construct(\n" +" private bool $skipOnEmpty = true,\n" +") {\n" +"}\n" #. type: Plain text #: ../src/internals/014-docs.md msgid "The `@see` tags must explicitly refer to class methods, properties, and constants. This is necessary for the correct display of links in IDEs, as well as for the correct display of links in API documentation." -msgstr "" +msgstr "As tags `@see` devem referenciar explicitamente métodos, propriedades e constantes da classe. Isso é necessário para que os links sejam exibidos corretamente nas IDEs e na documentação da API." #. type: Fenced code block (php) #: ../src/internals/014-docs.md @@ -305,6 +371,17 @@ msgid "" " public function doSomething(): void {}\n" "}\n" msgstr "" +"/**\n" +" * @see SOME_CONST\n" +" * @see $prop\n" +" * @see doSomething()\n" +" */\n" +"final class Example\n" +"{\n" +" public const SOME_CONST = '';\n" +" public int $prop;\n" +" public function doSomething(): void {}\n" +"}\n" #. type: Fenced code block (php) #: ../src/internals/014-docs.md @@ -322,69 +399,80 @@ msgid "" " public function doSomething(): void {}\n" "}\n" msgstr "" +"/**\n" +" * @see Example::SOME_CONST\n" +" * @see Example::$prop\n" +" * @see Example::doSomething()\n" +" */\n" +"final class Example\n" +"{\n" +" public const SOME_CONST = '';\n" +" public int $prop;\n" +" public function doSomething(): void {}\n" +"}\n" #. type: Title ## #: ../src/internals/014-docs.md #, no-wrap msgid "Readme checklist" -msgstr "" +msgstr "Checklist do readme" #. type: Plain text #: ../src/internals/014-docs.md msgid "Each package readme should be placed into `README.md` and contain the following:" -msgstr "" +msgstr "O readme de cada pacote deve ficar em `README.md` e conter o seguinte:" #. type: Bullet: '- ' #: ../src/internals/014-docs.md msgid "[ ] Logo." -msgstr "" +msgstr "[ ] Logo." #. type: Bullet: '- ' #: ../src/internals/014-docs.md msgid "[ ] Short description of the package. What does it do?" -msgstr "" +msgstr "[ ] Descrição curta do pacote. O que ele faz?" #. type: Bullet: '- ' #: ../src/internals/014-docs.md msgid "[ ] Quality badges (build, code coverage)." -msgstr "" +msgstr "[ ] Badges de qualidade (build, cobertura de código)." #. type: Bullet: '- ' #: ../src/internals/014-docs.md msgid "[ ] Screenshot (if applicable)." -msgstr "" +msgstr "[ ] Captura de tela (se aplicável)." #. type: Bullet: '- ' #: ../src/internals/014-docs.md msgid "[ ] Requirements." -msgstr "" +msgstr "[ ] Requisitos." #. type: Bullet: '- ' #: ../src/internals/014-docs.md msgid "[ ] Installation. Usually `composer require`." -msgstr "" +msgstr "[ ] Instalação. Normalmente `composer require`." #. type: Bullet: '- ' #: ../src/internals/014-docs.md msgid "[ ] Getting started. One or two common usage examples are demonstrated." -msgstr "" +msgstr "[ ] Primeiros passos. Um ou dois exemplos de uso comuns." #. type: Bullet: '- ' #: ../src/internals/014-docs.md msgid "[ ] Configuration." -msgstr "" +msgstr "[ ] Configuração." #. type: Bullet: '- ' #: ../src/internals/014-docs.md msgid "[ ] Contributing. It should contain a link to guidelines." -msgstr "" +msgstr "[ ] Contribuindo. Deve conter um link para as diretrizes." #. type: Bullet: '- ' #: ../src/internals/014-docs.md msgid "[ ] Running tests." -msgstr "" +msgstr "[ ] Executando os testes." #. type: Bullet: '- ' #: ../src/internals/014-docs.md msgid "[ ] License." -msgstr "" +msgstr "[ ] Licença." diff --git a/_translations/po/pt-BR/internals_015-phpstorm.md.po b/_translations/po/pt-BR/internals_015-phpstorm.md.po index 0f78a531..49aa1618 100644 --- a/_translations/po/pt-BR/internals_015-phpstorm.md.po +++ b/_translations/po/pt-BR/internals_015-phpstorm.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2025-12-24 08:02+0000\n" "PO-Revision-Date: 2025-12-24 08:02+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,39 +19,39 @@ msgstr "" #: ../src/en/internals/015-phpstorm.md #, no-wrap msgid "015 — PhpStorm metadata and attributes" -msgstr "" +msgstr "015 — Metadados e atributos do PhpStorm" #. type: Title ## #: ../src/en/internals/015-phpstorm.md #, no-wrap msgid "PhpStorm metadata" -msgstr "" +msgstr "Metadados do PhpStorm" #. type: Plain text #: ../src/en/internals/015-phpstorm.md msgid "[PhpStorm metadata](https://www.jetbrains.com/help/phpstorm/ide-advanced-metadata.html) helps the IDE to understand code better in cases when regular types and PHPDoc tags don't help." -msgstr "" +msgstr "Os [metadados do PhpStorm](https://www.jetbrains.com/help/phpstorm/ide-advanced-metadata.html) ajudam a IDE a entender melhor o código nos casos em que os tipos comuns e as tags PHPDoc não ajudam." #. type: Plain text #: ../src/en/internals/015-phpstorm.md msgid "We use the following set of coding styles for metadata." -msgstr "" +msgstr "Usamos o seguinte conjunto de convenções de estilo para os metadados." #. type: Title ### #: ../src/en/internals/015-phpstorm.md #, no-wrap msgid "Metadata location" -msgstr "" +msgstr "Localização dos metadados" #. type: Bullet: '- ' #: ../src/en/internals/015-phpstorm.md msgid "Metadata should be placed in `/.phpstorm.meta.php` directory." -msgstr "" +msgstr "Os metadados devem ficar no diretório `/.phpstorm.meta.php`." #. type: Bullet: '- ' #: ../src/en/internals/015-phpstorm.md msgid "Configuration should be split into files. Each file should be named after a class it configures." -msgstr "" +msgstr "A configuração deve ser dividida em arquivos. Cada arquivo deve ter o nome da classe que configura." #. type: Plain text #: ../src/en/internals/015-phpstorm.md @@ -60,17 +60,19 @@ msgid "" "> [!NOTE]\n" "> There is no support for subdirectories in PhpStorm yet.\n" msgstr "" +"> [!NOTE]\n" +"> O PhpStorm ainda não suporta subdiretórios.\n" #. type: Title ### #: ../src/en/internals/015-phpstorm.md #, no-wrap msgid "Constants " -msgstr "" +msgstr "Constantes " #. type: Plain text #: ../src/en/internals/015-phpstorm.md msgid "All constant dictionaries should be named as `{Class FQN}::{Group name}`. Group name should be short and written in capital letters. Use underscore as a word separator that's `\\Yiisoft\\Http\\Status::STATUSES`. For example:" -msgstr "" +msgstr "Todos os dicionários de constantes devem ser nomeados como `{Class FQN}::{Group name}`. O nome do grupo deve ser curto e escrito em letras maiúsculas. Use sublinhado como separador de palavras, por exemplo `\\Yiisoft\\Http\\Status::STATUSES`. Por exemplo:" #. type: Fenced code block (php) #: ../src/en/internals/015-phpstorm.md @@ -92,34 +94,49 @@ msgid "" " \\Yiisoft\\Http\\Method::OPTIONS,\n" ");\n" msgstr "" +"expectedReturnValues(\n" +" \\Psr\\Http\\Message\\RequestInterface::getMethod(),\n" +" argumentsSet('\\Yiisoft\\Http\\Method::METHODS'),\n" +");\n" +"\n" +"registerArgumentsSet(\n" +" '\\Yiisoft\\Http\\Method::METHODS',\n" +" \\Yiisoft\\Http\\Method::GET,\n" +" \\Yiisoft\\Http\\Method::POST,\n" +" \\Yiisoft\\Http\\Method::PUT,\n" +" \\Yiisoft\\Http\\Method::DELETE,\n" +" \\Yiisoft\\Http\\Method::PATCH,\n" +" \\Yiisoft\\Http\\Method::HEAD,\n" +" \\Yiisoft\\Http\\Method::OPTIONS,\n" +");\n" #. type: Title ## #: ../src/en/internals/015-phpstorm.md #, no-wrap msgid "PhpStorm attributes" -msgstr "" +msgstr "Atributos do PhpStorm" #. type: Plain text #: ../src/en/internals/015-phpstorm.md msgid "[PhpStorm attributes](https://github.com/JetBrains/phpstorm-attributes) CAN be used in code, but package `jetbrains/phpstorm-attributes` MUST be added as a dev dependency:" -msgstr "" +msgstr "Os [atributos do PhpStorm](https://github.com/JetBrains/phpstorm-attributes) PODEM ser usados no código, mas o pacote `jetbrains/phpstorm-attributes` DEVE ser adicionado como dependência de desenvolvimento:" #. type: Fenced code block (shell) #: ../src/en/internals/015-phpstorm.md #, no-wrap msgid "composer require --dev jetbrains/phpstorm-attributes\n" -msgstr "" +msgstr "composer require --dev jetbrains/phpstorm-attributes\n" #. type: Title ### #: ../src/en/internals/015-phpstorm.md #, no-wrap msgid "Using with ComposerRequireChecker" -msgstr "" +msgstr "Usando com o ComposerRequireChecker" #. type: Plain text #: ../src/en/internals/015-phpstorm.md msgid "When [ComposerRequireChecker](https://github.com/maglnet/ComposerRequireChecker) is also used within the same package, add involved attributes' class names to whitelist in config. For example:" -msgstr "" +msgstr "Quando o [ComposerRequireChecker](https://github.com/maglnet/ComposerRequireChecker) também é usado no mesmo pacote, adicione os nomes das classes dos atributos envolvidos à whitelist na configuração. Por exemplo:" #. type: Fenced code block (json) #: ../src/en/internals/015-phpstorm.md @@ -132,3 +149,9 @@ msgid "" " ]\n" "}\n" msgstr "" +"{\n" +" \"symbol-whitelist\": [\n" +" \"JetBrains\\\\PhpStorm\\\\ExpectedValues\",\n" +" \"JetBrains\\\\PhpStorm\\\\Pure\"\n" +" ]\n" +"}\n" diff --git a/_translations/po/pt-BR/internals_016-security-workflow.md.po b/_translations/po/pt-BR/internals_016-security-workflow.md.po index d4e222b2..0f5ae7c4 100644 --- a/_translations/po/pt-BR/internals_016-security-workflow.md.po +++ b/_translations/po/pt-BR/internals_016-security-workflow.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-05-09 18:47+0000\n" "PO-Revision-Date: 2026-05-09 18:47+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,12 +19,12 @@ msgstr "" #: ../src/internals/016-security-workflow.md #, no-wrap msgid "016 — Security workflow" -msgstr "" +msgstr "016 — Fluxo de segurança" #. type: Plain text #: ../src/internals/016-security-workflow.md msgid "Security issues are typically sent via [a security form](https://www.yiiframework.com/security)." -msgstr "" +msgstr "Problemas de segurança normalmente são enviados pelo [formulário de segurança](https://www.yiiframework.com/security)." #. type: Plain text #: ../src/internals/016-security-workflow.md @@ -33,6 +33,8 @@ msgid "" "If an issue is reported directly to a public page such as a repository issue or a forum topic, get the message\n" "and delete the issue. Say thanks to the reporter and point to the security form for next time. \n" msgstr "" +"Se um problema for relatado diretamente em uma página pública, como uma issue do repositório ou um tópico do fórum, copie a mensagem\n" +"e apague a issue. Agradeça a quem relatou e indique o formulário de segurança para a próxima vez. \n" #. type: Fenced code block (mermaid) #: ../src/internals/016-security-workflow.md @@ -54,106 +56,121 @@ msgid "" " wait --> release[Release]\n" " release --> publish[Publish advisory and submit FriendsOfPHP entry]\n" msgstr "" +"flowchart TD\n" +" form[Relato pelo formulário de segurança] --> verify[Verificar o problema]\n" +" public[Relato público] --> remove[Salvar os detalhes e apagar a issue pública]\n" +" remove --> redirect[Indicar o formulário de segurança a quem relatou]\n" +" redirect --> verify\n" +" verify -->|precisa de detalhes| requestInfo[Pedir mais informações]\n" +" requestInfo --> verify\n" +" verify -->|válido| advisory[Criar rascunho de security advisory]\n" +" advisory --> severity[Definir a severidade CVSS]\n" +" severity --> credit[Perguntar sobre o crédito a quem relatou]\n" +" credit --> cve[Solicitar número CVE]\n" +" cve --> patch[Preparar pull request com o patch]\n" +" patch --> wait[Aguardar a atribuição do CVE]\n" +" wait --> release[Release]\n" +" release --> publish[Publicar o advisory e enviar entrada ao FriendsOfPHP]\n" #. type: Title ## #: ../src/internals/016-security-workflow.md #, no-wrap msgid "Verify" -msgstr "" +msgstr "Verificar" #. type: Plain text #: ../src/internals/016-security-workflow.md msgid "Verify that the issue is valid. Request more information if needed." -msgstr "" +msgstr "Verifique se o problema é válido. Peça mais informações, se necessário." #. type: Title ## #: ../src/internals/016-security-workflow.md #, no-wrap msgid "Add security advisory" -msgstr "" +msgstr "Adicionar security advisory" #. type: Plain text #: ../src/internals/016-security-workflow.md msgid "Create a draft GitHub security advisory." -msgstr "" +msgstr "Crie um rascunho de security advisory no GitHub." #. type: Title ### #: ../src/internals/016-security-workflow.md #, no-wrap msgid "Find out severity" -msgstr "" +msgstr "Descobrir a severidade" #. type: Bullet: '1. ' #: ../src/internals/016-security-workflow.md msgid "Get CVSS score using [NVD calculator](https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator)." -msgstr "" +msgstr "Obtenha a pontuação CVSS usando a [calculadora do NVD](https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator)." #. type: Bullet: '2. ' #: ../src/internals/016-security-workflow.md msgid "Choose severity based on the [rating scale](https://www.first.org/cvss/specification-document#Qualitative-Severity-Rating-Scale)." -msgstr "" +msgstr "Escolha a severidade com base na [escala de classificação](https://www.first.org/cvss/specification-document#Qualitative-Severity-Rating-Scale)." #. type: Title ### #: ../src/internals/016-security-workflow.md #, no-wrap msgid "Give credit to the reporter" -msgstr "" +msgstr "Dar crédito a quem relatou" #. type: Plain text #: ../src/internals/016-security-workflow.md msgid "Ask the reporter if he wants a credit for finding the issue. If so, point to his GitHub account." -msgstr "" +msgstr "Pergunte a quem relatou se deseja receber crédito por ter encontrado o problema. Se sim, indique a conta dessa pessoa no GitHub." #. type: Title ## #: ../src/internals/016-security-workflow.md #, no-wrap msgid "Request a CVE number" -msgstr "" +msgstr "Solicitar um número CVE" #. type: Plain text #: ../src/internals/016-security-workflow.md msgid "When you're ready, request a CVE." -msgstr "" +msgstr "Quando estiver pronto, solicite um CVE." #. type: Title ## #: ../src/internals/016-security-workflow.md #, no-wrap msgid "Prepare a patch" -msgstr "" +msgstr "Preparar um patch" #. type: Plain text #: ../src/internals/016-security-workflow.md msgid "Prepare a pull request fixing the issue. GitHub allows doing it in a private fork." -msgstr "" +msgstr "Prepare um pull request que corrija o problema. O GitHub permite fazer isso em um fork privado." #. type: Title ## #: ../src/internals/016-security-workflow.md #, no-wrap msgid "Wait till the CVE number is allocated " -msgstr "" +msgstr "Aguardar a atribuição do número CVE " #. type: Plain text #: ../src/internals/016-security-workflow.md msgid "It usually takes several days." -msgstr "" +msgstr "Normalmente leva alguns dias." #. type: Title ## #: ../src/internals/016-security-workflow.md #, no-wrap msgid "Release" -msgstr "" +msgstr "Release" #. type: Bullet: '- ' #: ../src/internals/016-security-workflow.md msgid "Merge the patch pull request right before tagging the next package release." -msgstr "" +msgstr "Faça o merge do pull request com o patch logo antes de criar a tag do próximo release do pacote." #. type: Bullet: '- ' #: ../src/internals/016-security-workflow.md msgid "Publish security advisory." -msgstr "" +msgstr "Publique o security advisory." #. type: Bullet: '- ' #: ../src/internals/016-security-workflow.md msgid "Add CVE to [FriendsOfPHP/security-advisories](https://github.com/FriendsOfPHP/security-advisories). See [#488](https://github.com/FriendsOfPHP/security-advisories/pull/488) as an example." -msgstr "" +msgstr "Adicione o CVE em [FriendsOfPHP/security-advisories](https://github.com/FriendsOfPHP/security-advisories). Veja [#488](https://github.com/FriendsOfPHP/security-advisories/pull/488) como exemplo." diff --git a/_translations/po/pt-BR/internals_017-tags.md.po b/_translations/po/pt-BR/internals_017-tags.md.po index 1077f68b..d0c5b186 100644 --- a/_translations/po/pt-BR/internals_017-tags.md.po +++ b/_translations/po/pt-BR/internals_017-tags.md.po @@ -8,119 +8,116 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2025-12-24 08:02+0000\n" "PO-Revision-Date: 2025-12-24 08:02+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/en/guide/concept/immutability.md ../src/en/internals/017-tags.md -#: ../src/en/internals/018-widgets.md +#: ../src/en/guide/concept/immutability.md ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md #, no-wrap msgid "Immutability" -msgstr "" +msgstr "Imutabilidade" #. type: Title ### -#: ../src/en/internals/010-code-style.md ../src/en/internals/017-tags.md -#: ../src/en/internals/018-widgets.md +#: ../src/en/internals/010-code-style.md ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md #, no-wrap msgid "Names" -msgstr "" +msgstr "Nomes" #. type: Title ## -#: ../src/en/internals/010-code-style.md ../src/en/internals/017-tags.md -#: ../src/en/internals/018-widgets.md +#: ../src/en/internals/010-code-style.md ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md #, no-wrap msgid "Methods" -msgstr "" +msgstr "Métodos" #. type: Title # #: ../src/en/internals/017-tags.md #, no-wrap msgid "017 - Tags" -msgstr "" +msgstr "017 - Tags" #. type: Plain text #: ../src/en/internals/017-tags.md msgid "Unlike regular classes, tags are used in view templates, so syntax is important. It should be both easy to write, easy to read and not too verbose because similar constructs are meant to be used over and over again." -msgstr "" +msgstr "Diferente das classes comuns, as tags são usadas em templates de view, então a sintaxe é importante. Ela deve ser fácil de escrever, fácil de ler e não muito verbosa, porque construções parecidas são usadas repetidas vezes." #. type: Title ## #: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md #, no-wrap msgid "Class names" -msgstr "" +msgstr "Nomes de classes" #. type: Bullet: '- ' #: ../src/en/internals/017-tags.md msgid "Tags aren't postfixed or prefixed unless it's an abstract base class." -msgstr "" +msgstr "As tags não têm prefixo nem sufixo, a menos que sejam uma classe base abstrata." #. type: Bullet: '- ' #: ../src/en/internals/017-tags.md msgid "If the tag represents a specification, use a name used in the specification." -msgstr "" +msgstr "Se a tag representa uma especificação, use o nome usado na especificação." #. type: Title ## #: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md #, no-wrap msgid "Inheritance" -msgstr "" +msgstr "Herança" #. type: Plain text #: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md msgid "Inheritance is allowed with some restrictions:" -msgstr "" +msgstr "A herança é permitida com algumas restrições:" #. type: Bullet: '- ' #: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md msgid "If a class isn't abstract, it should be final." -msgstr "" +msgstr "Se uma classe não é abstrata, ela deve ser final." #. type: Bullet: '- ' #: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md msgid "Hierarchy should be kept as linear as possible." -msgstr "" +msgstr "A hierarquia deve ser mantida o mais linear possível." #. type: Plain text #: ../src/en/internals/017-tags.md msgid "Tags should:" -msgstr "" +msgstr "As tags devem:" #. type: Bullet: '- ' #: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md msgid "Have no state." -msgstr "" +msgstr "Não ter estado." #. type: Bullet: '- ' #: ../src/en/internals/017-tags.md msgid "Be immutable. Every method that modifies a setting returns a clone with the setting changed." -msgstr "" +msgstr "Ser imutáveis. Todo método que modifica uma configuração retorna um clone com a configuração alterada." #. type: Bullet: '- ' #: ../src/en/internals/017-tags.md msgid "Be free of side effects. Many calls of the same method with the same argument should give the same result." -msgstr "" +msgstr "Não ter efeitos colaterais. Várias chamadas do mesmo método com o mesmo argumento devem dar o mesmo resultado." #. type: Bullet: '- ' #: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md msgid "Unlike other classes, methods that return a clone of the object with some properties modified aren't prefixed." -msgstr "" +msgstr "Diferente de outras classes, os métodos que retornam um clone do objeto com algumas propriedades modificadas não têm prefixo." #. type: Bullet: '- ' #: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md msgid "Keep method names as short as possible but don't hurt readability." -msgstr "" +msgstr "Mantenha os nomes dos métodos o mais curtos possível, sem prejudicar a legibilidade." #. type: Title ### #: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md #, no-wrap msgid "Boolean flags" -msgstr "" +msgstr "Flags booleanas" #. type: Plain text #: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md msgid "The method that corresponds to the boolean attribute should be named after the attribute and accept a boolean flag argument." -msgstr "" +msgstr "O método que corresponde a um atributo booleano deve ter o nome do atributo e aceitar um argumento booleano como flag." diff --git a/_translations/po/pt-BR/internals_018-widgets.md.po b/_translations/po/pt-BR/internals_018-widgets.md.po index 0c4b6f84..a7c1ab59 100644 --- a/_translations/po/pt-BR/internals_018-widgets.md.po +++ b/_translations/po/pt-BR/internals_018-widgets.md.po @@ -8,109 +8,106 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2025-12-24 08:02+0000\n" "PO-Revision-Date: 2025-12-24 08:02+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/en/guide/concept/immutability.md ../src/en/internals/017-tags.md -#: ../src/en/internals/018-widgets.md +#: ../src/en/guide/concept/immutability.md ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md #, no-wrap msgid "Immutability" -msgstr "" +msgstr "Imutabilidade" #. type: Title ### -#: ../src/en/internals/010-code-style.md ../src/en/internals/017-tags.md -#: ../src/en/internals/018-widgets.md +#: ../src/en/internals/010-code-style.md ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md #, no-wrap msgid "Names" -msgstr "" +msgstr "Nomes" #. type: Title ## -#: ../src/en/internals/010-code-style.md ../src/en/internals/017-tags.md -#: ../src/en/internals/018-widgets.md +#: ../src/en/internals/010-code-style.md ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md #, no-wrap msgid "Methods" -msgstr "" +msgstr "Métodos" #. type: Title ## #: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md #, no-wrap msgid "Class names" -msgstr "" +msgstr "Nomes de classes" #. type: Title ## #: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md #, no-wrap msgid "Inheritance" -msgstr "" +msgstr "Herança" #. type: Plain text #: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md msgid "Inheritance is allowed with some restrictions:" -msgstr "" +msgstr "A herança é permitida com algumas restrições:" #. type: Bullet: '- ' #: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md msgid "If a class isn't abstract, it should be final." -msgstr "" +msgstr "Se uma classe não é abstrata, ela deve ser final." #. type: Bullet: '- ' #: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md msgid "Hierarchy should be kept as linear as possible." -msgstr "" +msgstr "A hierarquia deve ser mantida o mais linear possível." #. type: Bullet: '- ' #: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md msgid "Have no state." -msgstr "" +msgstr "Não ter estado." #. type: Bullet: '- ' #: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md msgid "Unlike other classes, methods that return a clone of the object with some properties modified aren't prefixed." -msgstr "" +msgstr "Diferente de outras classes, os métodos que retornam um clone do objeto com algumas propriedades modificadas não têm prefixo." #. type: Bullet: '- ' #: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md msgid "Keep method names as short as possible but don't hurt readability." -msgstr "" +msgstr "Mantenha os nomes dos métodos o mais curtos possível, sem prejudicar a legibilidade." #. type: Title ### #: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md #, no-wrap msgid "Boolean flags" -msgstr "" +msgstr "Flags booleanas" #. type: Plain text #: ../src/en/internals/017-tags.md ../src/en/internals/018-widgets.md msgid "The method that corresponds to the boolean attribute should be named after the attribute and accept a boolean flag argument." -msgstr "" +msgstr "O método que corresponde a um atributo booleano deve ter o nome do atributo e aceitar um argumento booleano como flag." #. type: Title # #: ../src/en/internals/018-widgets.md #, no-wrap msgid "018 - Widgets" -msgstr "" +msgstr "018 - Widgets" #. type: Plain text #: ../src/en/internals/018-widgets.md msgid "Unlike regular classes, widgets are used in view templates, so syntax is important. It should be both easy to write, easy to read and not too verbose because similar constructs are meant to be used over and over again." -msgstr "" +msgstr "Diferente das classes comuns, os widgets são usados em templates de view, então a sintaxe é importante. Ela deve ser fácil de escrever, fácil de ler e não muito verbosa, porque construções parecidas são usadas repetidas vezes." #. type: Plain text #: ../src/en/internals/018-widgets.md msgid "Widgets aren't postfixed or prefixed." -msgstr "" +msgstr "Os widgets não têm prefixo nem sufixo." #. type: Plain text #: ../src/en/internals/018-widgets.md msgid "Widgets should:" -msgstr "" +msgstr "Os widgets devem:" #. type: Bullet: '- ' #: ../src/en/internals/018-widgets.md msgid "Be immutable." -msgstr "" +msgstr "Ser imutáveis." diff --git a/_translations/po/pt-BR/internals_019-view-code-style.md.po b/_translations/po/pt-BR/internals_019-view-code-style.md.po index 445c60d6..5ff805f2 100644 --- a/_translations/po/pt-BR/internals_019-view-code-style.md.po +++ b/_translations/po/pt-BR/internals_019-view-code-style.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2025-12-24 08:02+0000\n" "PO-Revision-Date: 2025-12-24 08:02+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,23 +19,23 @@ msgstr "" #: ../src/en/internals/019-view-code-style.md #, no-wrap msgid "019 — View code style" -msgstr "" +msgstr "019 — Estilo de código das views" #. type: Plain text #: ../src/en/internals/019-view-code-style.md msgid "The PHP code in the view files shouldn't be complicated. The code must contain the logic responsible for formatting the data, but not the logic for requesting this data." -msgstr "" +msgstr "O código PHP nos arquivos de view não deve ser complicado. O código deve conter a lógica responsável por formatar os dados, mas não a lógica para buscar esses dados." #. type: Title ## #: ../src/en/internals/019-view-code-style.md #, no-wrap msgid "Heading" -msgstr "" +msgstr "Cabeçalho" #. type: Plain text #: ../src/en/internals/019-view-code-style.md msgid "View file heading is used to place phpdoc describing variables available and to import classes:" -msgstr "" +msgstr "O cabeçalho do arquivo de view é usado para colocar o phpdoc que descreve as variáveis disponíveis e para importar classes:" #. type: Fenced code block (php) #: ../src/en/internals/019-view-code-style.md @@ -50,17 +50,25 @@ msgid "" "\n" "use Yiisoft\\Html\\Html;\n" msgstr "" +"getDescription()) ?>

\n" "\n" msgstr "" +" \n" +"

getTitle()) ?>

\n" +"

getDescription()) ?>

\n" +"\n" #. type: Title ## #: ../src/en/internals/019-view-code-style.md #, no-wrap msgid "Short echo" -msgstr "" +msgstr "Short echo" #. type: Plain text #: ../src/en/internals/019-view-code-style.md msgid "Short echo is preferred:" -msgstr "" +msgstr "Prefira o short echo:" #. type: Fenced code block (php) #: ../src/en/internals/019-view-code-style.md #, no-wrap msgid "\n" -msgstr "" +msgstr "\n" #. type: Title ## #: ../src/en/internals/019-view-code-style.md #, no-wrap msgid "Class methods" -msgstr "" +msgstr "Métodos de classe" #. type: Plain text #: ../src/en/internals/019-view-code-style.md msgid "All class methods used in view files must be public regardless if the view is rendered by the class itself." -msgstr "" +msgstr "Todos os métodos de classe usados em arquivos de view devem ser públicos, mesmo que a view seja renderizada pela própria classe." diff --git a/_translations/po/pt-BR/internals_020-package-release.md.po b/_translations/po/pt-BR/internals_020-package-release.md.po index 074224d6..07c8cb51 100644 --- a/_translations/po/pt-BR/internals_020-package-release.md.po +++ b/_translations/po/pt-BR/internals_020-package-release.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-05-29 09:48+0000\n" "PO-Revision-Date: 2026-05-29 09:48+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,85 +19,85 @@ msgstr "" #: ../src/internals/020-package-release.md #, no-wrap msgid "020 — Package release" -msgstr "" +msgstr "020 — Release de pacotes" #. type: Title ## #: ../src/internals/020-package-release.md #, no-wrap msgid "Criteria" -msgstr "" +msgstr "Critérios" #. type: Bullet: '- ' #: ../src/internals/020-package-release.md msgid "No critical issues." -msgstr "" +msgstr "Nenhuma issue crítica." #. type: Bullet: '- ' #: ../src/internals/020-package-release.md msgid "Public API changes aren't likely. Some time passed w/o issues reported that may require API changes." -msgstr "" +msgstr "Mudanças na API pública são improváveis. Já passou algum tempo sem issues relatadas que possam exigir mudanças na API." #. type: Bullet: '- ' #: ../src/internals/020-package-release.md msgid "All dependencies are stable." -msgstr "" +msgstr "Todas as dependências são estáveis." #. type: Bullet: '- ' #: ../src/internals/020-package-release.md msgid "Close to 100% test coverage with, ideally, a 100% MSI score." -msgstr "" +msgstr "Cobertura de testes próxima de 100% e, idealmente, score MSI de 100%." #. type: Bullet: '- ' #: ../src/internals/020-package-release.md msgid "README is alright." -msgstr "" +msgstr "O README está em ordem." #. type: Bullet: '- ' #: ../src/internals/020-package-release.md msgid "Everything is type-hinted unless special cases." -msgstr "" +msgstr "Tudo tem type hints, exceto em casos especiais." #. type: Bullet: '- ' #: ../src/internals/020-package-release.md msgid "Psalm analysis passes on at least level 2." -msgstr "" +msgstr "A análise do Psalm passa pelo menos no nível 2." #. type: Bullet: '- ' #: ../src/internals/020-package-release.md msgid "phpdoc is alright." -msgstr "" +msgstr "O phpdoc está em ordem." #. type: Bullet: '- ' #: ../src/internals/020-package-release.md msgid "Public API is alright." -msgstr "" +msgstr "A API pública está em ordem." #. type: Title ## #: ../src/internals/020-package-release.md #, no-wrap msgid "Release branch policy" -msgstr "" +msgstr "Política de branches de release" #. type: Plain text #: ../src/internals/020-package-release.md msgid "Use `master` for all regular releases." -msgstr "" +msgstr "Use `master` para todos os releases regulares." #. type: Plain text #: ../src/internals/020-package-release.md msgid "Create a separate branch only when releasing a new version for a previous major version. In this case, create the branch from the latest tag in that previous major version line and apply only the changes needed for the release." -msgstr "" +msgstr "Crie um branch separado apenas ao lançar uma nova versão de uma versão major anterior. Nesse caso, crie o branch a partir da tag mais recente dessa linha de versão major anterior e aplique apenas as mudanças necessárias para o release." #. type: Title ## #: ../src/internals/020-package-release.md #, no-wrap msgid "Release instruction" -msgstr "" +msgstr "Instruções de release" #. type: Plain text #: ../src/internals/020-package-release.md msgid "Release a package via [Yii Development Tool](005-development-tool.md)." -msgstr "" +msgstr "Faça o release de um pacote com a [Ferramenta de desenvolvimento do Yii](005-development-tool.md)." #. type: Plain text #: ../src/internals/020-package-release.md @@ -106,11 +106,13 @@ msgid "" "1. Check that you can sign commits locally (see \n" "[Signing commits](https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits)).\n" msgstr "" +"1. Verifique se você consegue assinar commits localmente (veja \n" +"[Assinando commits](https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits)).\n" #. type: Bullet: '2. ' #: ../src/internals/020-package-release.md msgid "For regular releases, pull last changes from the `master` branch:" -msgstr "" +msgstr "Para releases regulares, faça pull das últimas mudanças do branch `master`:" #. type: Fenced code block (shell) #: ../src/internals/020-package-release.md @@ -119,39 +121,41 @@ msgid "" "./yii-dev git/checkout master package-name\n" "./yii-dev git/pull package-name\n" msgstr "" +"./yii-dev git/checkout master package-name\n" +"./yii-dev git/pull package-name\n" #. type: Plain text #: ../src/internals/020-package-release.md msgid "For previous major version releases, use the branch created according to the release branch policy instead of `master`." -msgstr "" +msgstr "Para releases de versões major anteriores, use o branch criado de acordo com a política de branches de release, em vez de `master`." #. type: Bullet: '3. ' #: ../src/internals/020-package-release.md msgid "Check the package for compliance with the criteria above." -msgstr "" +msgstr "Verifique se o pacote atende aos critérios acima." #. type: Bullet: '4. ' #: ../src/internals/020-package-release.md msgid "Run `release/make` command:" -msgstr "" +msgstr "Execute o comando `release/make`:" #. type: Fenced code block (shell) #: ../src/internals/020-package-release.md #, no-wrap msgid "./yii-dev release/make package-name\n" -msgstr "" +msgstr "./yii-dev release/make package-name\n" #. type: Bullet: '5. ' #: ../src/internals/020-package-release.md msgid "Select the version type (major, minor or patch)." -msgstr "" +msgstr "Selecione o tipo de versão (major, minor ou patch)." #. type: Bullet: '6. ' #: ../src/internals/020-package-release.md msgid "On the question \"Push commits and tags, and release on GitHub?\" check a diff. If the diff is alright, answer \"yes.\"" -msgstr "" +msgstr "Na pergunta \"Push commits and tags, and release on GitHub?\", confira o diff. Se o diff estiver correto, responda \"yes\"." #. type: Bullet: '7. ' #: ../src/internals/020-package-release.md msgid "For major and minor releases, add a record with release notes on [Yii Framework News](https://www.yiiframework.com/news)." -msgstr "" +msgstr "Para releases major e minor, adicione um registro com as notas de release em [Yii Framework News](https://www.yiiframework.com/news)." diff --git a/_translations/po/pt-BR/internals_021-changelog-upgrade.md.po b/_translations/po/pt-BR/internals_021-changelog-upgrade.md.po index 76446e13..bf33f29e 100644 --- a/_translations/po/pt-BR/internals_021-changelog-upgrade.md.po +++ b/_translations/po/pt-BR/internals_021-changelog-upgrade.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-01-08 08:54+0000\n" "PO-Revision-Date: 2026-01-08 08:54+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,23 +19,23 @@ msgstr "" #: ../src/internals/021-changelog-upgrade.md #, no-wrap msgid "021 — Changelog and upgrade" -msgstr "" +msgstr "021 — Changelog e upgrade" #. type: Plain text #: ../src/internals/021-changelog-upgrade.md msgid "For all released packages, we've a detailed changelog and upgrade guide." -msgstr "" +msgstr "Para todos os pacotes lançados, mantemos um changelog detalhado e um guia de upgrade." #. type: Title ## #: ../src/internals/021-changelog-upgrade.md #, no-wrap msgid "Changelog" -msgstr "" +msgstr "Changelog" #. type: Plain text #: ../src/internals/021-changelog-upgrade.md msgid "Changelog is written for each version released. The file name is `CHANGELOG.md`. The format is the following:" -msgstr "" +msgstr "O changelog é escrito para cada versão lançada. O nome do arquivo é `CHANGELOG.md`. O formato é o seguinte:" #. type: Fenced code block (markdown) #: ../src/internals/021-changelog-upgrade.md @@ -55,57 +55,70 @@ msgid "" "\n" "- Initial release.\n" msgstr "" +"# My package Change Log\n" +"\n" +"## 1.0.2 under development\n" +"\n" +"- no changes in this release.\n" +"\n" +"## 1.0.1 March 23, 2021\n" +"\n" +"- Bug #42: Short description of the change (@author1, @author2)\n" +"\n" +"## 1.0.0 February 02, 2021\n" +"\n" +"- Initial release.\n" #. type: Plain text #: ../src/internals/021-changelog-upgrade.md msgid "There \"My package\" is the name of the package, `1.0.1` is the version released followed by release date. For each version, there are a number of lines listing the changes. \"Bug\" refers to a change type. The following types are used:" -msgstr "" +msgstr "Ali, \"My package\" é o nome do pacote, `1.0.1` é a versão lançada, seguida da data de release. Para cada versão, há algumas linhas listando as mudanças. \"Bug\" indica o tipo da mudança. São usados os seguintes tipos:" #. type: Bullet: '- ' #: ../src/internals/021-changelog-upgrade.md msgid "New — New features." -msgstr "" +msgstr "New — Novas funcionalidades." #. type: Bullet: '- ' #: ../src/internals/021-changelog-upgrade.md msgid "Chg — General changes." -msgstr "" +msgstr "Chg — Mudanças gerais." #. type: Bullet: '- ' #: ../src/internals/021-changelog-upgrade.md msgid "Enh — Existing feature enhancements." -msgstr "" +msgstr "Enh — Melhorias em funcionalidades existentes." #. type: Bullet: '- ' #: ../src/internals/021-changelog-upgrade.md msgid "Bug — Bug fixes." -msgstr "" +msgstr "Bug — Correções de bugs." #. type: Plain text #: ../src/internals/021-changelog-upgrade.md msgid "In the changelog file lines should be ordered as New, Chg, Enh, Bug." -msgstr "" +msgstr "No arquivo de changelog, as linhas devem ser ordenadas como New, Chg, Enh, Bug." #. type: Plain text #: ../src/internals/021-changelog-upgrade.md msgid "\"#42\" above is the number of issue or pull requests corresponding to the change. \"author1\" is the GitHub nickname of the code author. \"author2\" is an additional author. An author's nickname MUST be prefixed with `@`." -msgstr "" +msgstr "\"#42\" acima é o número da issue ou do pull request correspondente à mudança. \"author1\" é o nickname no GitHub do autor do código. \"author2\" é um autor adicional. O nickname de um autor DEVE ter o prefixo `@`." #. type: Title ## #: ../src/internals/021-changelog-upgrade.md #, no-wrap msgid "Upgrade" -msgstr "" +msgstr "Upgrade" #. type: Plain text #: ../src/internals/021-changelog-upgrade.md msgid "Upgrade guide is created when there is a new major version that isn't compatible with the previous one. It describes steps necessary to upgrade application code." -msgstr "" +msgstr "O guia de upgrade é criado quando há uma nova versão major que não é compatível com a anterior. Ele descreve os passos necessários para fazer o upgrade do código da aplicação." #. type: Plain text #: ../src/internals/021-changelog-upgrade.md msgid "The file name is `UPGRADE.md`. The format is the following:" -msgstr "" +msgstr "O nome do arquivo é `UPGRADE.md`. O formato é o seguinte:" #. type: Fenced code block (markdown) #: ../src/internals/021-changelog-upgrade.md @@ -128,3 +141,19 @@ msgid "" "\n" "- Clean up the cache after upgrading. Old cache is not compatible with new code.\n" msgstr "" +"# Upgrading Instructions for my package\n" +"\n" +"This file contains the upgrade notes. These notes highlight changes that could break your\n" +"application when you upgrade the package from one version to another.\n" +"\n" +"> **Important!** The following upgrading instructions are cumulative. That is, if you want\n" +"> to upgrade from version A to version C and there is version B between A and C, you need\n" +"> to follow the instructions for both A and B.\n" +"\n" +"## Upgrade from 2.x\n" +"\n" +"- Public method `test()` was removed. Use `perform()` instead.\n" +"\n" +"## Upgrade from 1.x\n" +"\n" +"- Clean up the cache after upgrading. Old cache is not compatible with new code.\n" diff --git a/_translations/po/pt-BR/internals_022-config-groups.md.po b/_translations/po/pt-BR/internals_022-config-groups.md.po index 26409073..30ce8ac8 100644 --- a/_translations/po/pt-BR/internals_022-config-groups.md.po +++ b/_translations/po/pt-BR/internals_022-config-groups.md.po @@ -8,237 +8,235 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2025-12-24 08:02+0000\n" "PO-Revision-Date: 2025-12-24 08:02+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/en/guide/concept/configuration.md ../src/en/guide/concept/events.md -#: ../src/en/internals/022-config-groups.md +#: ../src/en/guide/concept/configuration.md ../src/en/guide/concept/events.md ../src/en/internals/022-config-groups.md #, no-wrap msgid "Events" -msgstr "" +msgstr "Eventos" #. type: Title ## -#: ../src/en/guide/concept/configuration.md -#: ../src/en/internals/022-config-groups.md +#: ../src/en/guide/concept/configuration.md ../src/en/internals/022-config-groups.md #, no-wrap msgid "Parameters" -msgstr "" +msgstr "Parâmetros" #. type: Title ## #: ../src/en/internals/003-roadmap.md ../src/en/internals/022-config-groups.md #, no-wrap msgid "Others" -msgstr "" +msgstr "Outros" #. type: Title # #: ../src/en/internals/022-config-groups.md #, no-wrap msgid "022 — Config groups" -msgstr "" +msgstr "022 — Grupos de configuração" #. type: Plain text #: ../src/en/internals/022-config-groups.md msgid "This document defines naming convention for the framework groups used with [yiisoft/config](https://github.com/yiisoft/config). Note that this isn't a naming convention for config files. These could be anything and are mapped to group names via `composer.json`." -msgstr "" +msgstr "Este documento define a convenção de nomes para os grupos do framework usados com o [yiisoft/config](https://github.com/yiisoft/config). Observe que esta não é uma convenção de nomes para arquivos de configuração. Eles podem ter qualquer nome e são mapeados para os nomes de grupo via `composer.json`." #. type: Title ## #: ../src/en/internals/022-config-groups.md #, no-wrap msgid "Config group name postfixes" -msgstr "" +msgstr "Sufixos dos nomes de grupos de configuração" #. type: Bullet: '- ' #: ../src/en/internals/022-config-groups.md msgid "\"web\" postfix applies to web only that's classic server HTML generation, REST, RPC, etc." -msgstr "" +msgstr "O sufixo \"web\" se aplica apenas à web, ou seja, geração clássica de HTML no servidor, REST, RPC etc." #. type: Bullet: '- ' #: ../src/en/internals/022-config-groups.md msgid "\"console\" postfix applies to console" -msgstr "" +msgstr "O sufixo \"console\" se aplica ao console" #. type: Bullet: '- ' #: ../src/en/internals/022-config-groups.md msgid "If there's no postfix, it's \"common\" and applies to both web and console" -msgstr "" +msgstr "Se não houver sufixo, o grupo é \"common\" e se aplica tanto à web quanto ao console" #. type: Bullet: '- ' #: ../src/en/internals/022-config-groups.md msgid "\"web\" and \"console\" may override what's defined in \"common\"" -msgstr "" +msgstr "\"web\" e \"console\" podem sobrescrever o que está definido em \"common\"" #. type: Plain text #: ../src/en/internals/022-config-groups.md msgid "Application config parameters that are used in all configs." -msgstr "" +msgstr "Parâmetros de configuração da aplicação usados em todas as configurações." #. type: Bullet: '- ' #: ../src/en/internals/022-config-groups.md msgid "`params` — common parameters" -msgstr "" +msgstr "`params` — parâmetros comuns" #. type: Bullet: '- ' #: ../src/en/internals/022-config-groups.md msgid "`params-web` — web application parameters" -msgstr "" +msgstr "`params-web` — parâmetros da aplicação web" #. type: Bullet: '- ' #: ../src/en/internals/022-config-groups.md msgid "`params-console` — console application parameters" -msgstr "" +msgstr "`params-console` — parâmetros da aplicação de console" #. type: Title ## #: ../src/en/internals/022-config-groups.md #, no-wrap msgid "Container" -msgstr "" +msgstr "Container" #. type: Plain text #: ../src/en/internals/022-config-groups.md msgid "Configuration for [yiisoft/di](https://github.com/yiisoft/di)." -msgstr "" +msgstr "Configuração do [yiisoft/di](https://github.com/yiisoft/di)." #. type: Title ### #: ../src/en/internals/022-config-groups.md #, no-wrap msgid "Definitions" -msgstr "" +msgstr "Definições" #. type: Bullet: '- ' #: ../src/en/internals/022-config-groups.md msgid "`di` — common container definitions" -msgstr "" +msgstr "`di` — definições comuns do container" #. type: Bullet: '- ' #: ../src/en/internals/022-config-groups.md msgid "`di-web` — web container definitions" -msgstr "" +msgstr "`di-web` — definições do container para web" #. type: Bullet: '- ' #: ../src/en/internals/022-config-groups.md msgid "`di-console` — console container definitions" -msgstr "" +msgstr "`di-console` — definições do container para console" #. type: Title ### #: ../src/en/internals/022-config-groups.md #, no-wrap msgid "Providers" -msgstr "" +msgstr "Providers" #. type: Bullet: '- ' #: ../src/en/internals/022-config-groups.md msgid "`di-providers` — common container providers" -msgstr "" +msgstr "`di-providers` — providers comuns do container" #. type: Bullet: '- ' #: ../src/en/internals/022-config-groups.md msgid "`di-providers-web` — web container providers" -msgstr "" +msgstr "`di-providers-web` — providers do container para web" #. type: Bullet: '- ' #: ../src/en/internals/022-config-groups.md msgid "`di-providers-console` — console container providers" -msgstr "" +msgstr "`di-providers-console` — providers do container para console" #. type: Title ### #: ../src/en/internals/022-config-groups.md #, no-wrap msgid "Delegates" -msgstr "" +msgstr "Delegates" #. type: Bullet: '- ' #: ../src/en/internals/022-config-groups.md msgid "`di-delegates` — common container delegates" -msgstr "" +msgstr "`di-delegates` — delegates comuns do container" #. type: Bullet: '- ' #: ../src/en/internals/022-config-groups.md msgid "`di-delegates-web` — web container delegates" -msgstr "" +msgstr "`di-delegates-web` — delegates do container para web" #. type: Bullet: '- ' #: ../src/en/internals/022-config-groups.md msgid "`di-delegates-console` — console container delegates" -msgstr "" +msgstr "`di-delegates-console` — delegates do container para console" #. type: Title ### #: ../src/en/internals/022-config-groups.md #, no-wrap msgid "Tags" -msgstr "" +msgstr "Tags" #. type: Bullet: '- ' #: ../src/en/internals/022-config-groups.md msgid "`di-tags` — common container tags" -msgstr "" +msgstr "`di-tags` — tags comuns do container" #. type: Bullet: '- ' #: ../src/en/internals/022-config-groups.md msgid "`di-tags-web` — web container tags" -msgstr "" +msgstr "`di-tags-web` — tags do container para web" #. type: Bullet: '- ' #: ../src/en/internals/022-config-groups.md msgid "`di-tags-console` — console container tags" -msgstr "" +msgstr "`di-tags-console` — tags do container para console" #. type: Plain text #: ../src/en/internals/022-config-groups.md msgid "Configuration for [yiisoft/yii-event](https://github.com/yiisoft/yii-event)." -msgstr "" +msgstr "Configuração do [yiisoft/yii-event](https://github.com/yiisoft/yii-event)." #. type: Bullet: '- ' #: ../src/en/internals/022-config-groups.md msgid "`events` — common events" -msgstr "" +msgstr "`events` — eventos comuns" #. type: Bullet: '- ' #: ../src/en/internals/022-config-groups.md msgid "`events-web` — web events" -msgstr "" +msgstr "`events-web` — eventos da web" #. type: Bullet: '- ' #: ../src/en/internals/022-config-groups.md msgid "`events-console` — console events" -msgstr "" +msgstr "`events-console` — eventos do console" #. type: Title ## #: ../src/en/internals/022-config-groups.md #, no-wrap msgid "Bootstrap" -msgstr "" +msgstr "Bootstrap" #. type: Plain text #: ../src/en/internals/022-config-groups.md msgid "Application bootstrapping for [yiisoft/yii-runner](https://github.com/yiisoft/yii-runner)." -msgstr "" +msgstr "Bootstrap da aplicação para o [yiisoft/yii-runner](https://github.com/yiisoft/yii-runner)." #. type: Bullet: '- ' #: ../src/en/internals/022-config-groups.md msgid "`bootstrap` — common bootstrap" -msgstr "" +msgstr "`bootstrap` — bootstrap comum" #. type: Bullet: '- ' #: ../src/en/internals/022-config-groups.md msgid "`bootstrap-web` — web bootstrap" -msgstr "" +msgstr "`bootstrap-web` — bootstrap da web" #. type: Bullet: '- ' #: ../src/en/internals/022-config-groups.md msgid "`bootstrap-console` — console bootstrap" -msgstr "" +msgstr "`bootstrap-console` — bootstrap do console" #. type: Bullet: '- ' #: ../src/en/internals/022-config-groups.md msgid "`routes` — [yiisoft/router](https://github.com/yiisoft/router) routes" -msgstr "" +msgstr "`routes` — rotas do [yiisoft/router](https://github.com/yiisoft/router)" #. type: Bullet: '- ' #: ../src/en/internals/022-config-groups.md msgid "`widgets` — [yiisoft/widget](https://github.com/yiisoft/widget) default widgets configuration" -msgstr "" +msgstr "`widgets` — configuração padrão de widgets do [yiisoft/widget](https://github.com/yiisoft/widget)" diff --git a/_translations/po/pt-BR/internals_023-github-actions.md.po b/_translations/po/pt-BR/internals_023-github-actions.md.po index 74b83cf3..240c47b7 100644 --- a/_translations/po/pt-BR/internals_023-github-actions.md.po +++ b/_translations/po/pt-BR/internals_023-github-actions.md.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2026-04-05 07:15+0000\n" "PO-Revision-Date: 2026-04-05 07:15+0000\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Last-Translator: Yuri Neves \n" +"Language-Team: Portuguese (Brazil)\n" "Language: pt-BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,28 +19,28 @@ msgstr "" #: ../src/internals/023-github-actions.md #, no-wrap msgid "023 — GitHub Actions" -msgstr "" +msgstr "023 — GitHub Actions" #. type: Plain text #: ../src/internals/023-github-actions.md msgid "This document defines naming convention for the GitHub actions configuration files." -msgstr "" +msgstr "Este documento define a convenção de nomes para os arquivos de configuração das GitHub Actions." #. type: Title ## #: ../src/internals/023-github-actions.md #, no-wrap msgid "Inputs and Outputs" -msgstr "" +msgstr "Inputs e outputs" #. type: Plain text #: ../src/internals/023-github-actions.md msgid "Input names and output names must use kebab-case format." -msgstr "" +msgstr "Os nomes de inputs e de outputs devem usar o formato kebab-case." #. type: Plain text #: ../src/internals/023-github-actions.md msgid "For example:" -msgstr "" +msgstr "Por exemplo:" #. type: Fenced code block (yaml) #: ../src/internals/023-github-actions.md @@ -50,17 +50,20 @@ msgid "" " my-input:\n" " description: 'My input'\n" msgstr "" +"inputs:\n" +" my-input:\n" +" description: 'My input'\n" #. type: Title ## #: ../src/internals/023-github-actions.md #, no-wrap msgid "Secrets and Environment Variables" -msgstr "" +msgstr "Secrets e variáveis de ambiente" #. type: Plain text #: ../src/internals/023-github-actions.md msgid "Secret names and environment variable names must use SCREAMING_SNAKE_CASE format." -msgstr "" +msgstr "Os nomes de secrets e de variáveis de ambiente devem usar o formato SCREAMING_SNAKE_CASE." #. type: Fenced code block (yaml) #: ../src/internals/023-github-actions.md @@ -70,6 +73,9 @@ msgid "" " MY_SECRET:\n" " description: 'My secret'\n" msgstr "" +"secrets:\n" +" MY_SECRET:\n" +" description: 'My secret'\n" #. type: Fenced code block (yaml) #: ../src/internals/023-github-actions.md @@ -78,3 +84,5 @@ msgid "" "env:\n" " MY_ENV_VAR: 1\n" msgstr "" +"env:\n" +" MY_ENV_VAR: 1\n" diff --git a/src/pt-BR/internals/000-packages.md b/src/pt-BR/internals/000-packages.md index b8f9434a..a0ccf0d7 100644 --- a/src/pt-BR/internals/000-packages.md +++ b/src/pt-BR/internals/000-packages.md @@ -1,42 +1,44 @@ -# 000 — Packages +# 000 — Pacotes -Yii3 team divided the framework into several packages that conform to the -following agreements. +O time do Yii3 dividiu o framework em vários pacotes que seguem os acordos +abaixo. -For all packages, the GitHub repository name exactly matches the Packagist -package name. +Em todos os pacotes, o nome do repositório no GitHub corresponde exatamente +ao nome do pacote no Packagist. -For a full list of packages and their building status, see [status page at +Para ver a lista completa de pacotes e o status de build de cada um, +consulte a [página de status em yiiframework.com](https://www.yiiframework.com/status/3.0). -## Yii-specific packages (framework and extensions) +## Pacotes específicos do Yii (framework e extensões) -- named `yiisoft/yii-something` or more specific: `yii-type-something` e.g.: - - modules: `yii-module-users`, `yii-module-pages` - - themes: `yii-theme-adminlte`, `yii-theme-hyde` +- nomeados como `yiisoft/yii-something` ou de forma mais específica: + `yii-type-something`, por exemplo: + - módulos: `yii-module-users`, `yii-module-pages` + - temas: `yii-theme-adminlte`, `yii-theme-hyde` - widgets: `yii-widget-datepicker` - ... -- titled as "Yii Framework ..." -- may have any dependencies and Yii-specific code +- intitulados como "Yii Framework ..." +- podem ter quaisquer dependências e código específico do Yii -## General purpose packages (libraries) +## Pacotes de uso geral (bibliotecas) -- you can use these independently of Yii Framework -- named as `yiisoft/something` without yii-prefix -- titled as "Yii ..." -- must not have dependencies on any Yii-specific packages -- should have as fewer dependencies as possible +- você pode usá-los independentemente do Yii Framework +- nomeados como `yiisoft/something`, sem o prefixo yii +- intitulados como "Yii ..." +- não podem ter dependências de nenhum pacote específico do Yii +- devem ter o menor número possível de dependências -## Configs and defaults +## Configurações e padrões -The following applies to both Yii-specific packages and general purpose -packages: +O que segue se aplica tanto aos pacotes específicos do Yii quanto aos +pacotes de uso geral: -- Package may have `config` directory with Yii-specific defaults. -- Package may have "config-plugin" in "extra" section of `composer.json`. -- Package mustn't have dependencies in `require` section of `composer.json` - that are used in `config` only. -- You should namespace parameters with `vendor/package-name`: +- O pacote pode ter um diretório `config` com padrões específicos do Yii. +- O pacote pode ter "config-plugin" na seção "extra" do `composer.json`. +- O pacote não pode ter, na seção `require` do `composer.json`, dependências + usadas apenas em `config`. +- Você deve colocar os parâmetros sob o namespace `vendor/package-name`: ```php return [ @@ -47,38 +49,39 @@ return [ ]; ``` -## Versions +## Versões -All packages follow [SemVer](https://semver.org/) versioning: +Todos os pacotes seguem o versionamento [SemVer](https://semver.org/): -- `x.*.*` - incompatible API changes. -- `*.x.*` - add functionality (backwards-compatible). -- `*.*.x` - bug fixes (backwards-compatible). +- `x.*.*` - mudanças incompatíveis na API. +- `*.x.*` - adição de funcionalidades (compatível com versões anteriores). +- `*.*.x` - correções de bugs (compatível com versões anteriores). -The first stable version should be 1.0.0. +A primeira versão estável deve ser 1.0.0. -Each package version number doesn't depend on any other package version or -framework name/version, only on its own public contract. The framework as a -whole has the "Yii3" name. +O número de versão de cada pacote não depende da versão de nenhum outro +pacote nem do nome/versão do framework, apenas do seu próprio contrato +público. O framework como um todo tem o nome "Yii3". -It's alright to use packages with different major versions together, as long -as they're compatible. +Não há problema em usar juntos pacotes com versões major diferentes, desde +que sejam compatíveis. -## PHP versions support +## Suporte a versões do PHP -The support of PHP versions supported for a package depends on [PHP versions -life cycle](https://www.php.net/supported-versions.php). +O suporte às versões do PHP em um pacote depende do [ciclo de vida das +versões do PHP](https://www.php.net/supported-versions.php). -- Package versions with active support MUST support all PHP versions that - have active support. -- Both packages and application templates MUST have supported versions that - receive bug and security fixes. These SHOULD correspond to PHP versions - receiving security fixes. -- Packages and application templates MIGHT have supported versions that work - with unsupported PHP versions. -- Bumping the minimal PHP version in a package or an application template is - a minor change. +- Versões de pacotes com suporte ativo DEVEM suportar todas as versões do + PHP que têm suporte ativo. +- Tanto os pacotes quanto os templates de aplicação DEVEM ter versões + suportadas que recebem correções de bugs e de segurança. Essas versões + DEVERIAM corresponder às versões do PHP que recebem correções de + segurança. +- Pacotes e templates de aplicação PODEM ter versões suportadas que + funcionam com versões do PHP sem suporte. +- Aumentar a versão mínima do PHP em um pacote ou template de aplicação é + uma mudança minor. ## composer.json -A logical OR operator in version ranges MUST use double pipe (`||`). For example: `"yiisoft/arrays": "^1.0 || ^2.0"`. +Um operador lógico OU em intervalos de versão DEVE usar pipe duplo (`||`). Por exemplo: `"yiisoft/arrays": "^1.0 || ^2.0"`. diff --git a/src/pt-BR/internals/001-yii-values.md b/src/pt-BR/internals/001-yii-values.md index b69a77e2..8735807b 100644 --- a/src/pt-BR/internals/001-yii-values.md +++ b/src/pt-BR/internals/001-yii-values.md @@ -1,82 +1,85 @@ -# 001 — Yii goal and values +# 001 — Objetivo e valores do Yii -## Goal +## Objetivo -The Yii project aims to build and support _practical_ and _helpful_ tools -and community. +O projeto Yii tem como objetivo construir e manter ferramentas e uma +comunidade _práticas_ e _úteis_. -## Values +## Valores -The values we express in our work support the goal. We try to +Os valores que expressamos em nosso trabalho apoiam esse +objetivo. Procuramos -- Be practical - - [High performance](#high-performance) - - [Sensible defaults and - flexibility](#sensible-defaults-and-flexibility) - - [Be practice-oriented](#be-practice-oriented) -- Be helpful - - [Be simple](#be-simple) - - [Be explicit](#be-explicit) - - [Be consistent](#be-consistent) +- Ser práticos + - [Alto desempenho](#alto-desempenho) + - [Padrões sensatos e flexibilidade](#padroes-sensatos-e-flexibilidade) + - [Ser orientado à prática](#ser-orientado-a-pratica) +- Ser úteis + - [Ser simples](#ser-simples) + - [Ser explícito](#ser-explicito) + - [Ser consistente](#ser-consistente) -## Be practical +## Ser práticos -### High performance +### Alto desempenho -Performance is a necessary condition of practicality. Software shouldn't -waste machine resources or human resources. +Desempenho é uma condição necessária para a praticidade. O software não deve +desperdiçar recursos de máquina nem recursos humanos. -### Sensible defaults and flexibility +### Padrões sensatos e flexibilidade -We prefer sensible defaults and conventions that users can customize. We -seek a balance between flexibility, discipline and simplicity that meets -common needs. +Preferimos padrões e convenções sensatos que os usuários possam +personalizar. Buscamos um equilíbrio entre flexibilidade, disciplina e +simplicidade que atenda às necessidades comuns. -### Be practice-oriented +### Ser orientado à prática -We prefer practice to theory. For example: +Preferimos a prática à teoria. Por exemplo: -- Solutions for known use cases should avoid excess complexity by providing - only necessary flexibility. -- Standard implementations should take practical use into account. -- Experience is at least as useful as theory in guiding design. -- Context is critical in determining appropriateness. +- Soluções para casos de uso conhecidos devem evitar complexidade excessiva, + oferecendo apenas a flexibilidade necessária. +- Implementações padrão devem levar em conta o uso prático. +- A experiência é pelo menos tão útil quanto a teoria para orientar o + design. +- O contexto é fundamental para determinar o que é adequado. -## Be helpful +## Ser úteis -This value guides technical decisions as well as community activity. -Consideration of how software features help users should guide development. -Community-wise, we value any helpful contribution, be it a pull request or -an answer in the forum. +Esse valor orienta tanto as decisões técnicas quanto a atividade da +comunidade. O desenvolvimento deve ser guiado pela forma como os recursos +do software ajudam os usuários. Na comunidade, valorizamos qualquer +contribuição útil, seja um pull request ou uma resposta no fórum. -When the other principles conflict, we choose a solution that's more helpful -to the community. +Quando os outros princípios entram em conflito, escolhemos a solução mais +útil para a comunidade. -### Be simple +### Ser simples -Solutions should be simple and expressive: +As soluções devem ser simples e expressivas: -- We use as much complexity as needed and no more. -- We avoid ugly solutions unless there is no alternative. -- Fewer rules are better than more rules. +- Usamos tanta complexidade quanto necessário, e não mais. +- Evitamos soluções feias, a menos que não haja alternativa. +- Menos regras é melhor do que mais regras. -### Be Explicit +### Ser explícito -We prefer explicit, obvious solutions and code. Solutions should clearly -express exactly what they do. For example: +Preferimos soluções e código explícitos e óbvios. As soluções devem +expressar claramente o que fazem. Por exemplo: -- A straightforward solution is better than an abstract one unless the - abstraction has a practical purpose. -- Loud fails are better than silent fails or masking errors. -- Explicit casts are better than PHP type juggling, type hints are good. -- No magic unless necessary. +- Uma solução direta é melhor do que uma abstrata, a menos que a abstração + tenha um propósito prático. +- Falhas ruidosas são melhores do que falhas silenciosas ou erros + mascarados. +- Conversões explícitas são melhores do que a conversão automática de tipos + do PHP; type hints são bons. +- Nada de mágica, a menos que seja necessário. -### Be consistent +### Ser consistente -We try to be consistent in: +Procuramos ser consistentes em: -- Code style -- Naming +- Estilo de código +- Nomenclatura - Design -- Structure -- Values and goals +- Estrutura +- Valores e objetivos diff --git a/src/pt-BR/internals/002-issue-workflow.md b/src/pt-BR/internals/002-issue-workflow.md index 58f8df1c..44b09afa 100644 --- a/src/pt-BR/internals/002-issue-workflow.md +++ b/src/pt-BR/internals/002-issue-workflow.md @@ -1,27 +1,30 @@ -# 002 — Issue workflow +# 002 — Fluxo de issues -The process of handing incoming issues is the following: +O processo de tratamento das issues recebidas é o seguinte: -![Issue workflow schema](/images/internals/002-issue-workflow.svg) +![Esquema do fluxo de issues](/images/internals/002-issue-workflow.svg) -## Roles +## Papéis -We've many roles: +Temos vários papéis: -- Process managers - initially triage issues and manage labels. -- Decision makers - participate in discussions moving them to resolutions. -- Bug hunters - verifying bugs. -- Contributors - create code for pull requests. -- Code reviewers - review pull requests. +- Gerentes de processo - fazem a triagem inicial das issues e gerenciam os + labels. +- Tomadores de decisão - participam das discussões, levando-as a uma + resolução. +- Caçadores de bugs - verificam os bugs. +- Contribuidores - escrevem o código dos pull requests. +- Revisores de código - revisam os pull requests. -A single person may take one or more roles in the issue-resolving process. +Uma mesma pessoa pode assumir um ou mais papéis no processo de resolução de +issues. ## Labels -We label issues to mark many things: current status, issue type, component -affected. Status labels speak for themselves. +Usamos labels nas issues para marcar várias coisas: status atual, tipo da +issue, componente afetado. Os labels de status falam por si. ## Milestones -Issues aren't assigned to milestones unless they're critical or there is a -likely good pull request exists. +As issues não são atribuídas a milestones, a menos que sejam críticas ou que +provavelmente exista um bom pull request para elas. diff --git a/src/pt-BR/internals/003-roadmap.md b/src/pt-BR/internals/003-roadmap.md index 92cb78f0..c2fb9d11 100644 --- a/src/pt-BR/internals/003-roadmap.md +++ b/src/pt-BR/internals/003-roadmap.md @@ -1,207 +1,210 @@ # 003 — Roadmap -We want Yii 3 to: +Queremos que o Yii 3: -- Not limit a developer to choosing architecture. Allow anything from - "classic" MVC to DDD. -- Be based on the best practices such as SOLID, GRASP, etc. and teach them - to the community. -- Keep the most good things from Yii 2. -- Be more open to the global PHP community and infrastructure. +- Não limite o desenvolvedor na escolha da arquitetura. Permita qualquer + coisa, do MVC "clássico" ao DDD. +- Seja baseado em boas práticas como SOLID, GRASP etc. e as ensine à + comunidade. +- Mantenha a maior parte das coisas boas do Yii 2. +- Seja mais aberto à comunidade e à infraestrutura PHP global. -## PSRs compliance +## Conformidade com PSRs -PSR compliance helps with customizability, the ability to use general PHP -libraries and implement fewer wrappers. Here's the list of PSRs we want to -implement. +A conformidade com PSRs ajuda na personalização, permite usar bibliotecas +PHP gerais e implementar menos wrappers. Aqui está a lista de PSRs que +queremos implementar. ### PSR-3 Logger -Implemented as a [separate package that isn't dependent on a +Implementado como um [pacote separado que não depende de um framework](https://github.com/yiisoft/log). -- [x] Framework packages should depend on interface only. -- [x] Split drivers into packages. -- [x] Clean-up code. -- [x] [Fix email target](https://github.com/yiisoft/log-target-email). +- [x] Os pacotes do framework devem depender apenas da interface. +- [x] Separar os drivers em pacotes. +- [x] Limpar o código. +- [x] [Corrigir o destino de + e-mail](https://github.com/yiisoft/log-target-email). ### PSR-4 Autoloading -- [x] Autoloading is fine already. -- [x] Document on how it works. +- [x] O autoloading já está bom. +- [x] Documentar como funciona. ### PSR-7 HTTP message -- [x] Remove our own implementation. At least for now. -- [x] Framework packages should depend on interfaces only. +- [x] Remover nossa própria implementação. Pelo menos por enquanto. +- [x] Os pacotes do framework devem depender apenas de interfaces. ### PSR-11 Container -Implemented as a [separate package that isn't dependent on a +Implementado como um [pacote separado que não depende de um framework](https://github.com/yiisoft/di). -- [x] Framework packages shouldn't use container directly. One should be - able to instantiate everything manually. -- [x] Finish refactoring. -- [x] Remove all framework-specific implementations from the package. Move - to a framework. -- [x] [Implement autoloader - fallback](https://github.com/yiisoft/di/issues/88) +- [x] Os pacotes do framework não devem usar o container diretamente. Deve + ser possível instanciar tudo manualmente. +- [x] Terminar a refatoração. +- [x] Remover do pacote todas as implementações específicas do + framework. Movê-las para o framework. +- [x] [Implementar fallback para o + autoloader](https://github.com/yiisoft/di/issues/88) ### PSR-12 Code style -- [x] Make sure the code follows it. -- [x] Automate fixing style before release. +- [x] Garantir que o código o siga. +- [x] Automatizar a correção de estilo antes do release. ### PSR-14 Event dispatcher -- [x] [Implement as a separate - library](https://github.com/yiisoft/event-dispatcher). -- [x] Use in other packages. -- [x] Polish. +- [x] [Implementar como uma biblioteca + separada](https://github.com/yiisoft/event-dispatcher). +- [x] Usar em outros pacotes. +- [x] Polir. ### PSR-15 HTTP handlers -- [x] Rewrite HTTP flow to PSR-7 request-response + formatting response via - emitter. -- [x] Offer SAPI emitter out of the box. -- [x] Make it possible to use alternative emitters such as RoadRunner. -- [x] Support middleware. -- [x] Implement filters as middleware: - - [x] [Rate limiting](https://github.com/yiisoft/yii-web/issues/63) - - [x] [Authentication](https://github.com/yiisoft/yii-web/issues/114) -- [x] Re-implement router w/ middleware support for route groups. -- [x] Filters should be middlewares. +- [x] Reescrever o fluxo HTTP para requisição-resposta PSR-7 + formatação da + resposta via emitter. +- [x] Oferecer um emitter SAPI pronto para uso. +- [x] Possibilitar o uso de emitters alternativos, como o RoadRunner. +- [x] Suportar middleware. +- [x] Implementar filtros como middleware: + - [x] [Limitação de taxa](https://github.com/yiisoft/yii-web/issues/63) + - [x] [Autenticação](https://github.com/yiisoft/yii-web/issues/114) +- [x] Reimplementar o router com suporte a middleware para grupos de rotas. +- [x] Filtros devem ser middlewares. ### PSR-16 Simple cache -Implemented as a [separate package that isn't dependent on a +Implementado como um [pacote separado que não depende de um framework](https://github.com/yiisoft/cache). -- [x] Framework packages should depend on interfaces only. -- [x] Split drivers into packages. -- [x] Clean-up code. +- [x] Os pacotes do framework devem depender apenas de interfaces. +- [x] Separar os drivers em pacotes. +- [x] Limpar o código. ### PSR-17 HTTP factories -- [x] Use PSR factories. +- [x] Usar as factories PSR. ### PSR-18 HTTP client -- [x] Remove our own implementation. At least for now. -- [x] Framework packages should depend on interfaces only. +- [x] Remover nossa própria implementação. Pelo menos por enquanto. +- [x] Os pacotes do framework devem depender apenas de interfaces. -## Stricter types +## Tipos mais estritos -- [x] Make sure type hinting is used everywhere. -- [x] Make sure types are as definitive as possible. Avoid varying types if - possible. +- [x] Garantir que type hints sejam usados em todo lugar. +- [x] Garantir que os tipos sejam o mais definidos possível. Evitar tipos + variáveis sempre que possível. -## Single application template +## Template de aplicação único -- [x] Drop basic/advanced. -- [x] Create a [single application template that works out of the - box](https://github.com/yiisoft/app). +- [x] Abandonar basic/advanced. +- [x] Criar um [template de aplicação único que funcione de + imediato](https://github.com/yiisoft/app). ## Router -Implemented as a [separate package that isn't dependent on a +Implementado como um [pacote separado que não depende de um framework](https://github.com/yiisoft/router). -- [x] DSL for configuration. -- [x] Ability to route to any callable. -- [x] Named routes. -- [x] Route groups w/ middleware support. +- [x] DSL para configuração. +- [x] Possibilidade de rotear para qualquer callable. +- [x] Rotas nomeadas. +- [x] Grupos de rotas com suporte a middleware. -## Best practices and SOLID compliance of all classes/packages +## Boas práticas e conformidade com SOLID em todas as classes/pacotes -- [x] Make sure interfaces follow the "interface segregation" principle. -- [x] Don't use public properties. -- [x] Don't use `init()`. -- [x] Don't inherit from `BaseObject` or `Component`. Remove these. -- [x] No globals. -- [x] No static calls except helpers that are final. -- [x] Prefer throwing exceptions to fixing input. +- [x] Garantir que as interfaces sigam o princípio de "segregação de + interfaces". +- [x] Não usar propriedades públicas. +- [x] Não usar `init()`. +- [x] Não herdar de `BaseObject` ou `Component`. Removê-los. +- [x] Nada de globais. +- [x] Nada de chamadas estáticas, exceto helpers finais. +- [x] Preferir lançar exceções a corrigir a entrada. -## Development toolkit +## Kit de ferramentas de desenvolvimento -- [x] Release command line tool -- [x] Development command line tool (symlinks packages into usable - application) +- [x] Ferramenta de linha de comando para release +- [x] Ferramenta de linha de comando para desenvolvimento (cria symlinks dos + pacotes em uma aplicação utilizável) ## Console -- [x] Separate web and console application -- [x] Possibly eliminate base application (still needed) -- [x] Create an interface for the console (using Symfony one) -- [x] Implementation may be one of the popular ones (using Symfony one) -- [x] Ensure application can add commands via config +- [x] Separar aplicação web e aplicação de console +- [x] Possivelmente eliminar a aplicação base (ainda é necessária) +- [x] Criar uma interface para o console (usando a do Symfony) +- [x] A implementação pode ser uma das populares (usando a do Symfony) +- [x] Garantir que a aplicação possa adicionar comandos via configuração ## Documentação -- [ ] Follow best practices. -- [ ] Don't use the "MVC" term. -- [ ] Upgrading from Yii 2. +- [ ] Seguir boas práticas. +- [ ] Não usar o termo "MVC". +- [ ] Upgrade a partir do Yii 2. ## RBAC -RBAC is implemented as [a framework-independent -package](https://github.com/yiisoft/rbac). +O RBAC é implementado como [um pacote independente de +framework](https://github.com/yiisoft/rbac). -- [x] Finish refactoring. -- [x] Make sure it follows best practices. -- [x] Split drivers into packages. +- [x] Terminar a refatoração. +- [x] Garantir que siga boas práticas. +- [x] Separar os drivers em pacotes. ## View -View is implemented as [framework-independent -package](https://github.com/yiisoft/view). +A view é implementada como [pacote independente de +framework](https://github.com/yiisoft/view). -- [x] Finish refactoring ([see +- [x] Terminar a refatoração ([veja as issues](https://github.com/yiisoft/view/issues)). -- [x] Port widgets. -- [x] Rethink and implement active form widgets. -- [x] Implement caching widgets. +- [x] Portar os widgets. +- [x] Repensar e implementar os widgets de active form. +- [x] Implementar widgets de cache. -## Data abstractions and grid +## Abstrações de dados e grid -- [x] Finish [data abstractions](https://github.com/yiisoft/data). -- [x] Port sort, use data abstractions. Should be part of +- [x] Terminar as [abstrações de dados](https://github.com/yiisoft/data). +- [x] Portar a ordenação, usando abstrações de dados. Deve fazer parte do [yii-dataview](https://github.com/yiisoft/yii-dataview). -- [x] Port paging, use data abstractions. Should be part of +- [x] Portar a paginação, usando abstrações de dados. Deve fazer parte do [yii-dataview](https://github.com/yiisoft/yii-dataview). -- [x] Port grid, use data abstractions. Should be part of +- [x] Portar o grid, usando abstrações de dados. Deve fazer parte do [yii-dataview](https://github.com/yiisoft/yii-dataview). -- [x] Port list, use data abstractions. Should be part of +- [x] Portar a lista, usando abstrações de dados. Deve fazer parte do [yii-dataview](https://github.com/yiisoft/yii-dataview). -## Validators +## Validadores -- [x] Finish [the main package](https://github.com/yiisoft/validator) - redesign -- [x] Port necessary validators +- [x] Terminar o redesign do [pacote + principal](https://github.com/yiisoft/validator) +- [x] Portar os validadores necessários ## Debug toolbar -- [x] Port debug toolbar. +- [x] Portar a debug toolbar. ## Gii -- [x] Port Gii. +- [x] Portar o Gii. -## Infrastructure +## Infraestrutura -- [x] Cover [config](https://github.com/yiisoft/config) with tests. -- [x] Release stable [config](https://github.com/yiisoft/config). +- [x] Cobrir o [config](https://github.com/yiisoft/config) com testes. +- [x] Lançar uma versão estável do + [config](https://github.com/yiisoft/config). -## Others +## Outros -- [x] [Decide on +- [x] [Decidir sobre os namespaces](https://forum.yiiframework.com/t/lowercase-or-camelcase-namespaces/124983/52). -- [x] [Clean up error - handler](https://github.com/yiisoft/yii2/issues/14348). Make sure the - error handler catches fatals and is using response. -- [x] Make validators independent of models to allow reusing them in - handlers. -- [x] [Split +- [x] [Limpar o error + handler](https://github.com/yiisoft/yii2/issues/14348). Garantir que o + error handler capture erros fatais e use a resposta. +- [x] Tornar os validadores independentes dos models para permitir + reutilizá-los em handlers. +- [x] [Dividir a IdentityInterface](https://github.com/yiisoft/yii2/issues/13825). diff --git a/src/pt-BR/internals/004-namespaces.md b/src/pt-BR/internals/004-namespaces.md index 8f623dbd..5172d465 100644 --- a/src/pt-BR/internals/004-namespaces.md +++ b/src/pt-BR/internals/004-namespaces.md @@ -1,23 +1,23 @@ # 004 — Namespaces -Package namespace rules are the following: +As regras de namespace dos pacotes são as seguintes: -1. PascalCase is used for namespace parts. -2. Root vendor namespace is `Yiisoft`. -3. Package name parts are used in namespace. -4. Adjective is added to a noun and is a single part. +1. As partes do namespace usam PascalCase. +2. O namespace raiz do vendor é `Yiisoft`. +3. As partes do nome do pacote são usadas no namespace. +4. Um adjetivo é unido ao substantivo e forma uma única parte. -Some examples: +Alguns exemplos: -| Package | Namespace | +| Pacote | Namespace | |----------------------------|---------------------------| | yiisoft/yii-web | Yiisoft\Yii\Web | | yiisoft/di | Yiisoft\Di | | yiisoft/db-mysql | Yiisoft\Db\Mysql | | yiisoft/friendly-exception | Yiisoft\FriendlyException | -## References +## Referências -- [International forum - discussion](https://forum.yiiframework.com/t/use-yiisoft-as-a-root-namespace-instead-of-yii-for-yii-3-packages/125734) +- [Discussão no fórum + internacional](https://forum.yiiframework.com/t/use-yiisoft-as-a-root-namespace-instead-of-yii-for-yii-3-packages/125734) diff --git a/src/pt-BR/internals/005-development-tool.md b/src/pt-BR/internals/005-development-tool.md index 961d7e7e..ef9a4f3d 100644 --- a/src/pt-BR/internals/005-development-tool.md +++ b/src/pt-BR/internals/005-development-tool.md @@ -1,8 +1,8 @@ -# 005 — Yii development tool +# 005 — Ferramenta de desenvolvimento do Yii -For Yii3, the number of packages increased significantly to achieve more -reusability and independent releases. To ease development of the framework -itself, we've created a special tool available from +No Yii3, o número de pacotes aumentou bastante para permitir mais reuso e +releases independentes. Para facilitar o desenvolvimento do próprio +framework, criamos uma ferramenta especial, disponível em [yiisoft/yii-dev-tool](https://github.com/yiisoft/yii-dev-tool). ``` @@ -33,19 +33,20 @@ Available commands: update Update packages ``` -There are many commands available. The most important ones are `install` and -`update`. What it does is: +Há muitos comandos disponíveis. Os mais importantes são `install` e +`update`. O que eles fazem: -1. Install/update all packages listed in +1. Instalam/atualizam todos os pacotes listados em [`packages.php`](https://github.com/yiisoft/yii-dev-tool/blob/master/packages.php) - or individual package from that list if specified. -2. For every package installed check `vendor` directory for packages listed - in `packages.php`. If there is any, replace the package directory with a - symlink to another package source. - -As a result, you will have many packages using each other, so there is no -need to `git push` and `composer install` / `composer update` during -development. - -A [detailed example](https://github.com/yiisoft/yii-dev-tool#usage-example) -of using the tool is available in its README. + ou um pacote específico dessa lista, se informado. +2. Para cada pacote instalado, verificam no diretório `vendor` se há pacotes + listados em `packages.php`. Se houver, substituem o diretório do pacote + por um symlink para o código-fonte do outro pacote. + +Como resultado, você terá muitos pacotes usando uns aos outros, sem precisar +de `git push` e `composer install` / `composer update` durante o +desenvolvimento. + +Um [exemplo +detalhado](https://github.com/yiisoft/yii-dev-tool#usage-example) de uso da +ferramenta está disponível no README dela. diff --git a/src/pt-BR/internals/006-git-commit-messages.md b/src/pt-BR/internals/006-git-commit-messages.md index ad1bd260..421c1085 100644 --- a/src/pt-BR/internals/006-git-commit-messages.md +++ b/src/pt-BR/internals/006-git-commit-messages.md @@ -1,18 +1,18 @@ -# 006 — Git commit messages +# 006 — Mensagens de commit do Git -## Subject line +## Linha de assunto -- Use `#123` to reference issue by number -- Use imperative mood that's `Fix`, not `Fixed` -- Don't add a period at the end -- Use `[skip ci]` if there is no need to run unit tests -- Start with a capital letter -- Limit to 50 characters +- Use `#123` para referenciar uma issue pelo número +- Use o modo imperativo, ou seja, `Fix`, e não `Fixed` +- Não coloque ponto final +- Use `[skip ci]` se não houver necessidade de rodar os testes unitários +- Comece com letra maiúscula +- Limite a 50 caracteres ## Corpo -Use the message body **if** you need an extra explanation. Explain why, not -how. +Use o corpo da mensagem **se** precisar de uma explicação extra. Explique o +porquê, não o como. -- Limit line length to 72 characters +- Limite o tamanho das linhas a 72 caracteres diff --git a/src/pt-BR/internals/007-exceptions.md b/src/pt-BR/internals/007-exceptions.md index f40cf62e..09abfe56 100644 --- a/src/pt-BR/internals/007-exceptions.md +++ b/src/pt-BR/internals/007-exceptions.md @@ -1,16 +1,16 @@ -# 007 — Exceptions +# 007 — Exceções -- Throw exceptions instead of returning an error code. -- Exception class name must be suffixed with `Exception`. -- Use grammatically correct error messages including ending punctuation, - that's most exceptions must end with a period. -- `\InvalidArgumentException` must be used directly. There should be no - exceptions inherited from it. -- `\InvalidArgumentException` must never be caught. +- Lance exceções em vez de retornar um código de erro. +- O nome da classe de exceção deve ter o sufixo `Exception`. +- Use mensagens de erro gramaticalmente corretas, incluindo a pontuação + final, ou seja, a maioria das exceções deve terminar com ponto. +- `\InvalidArgumentException` deve ser usada diretamente. Não deve haver + exceções herdadas dela. +- `\InvalidArgumentException` nunca deve ser capturada. -## References +## Referências -- [International community discussion and - poll](https://forum.yiiframework.com/t/naming-exceptions/126613/6) -- [Russian community discussion and - poll](https://yiiframework.ru/forum/viewtopic.php?f=39&t=51290) +- [Discussão e enquete na comunidade + internacional](https://forum.yiiframework.com/t/naming-exceptions/126613/6) +- [Discussão e enquete na comunidade + russa](https://yiiframework.ru/forum/viewtopic.php?f=39&t=51290) diff --git a/src/pt-BR/internals/008-interfaces.md b/src/pt-BR/internals/008-interfaces.md index bfe91968..d2a0a6b5 100644 --- a/src/pt-BR/internals/008-interfaces.md +++ b/src/pt-BR/internals/008-interfaces.md @@ -1,10 +1,10 @@ # 008 — Interfaces -- Interface name should be suffixed with `Interface`. +- O nome da interface deve ter o sufixo `Interface`. -## References +## Referências -- [International community discussion and - poll](https://forum.yiiframework.com/t/naming-interfaces/126612/5) -- [Russian community discussion and - poll](https://yiiframework.ru/forum/viewtopic.php?f=39&t=51289) +- [Discussão e enquete na comunidade + internacional](https://forum.yiiframework.com/t/naming-interfaces/126612/5) +- [Discussão e enquete na comunidade + russa](https://yiiframework.ru/forum/viewtopic.php?f=39&t=51289) diff --git a/src/pt-BR/internals/009-design-decisions.md b/src/pt-BR/internals/009-design-decisions.md index a9e0f54b..08d91534 100644 --- a/src/pt-BR/internals/009-design-decisions.md +++ b/src/pt-BR/internals/009-design-decisions.md @@ -1,89 +1,93 @@ -# 009 — Design Decisions +# 009 — Decisões de design -In this document, we list important design decisions taken during Yii3 -development. +Neste documento, listamos decisões de design importantes tomadas durante o +desenvolvimento do Yii3. -## Remove magic properties +## Remover propriedades mágicas -Magic properties in Yii 2 were an interesting idea that allowed a developer -to start with public property and then seamlessly migrate to using -getter/setter called via magic methods without changing the code. +As propriedades mágicas do Yii 2 eram uma ideia interessante: permitiam ao +desenvolvedor começar com uma propriedade pública e depois migrar de forma +transparente para getter/setter chamados via métodos mágicos, sem mudar o +código. -The main reason for removal in Yii 3 is that it resulted in using public -properties everywhere, thus lack of encapsulation and code fragility. +O principal motivo da remoção no Yii 3 é que isso levava ao uso de +propriedades públicas em todo lugar, resultando em falta de encapsulamento e +código frágil. -## Remove the service locator +## Remover o service locator -Service locator both Yii 1 and Yii 2 was convenient but was also abused a -lot. Although a dependency injection container was available in Yii 2, -service locator was generally preferred to cause both a dependency on the -service locator itself, high coupling, hard to test code. +O service locator, tanto no Yii 1 quanto no Yii 2, era conveniente, mas +também muito abusado. Embora o Yii 2 tivesse um container de injeção de +dependência, o service locator costumava ser preferido, o que causava +dependência do próprio service locator, alto acoplamento e código difícil de +testar. -Yii 3 relies on dependency injection only lowering coupling significantly -and making code way more testable. +O Yii 3 usa apenas injeção de dependência, o que reduz bastante o +acoplamento e torna o código muito mais testável. -## Extract general packages +## Extrair pacotes de uso geral -Yii 1 and Yii 2 were fully closed communities. All the code we had wasn't -useful outside Yii, and most of the "external" code wasn't useful in Yii -without wrappers. It was noted many times by communities external to Yii -that many parts of Yii are well-designed and unique, and they'd use these if -these were available as standalone packages. +O Yii 1 e o Yii 2 eram comunidades totalmente fechadas. Todo o código que +tínhamos não era útil fora do Yii, e a maior parte do código "externo" não +era útil no Yii sem wrappers. Comunidades de fora do Yii comentaram muitas +vezes que várias partes do Yii são bem projetadas e únicas, e que as usariam +se estivessem disponíveis como pacotes independentes. -As part of Yii 3 packages such as cache, RBAC, view, etc. were extracted -into framework-independent packages. Benefits are: +Como parte do Yii 3, pacotes como cache, RBAC, view etc. foram extraídos +para pacotes independentes de framework. Os benefícios são: -- Increased usage and contribution -- Yii team could delegate maintenance -- Independent releases are possible +- Mais uso e mais contribuições +- O time do Yii pode delegar a manutenção +- Releases independentes passam a ser possíveis -## Adopt PSRs +## Adotar PSRs -The team adopted some PSRs in Yii 2, such as PSR-4 and PSR-2. Interfaces in -general weren't, although Yii is part of PHP-FIG. Mainly because when Yii 2 -was released, these were either in the making or not adopted enough. +O time adotou algumas PSRs no Yii 2, como a PSR-4 e a PSR-2. As interfaces, +em geral, não foram adotadas, embora o Yii faça parte do PHP-FIG. +Principalmente porque, quando o Yii 2 foi lançado, elas ainda estavam em +elaboração ou não tinham adoção suficiente. -Yii3 benefits from PSRs since there are nowadays many ready-to-use libraries -that one can get via Composer: cache backends, middleware, loggers, DI -containers, etc. +O Yii3 se beneficia das PSRs, já que hoje existem muitas bibliotecas prontas +para uso que você instala via Composer: backends de cache, middlewares, +loggers, containers de DI etc. -By implementing PSRs in general packages, we allow these to be used in more -projects, thus raising the contribution level. +Ao implementar PSRs nos pacotes de uso geral, permitimos que eles sejam +usados em mais projetos, aumentando o nível de contribuição. -## Improve DI container +## Melhorar o container de DI -The problem with the Yii 2 container was that it's tailored to be used with -Yii 2 components. API isn't well-designed to be used with general PHP -classes. +O problema do container do Yii 2 era que ele foi feito sob medida para os +componentes do Yii 2. A API não foi bem projetada para uso com classes PHP +em geral. -In Yii3, we ensured that container can be used to conveniently configure any -PHP class. +No Yii3, garantimos que o container possa ser usado para configurar qualquer +classe PHP de forma conveniente. -That should result in the absence of Yii-specific wrapper packages and more -direct usages of Composer packages. +Isso deve resultar na ausência de pacotes wrapper específicos do Yii e em +mais uso direto de pacotes do Composer. -## Adopt strict types +## Adotar strict types -Strict types were introduced because: +Os strict types foram introduzidos porque: -- PHP 7 is now mainstream -- While they solve no significant Yii 2 problems, they help to avoid many - day-to-day development issues +- O PHP 7 agora é o padrão do mercado +- Embora não resolvam nenhum problema significativo do Yii 2, ajudam a + evitar muitos problemas do dia a dia de desenvolvimento -## Adopt SemVer +## Adotar SemVer -Yii 2 has its own version policy. Problems: +O Yii 2 tem sua própria política de versões. Problemas: -- It wasn't standard -- Composer relies on SemVer -- It's hard to support a framework built on top of packages if the - versioning policy isn't strict +- Não era um padrão +- O Composer se baseia em SemVer +- É difícil manter um framework construído sobre pacotes se a política de + versionamento não for rígida -## Prevent validators mutating data +## Impedir que validadores alterem dados -In Yii 1 and Yii 2, validators such as "date" were mutating data. It was -confusing for a validation process not initially meant to mutate data it -validates. +No Yii 1 e no Yii 2, validadores como "date" alteravam os dados. Era +confuso que um processo de validação, que a princípio não deveria alterar os +dados que valida, fizesse isso. -[See related -discussion](https://forum.yiiframework.com/t/saving-or-killing-non-validation-in-validators/126086). +[Veja a discussão +relacionada](https://forum.yiiframework.com/t/saving-or-killing-non-validation-in-validators/126086). diff --git a/src/pt-BR/internals/010-code-style.md b/src/pt-BR/internals/010-code-style.md index 3cf3869a..d1b6f695 100644 --- a/src/pt-BR/internals/010-code-style.md +++ b/src/pt-BR/internals/010-code-style.md @@ -1,49 +1,52 @@ -# 010 — Code style +# 010 — Estilo de código -Code formatting used in Yii 3 packages is based on [PER Coding Style -3.0](https://www.php-fig.org/per/coding-style/) with extra rules added on -top of it. +A formatação de código usada nos pacotes do Yii 3 é baseada no [PER Coding +Style 3.0](https://www.php-fig.org/per/coding-style/) com regras extras +adicionadas por cima. -## Names +## Nomes -- Use English only. -- Use camelCase notation, including abbreviations (e.g., `enableIdn`). -- Use the shortest possible, but an explanatory name. -- Never trim or abbreviate a name. -- Postfix classes, interfaces, traits and variables, which is a - [collection](https://en.wikipedia.org/wiki/Collection_(abstract_data_type)), - with `Collection`. -- Postfix middleware classes with `Middleware`. +- Use apenas inglês. +- Use a notação camelCase, inclusive em abreviações (por exemplo, + `enableIdn`). +- Use o nome mais curto possível, mas que seja explicativo. +- Nunca corte ou abrevie um nome. +- Adicione o sufixo `Collection` a classes, interfaces, traits e variáveis + que sejam uma + [coleção](https://en.wikipedia.org/wiki/Collection_(abstract_data_type)). +- Adicione o sufixo `Middleware` às classes de middleware. -## Types +## Tipos -- Declare [argument and return - types](https://www.php.net/manual/en/migration70.new-features.php) where - possible. -- [Use types for properties](https://wiki.php.net/rfc/typed_properties_v2). -- Use strict typing. Avoid mixed and union types where possible except - compatible types such as `string|Stringable`. +- Declare [tipos de argumento e de + retorno](https://www.php.net/manual/en/migration70.new-features.php) + sempre que possível. +- [Use tipos nas + propriedades](https://wiki.php.net/rfc/typed_properties_v2). +- Use tipagem estrita. Evite tipos mixed e union sempre que possível, exceto + tipos compatíveis como `string|Stringable`. -## Comments +## Comentários -Inline comments are to be avoided unless code couldn't be understood without -them. A good example is a workaround for a bug in a certain PHP version. +Evite comentários inline, a menos que o código não possa ser entendido sem +eles. Um bom exemplo é um contorno para um bug em determinada versão do +PHP. -Method comment is necessary except it adds nothing to what method name and -signature already has. +O comentário de método é necessário, exceto quando não acrescenta nada ao +que o nome e a assinatura do método já dizem. -Class comment should describe the purpose of the class. +O comentário de classe deve descrever o propósito da classe. -See [PHPDoc](014-docs.md#phpdoc). +Veja [PHPDoc](014-docs.md#phpdoc). -## Formatting +## Formatação -### Line length +### Tamanho da linha -The maximum line length is 120 characters. +O tamanho máximo da linha é de 120 caracteres. -When a function or method call exceeds the limit, split arguments into -separate lines: +Quando uma chamada de função ou método excede o limite, separe os argumentos +em linhas distintas: ```php $this->assertSame( @@ -52,11 +55,11 @@ $this->assertSame( ); ``` -### No alignment +### Sem alinhamento -Property, variable and constant value assignments shouldn't be aligned. The -same applies to phpdoc tags. The reason is that aligned statements often -cause larger diff and even conflicts. +Atribuições de valores a propriedades, variáveis e constantes não devem ser +alinhadas. O mesmo vale para as tags phpdoc. O motivo é que instruções +alinhadas costumam gerar diffs maiores e até conflitos. ```php final class X @@ -79,11 +82,11 @@ final class X } ``` -### Chain calls +### Chamadas encadeadas -Chained calls should be formatted for better readability. If it's a long -chain that doesn't fit the line length of 120 characters, then each call -should on a new line: +Chamadas encadeadas devem ser formatadas para melhor legibilidade. Se for +uma cadeia longa que não cabe no limite de 120 caracteres por linha, cada +chamada deve ficar em uma nova linha: ```php $object @@ -94,7 +97,7 @@ $object ->withDeadline($deadline); ``` -If it's a short chain, it's alright for it to be on a single line: +Se for uma cadeia curta, não há problema em deixá-la em uma única linha: ```php $object = $object->withName('test'); @@ -102,44 +105,44 @@ $object = $object->withName('test'); ## Strings -- When no variables involved, use `'Hello!'` -- To get variables into string prefer `"Hello, $username!"` +- Quando não houver variáveis envolvidas, use `'Hello!'` +- Para inserir variáveis na string, prefira `"Hello, $username!"` -## Classes and interfaces +## Classes e interfaces -### Final by default +### Final por padrão -Classes should be `final` by default. +As classes devem ser `final` por padrão. -### Private by default +### Private por padrão -Constants, properties and methods should be private by default. +Constantes, propriedades e métodos devem ser private por padrão. -### Composition over inheritance +### Composição em vez de herança -Prefer [composition to inheritance](../guide/concept/di-container.md). +Prefira [composição a herança](../guide/concept/di-container.md). -### Property, constant and method order +### Ordem de propriedades, constantes e métodos -Order should be the following: +A ordem deve ser a seguinte: -- Constants -- Properties -- Methods +- Constantes +- Propriedades +- Métodos -Within each category, items should be sorted by visibility: +Dentro de cada categoria, os itens devem ser ordenados por visibilidade: - public - protected - private -### Abstract classes +### Classes abstratas -Abstract classes *shouldn't* be prefixed or postfixed with `Abstract`. +Classes abstratas *não devem* ter o prefixo ou sufixo `Abstract`. -#### Immutable methods +#### Métodos imutáveis -Immutable method convention is the following: +A convenção para métodos imutáveis é a seguinte: ```php public function withName(string $name): self @@ -150,13 +153,13 @@ public function withName(string $name): self } ``` -1. Cloned object name is `$new`. -2. Return type is `self`. +1. O nome do objeto clonado é `$new`. +2. O tipo de retorno é `self`. -#### Boolean check methods +#### Métodos de verificação booleana -Methods that are there to check if something is true should be named like -the following: +Métodos que servem para verificar se algo é verdadeiro devem ser nomeados +assim: ```php public function isDeleted(): bool; @@ -164,25 +167,26 @@ public function hasName(): bool; public function canDoIt(): bool; ``` -#### Flags in methods +#### Flags em métodos -Boolean flags in methods are better to be avoided. It's a sign the method -may be doing too much, and there should be two methods instead of one. +É melhor evitar flags booleanas em métodos. Elas são um sinal de que o +método pode estar fazendo coisas demais e de que deveria haver dois métodos +em vez de um. ```php public function login(bool $refreshPage = true): void; ``` -It is better to be two methods: +É melhor que sejam dois métodos: ```php public function login(): void; public function refreshPage(): void; ``` -## Variables +## Variáveis -Add an underscore (`_`) prefix for unused variables. For example: +Adicione o prefixo sublinhado (`_`) em variáveis não usadas. Por exemplo: ```php foreach ($items as $key => $_value) { @@ -192,7 +196,7 @@ foreach ($items as $key => $_value) { ## Imports -Prefer importing classes and functions to using fully qualified names: +Prefira importar classes e funções a usar nomes totalmente qualificados: ```php use Yiisoft\Arrays\ArrayHelper; @@ -203,8 +207,8 @@ use Yiisoft\Validator\Result; use function is_iterable; ``` -## Additional conventions +## Convenções adicionais - [Namespaces](004-namespaces.md) -- [Exceptions](007-exceptions.md) +- [Exceções](007-exceptions.md) - [Interfaces](008-interfaces.md) diff --git a/src/pt-BR/internals/011-error-correction.md b/src/pt-BR/internals/011-error-correction.md index 8e2f2b46..44fc1b4b 100644 --- a/src/pt-BR/internals/011-error-correction.md +++ b/src/pt-BR/internals/011-error-correction.md @@ -1,5 +1,5 @@ -# 011 — Error correction +# 011 — Correção de erros -If it's unambiguous within a class what the developer who incorrectly used -the class meant, it's OK to correct the error. Otherwise, the error MUST -NOT be corrected. +Se, dentro de uma classe, não houver ambiguidade sobre o que o desenvolvedor +que usou a classe de forma incorreta quis dizer, não há problema em corrigir +o erro. Caso contrário, o erro NÃO DEVE ser corrigido. diff --git a/src/pt-BR/internals/012-tests.md b/src/pt-BR/internals/012-tests.md index e09aa6d2..571d8af4 100644 --- a/src/pt-BR/internals/012-tests.md +++ b/src/pt-BR/internals/012-tests.md @@ -1,18 +1,21 @@ -# 012 — Tests +# 012 — Testes -For each package, we're adding unit-tests that are run via -[PHPUnit](https://phpunit.de/). When designing tests, the following -guidelines should be taken into account. +Para cada pacote, adicionamos testes unitários executados com o +[PHPUnit](https://phpunit.de/). Ao projetar os testes, leve em conta as +diretrizes a seguir. -- Test class should be marked as `final` by default. -- `@test` annotation must not be used, prefix methods with `test`. -- The test method name must reflect the purpose of the test. -- "should" must not be used in the test method name. -- If necessary, the test method phpdoc may describe the desired behavior. -- The test must follow AAA: first arrange the necessary preconditions, then - act, then assert expected results. -- There must be one test case per test method that's a single AAA. -- Test must use public API. Private properties or methods shouldn't be - accessed, assumptions on internals of the class tested shouldn't be made. -- Tests shouldn't rely on composer-config-plugin and DI container unless - necessary. +- A classe de teste deve ser marcada como `final` por padrão. +- A anotação `@test` não deve ser usada; use o prefixo `test` nos métodos. +- O nome do método de teste deve refletir o propósito do teste. +- "should" não deve ser usado no nome do método de teste. +- Se necessário, o phpdoc do método de teste pode descrever o comportamento + esperado. +- O teste deve seguir o AAA: primeiro prepare (arrange) as pré-condições + necessárias, depois aja (act) e, por fim, verifique (assert) os resultados + esperados. +- Deve haver um caso de teste por método de teste, ou seja, um único AAA. +- O teste deve usar a API pública. Não se deve acessar propriedades ou + métodos privados, nem fazer suposições sobre os detalhes internos da + classe testada. +- Os testes não devem depender do composer-config-plugin nem do container de + DI, a menos que seja necessário. diff --git a/src/pt-BR/internals/013-code-review.md b/src/pt-BR/internals/013-code-review.md index a363f954..f5192ac1 100644 --- a/src/pt-BR/internals/013-code-review.md +++ b/src/pt-BR/internals/013-code-review.md @@ -1,33 +1,33 @@ # 013 — Code review -Code reviews are essential for the success of the project and are as -important as contributing code. +Code reviews são essenciais para o sucesso do projeto e tão importantes +quanto contribuir com código. -Reviews are handled via GitHub pull requests. When the request is ready for -review, the "status: code review" label is added to it. +As revisões são feitas por meio de pull requests no GitHub. Quando o pull +request está pronto para revisão, recebe o label "status: code review". -[A full list of pull requests that need -review](https://github.com/search?q=org%3Ayiisoft+label%3A"status%3Acode+review"&state=open&type=Issues) -is available at GitHub. +[A lista completa de pull requests que precisam de +revisão](https://github.com/search?q=org%3Ayiisoft+label%3A"status%3Acode+review"&state=open&type=Issues) +está disponível no GitHub. -## Guidelines +## Diretrizes -- Check out the pull request branch, open the project in the IDE, get a big - picture. -- Does the pull request make sense overall? -- Run tests and/or application using code from the pull request. Are these - OK? -- Read all lines of code in the pull request. -- Could it be done simpler? -- Are there security issues? -- Are there performance issues? -- When leaving comments, be polite. -- Avoid code-formatting comments. +- Faça checkout do branch do pull request, abra o projeto na IDE e tenha uma + visão geral. +- O pull request faz sentido como um todo? +- Rode os testes e/ou a aplicação usando o código do pull request. Está tudo + certo? +- Leia todas as linhas de código do pull request. +- Daria para fazer de forma mais simples? +- Há problemas de segurança? +- Há problemas de desempenho? +- Ao deixar comentários, seja educado. +- Evite comentários sobre formatação de código. -## Mandatory parts +## Itens obrigatórios -- [ ] Tests that fail without code and pass with code. +- [ ] Testes que falham sem o código e passam com ele. - [ ] Type hints. - [ ] `declare(strict_types=1)`. -- [ ] Documentation: phpdoc, yiisoft/docs. -- [ ] Changelog entry (if package is stable). +- [ ] Documentação: phpdoc, yiisoft/docs. +- [ ] Entrada no changelog (se o pacote for estável). diff --git a/src/pt-BR/internals/014-docs.md b/src/pt-BR/internals/014-docs.md index 76c3ea24..4c65146b 100644 --- a/src/pt-BR/internals/014-docs.md +++ b/src/pt-BR/internals/014-docs.md @@ -1,94 +1,94 @@ -# 014 — Documentation +# 014 — Documentação -Documentation is one of the most important parts of Yii. +A documentação é uma das partes mais importantes do Yii. -## Package documentation +## Documentação de pacotes -Documentation for a package could either be in `README.md` or -`docs/{language}/{type}` where `{language}` is a language code and `{type}` -could be "guide," "cookbook" or something else. Usually `docs` is there if -the package usage or configuration isn't trivial or there's a need for -translation. +A documentação de um pacote pode ficar no `README.md` ou em +`docs/{language}/{type}`, onde `{language}` é um código de idioma e `{type}` +pode ser "guide", "cookbook" ou outra coisa. Normalmente, `docs` existe +quando o uso ou a configuração do pacote não é trivial ou quando há +necessidade de tradução. -Some indicators that it's time to create `docs`: +Alguns indícios de que é hora de criar `docs`: -1. There is a need for translation. -2. Many topics exist. Each of these is big by itself. +1. Há necessidade de tradução. +2. Existem muitos tópicos, e cada um deles é grande por si só. -If the total length of readme is less than about 200 lines, it's fine to -keep documentation in the readme. +Se o tamanho total do readme for menor que cerca de 200 linhas, não há +problema em manter a documentação no readme. -## Definitive guide +## Guia definitivo -The definitive guide, +O guia definitivo, [yiisoft/docs/guide](https://github.com/yiisoft/docs/tree/master/guide/en) -aims at covering usage of packages as a whole framework. Unlike package -documentation, it isn't focused on a single package but is covering certain -use-cases. +tem como objetivo cobrir o uso dos pacotes como um framework +completo. Diferente da documentação dos pacotes, ele não se concentra em um +único pacote, e sim em determinados casos de uso. -The guide should follow [Microsoft style -guide](https://learn.microsoft.com/en-us/style-guide/welcome/). +O guia deve seguir o [guia de estilo da +Microsoft](https://learn.microsoft.com/en-us/style-guide/welcome/). -### Translation +### Tradução -The definitive guide uses [po4a](https://github.com/mquinson/po4a) in GitHub Action for translations. +O guia definitivo usa o [po4a](https://github.com/mquinson/po4a) em uma GitHub Action para as traduções. -Translation algorithm: +Algoritmo de tradução: -- Install an application for working with `.po` translation files. For - example, [Poedit](https://poedit.net/), +- Instale uma aplicação para trabalhar com arquivos de tradução `.po`. Por + exemplo, [Poedit](https://poedit.net/), [Lokalize](https://apps.kde.org/ru/lokalize/), - [Gtranslator](https://wiki.gnome.org/Apps/Gtranslator) or another. -- Find file what you want to translate in `_translations/guide/{lang}`. Note - that if the source file is in a subfolder, the subfolder name is appended - to the file name and separated by an underscore, for example, for - translating `guide/en/concept/aliases.md` file find - `_translations/guide/{lang}/concept_aliases.md.po` file. -- Open the file with the `.po` extension in `Poedit` from the folder with - the desired localization, for example - `_translations/guide/ru/intro_what-is-yii.md.po`. If there is no - localization yet, create an issue. -- Translate necessary strings and push the changes -- Open a pull request to the main repository + [Gtranslator](https://wiki.gnome.org/Apps/Gtranslator) ou outra. +- Encontre o arquivo que você quer traduzir em + `_translations/guide/{lang}`. Observe que, se o arquivo original estiver + em uma subpasta, o nome da subpasta é adicionado ao nome do arquivo, + separado por um sublinhado. Por exemplo, para traduzir o arquivo + `guide/en/concept/aliases.md`, procure o arquivo + `_translations/guide/{lang}/concept_aliases.md.po`. +- Abra o arquivo com extensão `.po` no `Poedit` a partir da pasta com a + localização desejada, por exemplo + `_translations/guide/ru/intro_what-is-yii.md.po`. Se ainda não existir a + localização, crie uma issue. +- Traduza as strings necessárias e faça push das alterações +- Abra um pull request para o repositório principal > [!CAUTION] -> Do not change the translation in files in `/guide/{lang}` manually. +> Não altere manualmente a tradução nos arquivos em `/guide/{lang}`. -If you have changed English and want to update translations: +Se você alterou o texto em inglês e quer atualizar as traduções: -- Open a pull request to the main repository -- Pull updated branch after successful completion of workflow `Update docs - translation` in GitHub Action -- Update translation in `.po` files by `Poedit` -- Push changes +- Abra um pull request para o repositório principal +- Faça pull do branch atualizado depois que o workflow `Update docs + translation` da GitHub Action terminar com sucesso +- Atualize a tradução nos arquivos `.po` com o `Poedit` +- Faça push das alterações -## Blocks +## Blocos -Blocks are in the [GitHub Alerts -format](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts): +Os blocos usam o [formato GitHub +Alerts](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts): ``` > [!NOTE] -> Useful information that users should know, even when skimming content. +> Informação útil que os usuários devem saber, mesmo lendo o conteúdo por alto. > [!TIP] -> Helpful advice for doing things better or more easily. +> Conselho útil para fazer as coisas melhor ou com mais facilidade. > [!IMPORTANT] -> Key information users need to know to achieve their goal. +> Informação essencial que os usuários precisam saber para alcançar o objetivo. > [!WARNING] -> Urgent info that needs immediate user attention to avoid problems. +> Informação urgente que exige atenção imediata do usuário para evitar problemas. > [!CAUTION] -> Advises about risks or negative outcomes of certain actions. +> Alerta sobre riscos ou consequências negativas de certas ações. ``` -When translating documentation, these Block indicators should not be -translated. Keeps them intact as they are and only translate the block -content. For translating the label for the block, each guide translation -should have a `blocktypes.json` file containing the translations. The -following shows an example for German: +Ao traduzir a documentação, esses indicadores de bloco não devem ser +traduzidos. Mantenha-os intactos e traduza apenas o conteúdo do bloco. +Para traduzir o rótulo do bloco, cada tradução do guia deve ter um arquivo +`blocktypes.json` com as traduções. Veja a seguir um exemplo para o alemão: ```json { @@ -102,8 +102,8 @@ following shows an example for German: ## PHPDoc -PHPDoc mustn't be added if it doesn't add anything to what it describes. The -following is a bad example: +Não se deve adicionar PHPDoc se ele não acrescentar nada ao que +descreve. Este é um mau exemplo: ```php use Psr\Log\LoggerInterface; @@ -137,15 +137,15 @@ final class MyService extends MyServiceBase } ``` -PHPDoc, if present, should describe the purpose of the element it's added -for. +O PHPDoc, quando presente, deve descrever o propósito do elemento ao qual +foi adicionado. -Skip default values in PHPDoc when PHP already shows them in a parameter -default, promoted property default, or property initializer. The declaration -is the source of truth, and repeating the value in text can become outdated -after code changes. +Omita valores padrão no PHPDoc quando o PHP já os mostra no valor padrão de +um parâmetro, no valor padrão de uma propriedade promovida ou no +inicializador de uma propriedade. A declaração é a fonte da verdade, e +repetir o valor no texto pode ficar desatualizado após mudanças no código. -Example of incorrect code: +Exemplo de código incorreto: ```php /** @@ -157,7 +157,7 @@ public function __construct( } ``` -Example of a valid code: +Exemplo de código válido: ```php /** @@ -169,11 +169,11 @@ public function __construct( } ``` -The `@see` tags must explicitly refer to class methods, properties, and -constants. This is necessary for the correct display of links in IDEs, as -well as for the correct display of links in API documentation. +As tags `@see` devem referenciar explicitamente métodos, propriedades e +constantes da classe. Isso é necessário para que os links sejam exibidos +corretamente nas IDEs e na documentação da API. -Example of incorrect code: +Exemplo de código incorreto: ```php /** @@ -189,7 +189,7 @@ final class Example } ``` -Example of a valid code: +Exemplo de código válido: ```php /** @@ -205,19 +205,18 @@ final class Example } ``` -## Readme checklist +## Checklist do readme -Each package readme should be placed into `README.md` and contain the -following: +O readme de cada pacote deve ficar em `README.md` e conter o seguinte: - [ ] Logo. -- [ ] Short description of the package. What does it do? -- [ ] Quality badges (build, code coverage). -- [ ] Screenshot (if applicable). -- [ ] Requirements. -- [ ] Installation. Usually `composer require`. -- [ ] Getting started. One or two common usage examples are demonstrated. -- [ ] Configuration. -- [ ] Contributing. It should contain a link to guidelines. -- [ ] Running tests. -- [ ] License. +- [ ] Descrição curta do pacote. O que ele faz? +- [ ] Badges de qualidade (build, cobertura de código). +- [ ] Captura de tela (se aplicável). +- [ ] Requisitos. +- [ ] Instalação. Normalmente `composer require`. +- [ ] Primeiros passos. Um ou dois exemplos de uso comuns. +- [ ] Configuração. +- [ ] Contribuindo. Deve conter um link para as diretrizes. +- [ ] Executando os testes. +- [ ] Licença. diff --git a/src/pt-BR/internals/015-phpstorm.md b/src/pt-BR/internals/015-phpstorm.md index 7995ffc6..e1150af5 100644 --- a/src/pt-BR/internals/015-phpstorm.md +++ b/src/pt-BR/internals/015-phpstorm.md @@ -1,29 +1,29 @@ -# 015 — PhpStorm metadata and attributes +# 015 — Metadados e atributos do PhpStorm -## PhpStorm metadata +## Metadados do PhpStorm -[PhpStorm -metadata](https://www.jetbrains.com/help/phpstorm/ide-advanced-metadata.html) -helps the IDE to understand code better in cases when regular types and -PHPDoc tags don't help. +Os [metadados do +PhpStorm](https://www.jetbrains.com/help/phpstorm/ide-advanced-metadata.html) +ajudam a IDE a entender melhor o código nos casos em que os tipos comuns e +as tags PHPDoc não ajudam. -We use the following set of coding styles for metadata. +Usamos o seguinte conjunto de convenções de estilo para os metadados. -### Metadata location +### Localização dos metadados -- Metadata should be placed in `/.phpstorm.meta.php` directory. -- Configuration should be split into files. Each file should be named after - a class it configures. +- Os metadados devem ficar no diretório `/.phpstorm.meta.php`. +- A configuração deve ser dividida em arquivos. Cada arquivo deve ter o nome + da classe que configura. > [!NOTE] -> There is no support for subdirectories in PhpStorm yet. +> O PhpStorm ainda não suporta subdiretórios. -### Constants +### Constantes -All constant dictionaries should be named as `{Class FQN}::{Group -name}`. Group name should be short and written in capital letters. Use -underscore as a word separator that's `\Yiisoft\Http\Status::STATUSES`. For -example: +Todos os dicionários de constantes devem ser nomeados como `{Class +FQN}::{Group name}`. O nome do grupo deve ser curto e escrito em letras +maiúsculas. Use sublinhado como separador de palavras, por exemplo +`\Yiisoft\Http\Status::STATUSES`. Por exemplo: ```php expectedReturnValues( @@ -43,22 +43,22 @@ registerArgumentsSet( ); ``` -## PhpStorm attributes +## Atributos do PhpStorm -[PhpStorm attributes](https://github.com/JetBrains/phpstorm-attributes) CAN -be used in code, but package `jetbrains/phpstorm-attributes` MUST be added -as a dev dependency: +Os [atributos do PhpStorm](https://github.com/JetBrains/phpstorm-attributes) +PODEM ser usados no código, mas o pacote `jetbrains/phpstorm-attributes` +DEVE ser adicionado como dependência de desenvolvimento: ```shell composer require --dev jetbrains/phpstorm-attributes ``` -### Using with ComposerRequireChecker +### Usando com o ComposerRequireChecker -When +Quando o [ComposerRequireChecker](https://github.com/maglnet/ComposerRequireChecker) -is also used within the same package, add involved attributes' class names -to whitelist in config. For example: +também é usado no mesmo pacote, adicione os nomes das classes dos atributos +envolvidos à whitelist na configuração. Por exemplo: ```json { diff --git a/src/pt-BR/internals/016-security-workflow.md b/src/pt-BR/internals/016-security-workflow.md index 2a09d5b7..d7c6e29f 100644 --- a/src/pt-BR/internals/016-security-workflow.md +++ b/src/pt-BR/internals/016-security-workflow.md @@ -1,68 +1,68 @@ -# 016 — Security workflow +# 016 — Fluxo de segurança -Security issues are typically sent via [a security -form](https://www.yiiframework.com/security). +Problemas de segurança normalmente são enviados pelo [formulário de +segurança](https://www.yiiframework.com/security). -If an issue is reported directly to a public page such as a repository issue or a forum topic, get the message -and delete the issue. Say thanks to the reporter and point to the security form for next time. +Se um problema for relatado diretamente em uma página pública, como uma issue do repositório ou um tópico do fórum, copie a mensagem +e apague a issue. Agradeça a quem relatou e indique o formulário de segurança para a próxima vez. ```mermaid flowchart TD - form[Security form report] --> verify[Verify issue] - public[Public report] --> remove[Save details and delete public issue] - remove --> redirect[Point reporter to the security form] + form[Relato pelo formulário de segurança] --> verify[Verificar o problema] + public[Relato público] --> remove[Salvar os detalhes e apagar a issue pública] + remove --> redirect[Indicar o formulário de segurança a quem relatou] redirect --> verify - verify -->|needs details| requestInfo[Request more information] + verify -->|precisa de detalhes| requestInfo[Pedir mais informações] requestInfo --> verify - verify -->|valid| advisory[Create draft security advisory] - advisory --> severity[Set CVSS severity] - severity --> credit[Ask about reporter credit] - credit --> cve[Request CVE number] - cve --> patch[Prepare patch pull request] - patch --> wait[Wait for CVE allocation] + verify -->|válido| advisory[Criar rascunho de security advisory] + advisory --> severity[Definir a severidade CVSS] + severity --> credit[Perguntar sobre o crédito a quem relatou] + credit --> cve[Solicitar número CVE] + cve --> patch[Preparar pull request com o patch] + patch --> wait[Aguardar a atribuição do CVE] wait --> release[Release] - release --> publish[Publish advisory and submit FriendsOfPHP entry] + release --> publish[Publicar o advisory e enviar entrada ao FriendsOfPHP] ``` -## Verify +## Verificar -Verify that the issue is valid. Request more information if needed. +Verifique se o problema é válido. Peça mais informações, se necessário. -## Add security advisory +## Adicionar security advisory -Create a draft GitHub security advisory. +Crie um rascunho de security advisory no GitHub. -### Find out severity +### Descobrir a severidade -1. Get CVSS score using [NVD - calculator](https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator). -2. Choose severity based on the [rating - scale](https://www.first.org/cvss/specification-document#Qualitative-Severity-Rating-Scale). +1. Obtenha a pontuação CVSS usando a [calculadora do + NVD](https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator). +2. Escolha a severidade com base na [escala de + classificação](https://www.first.org/cvss/specification-document#Qualitative-Severity-Rating-Scale). -### Give credit to the reporter +### Dar crédito a quem relatou -Ask the reporter if he wants a credit for finding the issue. If so, point to -his GitHub account. +Pergunte a quem relatou se deseja receber crédito por ter encontrado o +problema. Se sim, indique a conta dessa pessoa no GitHub. -## Request a CVE number +## Solicitar um número CVE -When you're ready, request a CVE. +Quando estiver pronto, solicite um CVE. -## Prepare a patch +## Preparar um patch -Prepare a pull request fixing the issue. GitHub allows doing it in a private -fork. +Prepare um pull request que corrija o problema. O GitHub permite fazer isso +em um fork privado. -## Wait till the CVE number is allocated +## Aguardar a atribuição do número CVE -It usually takes several days. +Normalmente leva alguns dias. ## Release -- Merge the patch pull request right before tagging the next package - release. -- Publish security advisory. -- Add CVE to +- Faça o merge do pull request com o patch logo antes de criar a tag do + próximo release do pacote. +- Publique o security advisory. +- Adicione o CVE em [FriendsOfPHP/security-advisories](https://github.com/FriendsOfPHP/security-advisories). - See [#488](https://github.com/FriendsOfPHP/security-advisories/pull/488) - as an example. + Veja [#488](https://github.com/FriendsOfPHP/security-advisories/pull/488) + como exemplo. diff --git a/src/pt-BR/internals/017-tags.md b/src/pt-BR/internals/017-tags.md index 637e1805..1d4b5353 100644 --- a/src/pt-BR/internals/017-tags.md +++ b/src/pt-BR/internals/017-tags.md @@ -1,43 +1,43 @@ # 017 - Tags -Unlike regular classes, tags are used in view templates, so syntax is -important. It should be both easy to write, easy to read and not too -verbose because similar constructs are meant to be used over and over again. +Diferente das classes comuns, as tags são usadas em templates de view, então +a sintaxe é importante. Ela deve ser fácil de escrever, fácil de ler e não +muito verbosa, porque construções parecidas são usadas repetidas vezes. -## Class names +## Nomes de classes -- Tags aren't postfixed or prefixed unless it's an abstract base class. -- If the tag represents a specification, use a name used in the - specification. +- As tags não têm prefixo nem sufixo, a menos que sejam uma classe base + abstrata. +- Se a tag representa uma especificação, use o nome usado na especificação. -## Inheritance +## Herança -Inheritance is allowed with some restrictions: +A herança é permitida com algumas restrições: -- If a class isn't abstract, it should be final. -- Hierarchy should be kept as linear as possible. +- Se uma classe não é abstrata, ela deve ser final. +- A hierarquia deve ser mantida o mais linear possível. -## Immutability +## Imutabilidade -Tags should: +As tags devem: -- Have no state. -- Be immutable. Every method that modifies a setting returns a clone with - the setting changed. -- Be free of side effects. Many calls of the same method with the same - argument should give the same result. +- Não ter estado. +- Ser imutáveis. Todo método que modifica uma configuração retorna um clone + com a configuração alterada. +- Não ter efeitos colaterais. Várias chamadas do mesmo método com o mesmo + argumento devem dar o mesmo resultado. -## Methods +## Métodos -### Names +### Nomes -- Unlike other classes, methods that return a clone of the object with some - properties modified aren't prefixed. -- Keep method names as short as possible but don't hurt readability. -- If the tag represents a specification, use a name used in the - specification. +- Diferente de outras classes, os métodos que retornam um clone do objeto + com algumas propriedades modificadas não têm prefixo. +- Mantenha os nomes dos métodos o mais curtos possível, sem prejudicar a + legibilidade. +- Se a tag representa uma especificação, use o nome usado na especificação. -### Boolean flags +### Flags booleanas -The method that corresponds to the boolean attribute should be named after -the attribute and accept a boolean flag argument. +O método que corresponde a um atributo booleano deve ter o nome do atributo +e aceitar um argumento booleano como flag. diff --git a/src/pt-BR/internals/018-widgets.md b/src/pt-BR/internals/018-widgets.md index 4fb6bec2..0131e1bc 100644 --- a/src/pt-BR/internals/018-widgets.md +++ b/src/pt-BR/internals/018-widgets.md @@ -1,36 +1,38 @@ # 018 - Widgets -Unlike regular classes, widgets are used in view templates, so syntax is -important. It should be both easy to write, easy to read and not too -verbose because similar constructs are meant to be used over and over again. +Diferente das classes comuns, os widgets são usados em templates de view, +então a sintaxe é importante. Ela deve ser fácil de escrever, fácil de ler +e não muito verbosa, porque construções parecidas são usadas repetidas +vezes. -## Class names +## Nomes de classes -Widgets aren't postfixed or prefixed. +Os widgets não têm prefixo nem sufixo. -## Inheritance +## Herança -Inheritance is allowed with some restrictions: +A herança é permitida com algumas restrições: -- If a class isn't abstract, it should be final. -- Hierarchy should be kept as linear as possible. +- Se uma classe não é abstrata, ela deve ser final. +- A hierarquia deve ser mantida o mais linear possível. -## Immutability +## Imutabilidade -Widgets should: +Os widgets devem: -- Have no state. -- Be immutable. +- Não ter estado. +- Ser imutáveis. -## Methods +## Métodos -### Names +### Nomes -- Unlike other classes, methods that return a clone of the object with some - properties modified aren't prefixed. -- Keep method names as short as possible but don't hurt readability. +- Diferente de outras classes, os métodos que retornam um clone do objeto + com algumas propriedades modificadas não têm prefixo. +- Mantenha os nomes dos métodos o mais curtos possível, sem prejudicar a + legibilidade. -### Boolean flags +### Flags booleanas -The method that corresponds to the boolean attribute should be named after -the attribute and accept a boolean flag argument. +O método que corresponde a um atributo booleano deve ter o nome do atributo +e aceitar um argumento booleano como flag. diff --git a/src/pt-BR/internals/019-view-code-style.md b/src/pt-BR/internals/019-view-code-style.md index c5a19173..f04e19a4 100644 --- a/src/pt-BR/internals/019-view-code-style.md +++ b/src/pt-BR/internals/019-view-code-style.md @@ -1,13 +1,13 @@ -# 019 — View code style +# 019 — Estilo de código das views -The PHP code in the view files shouldn't be complicated. The code must -contain the logic responsible for formatting the data, but not the logic for -requesting this data. +O código PHP nos arquivos de view não deve ser complicado. O código deve +conter a lógica responsável por formatar os dados, mas não a lógica para +buscar esses dados. -## Heading +## Cabeçalho -View file heading is used to place phpdoc describing variables available and -to import classes: +O cabeçalho do arquivo de view é usado para colocar o phpdoc que descreve as +variáveis disponíveis e para importar classes: ```php @@ -34,13 +34,13 @@ preferred: ## Short echo -Short echo is preferred: +Prefira o short echo: ```php ``` -## Class methods +## Métodos de classe -All class methods used in view files must be public regardless if the view -is rendered by the class itself. +Todos os métodos de classe usados em arquivos de view devem ser públicos, +mesmo que a view seja renderizada pela própria classe. diff --git a/src/pt-BR/internals/020-package-release.md b/src/pt-BR/internals/020-package-release.md index 9e98546d..f5d5186b 100644 --- a/src/pt-BR/internals/020-package-release.md +++ b/src/pt-BR/internals/020-package-release.md @@ -1,56 +1,58 @@ -# 020 — Package release +# 020 — Release de pacotes -## Criteria +## Critérios -- No critical issues. -- Public API changes aren't likely. Some time passed w/o issues reported - that may require API changes. -- All dependencies are stable. -- Close to 100% test coverage with, ideally, a 100% MSI score. -- README is alright. -- Everything is type-hinted unless special cases. -- Psalm analysis passes on at least level 2. -- phpdoc is alright. -- Public API is alright. +- Nenhuma issue crítica. +- Mudanças na API pública são improváveis. Já passou algum tempo sem issues + relatadas que possam exigir mudanças na API. +- Todas as dependências são estáveis. +- Cobertura de testes próxima de 100% e, idealmente, score MSI de 100%. +- O README está em ordem. +- Tudo tem type hints, exceto em casos especiais. +- A análise do Psalm passa pelo menos no nível 2. +- O phpdoc está em ordem. +- A API pública está em ordem. -## Release branch policy +## Política de branches de release -Use `master` for all regular releases. +Use `master` para todos os releases regulares. -Create a separate branch only when releasing a new version for a previous -major version. In this case, create the branch from the latest tag in that -previous major version line and apply only the changes needed for the +Crie um branch separado apenas ao lançar uma nova versão de uma versão major +anterior. Nesse caso, crie o branch a partir da tag mais recente dessa linha +de versão major anterior e aplique apenas as mudanças necessárias para o release. -## Release instruction +## Instruções de release -Release a package via [Yii Development Tool](005-development-tool.md). +Faça o release de um pacote com a [Ferramenta de desenvolvimento do +Yii](005-development-tool.md). -1. Check that you can sign commits locally (see -[Signing commits](https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits)). +1. Verifique se você consegue assinar commits localmente (veja +[Assinando commits](https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits)). -2. For regular releases, pull last changes from the `master` branch: +2. Para releases regulares, faça pull das últimas mudanças do branch + `master`: ```shell ./yii-dev git/checkout master package-name ./yii-dev git/pull package-name ``` -For previous major version releases, use the branch created according to the -release branch policy instead of `master`. +Para releases de versões major anteriores, use o branch criado de acordo com +a política de branches de release, em vez de `master`. -3. Check the package for compliance with the criteria above. +3. Verifique se o pacote atende aos critérios acima. -4. Run `release/make` command: +4. Execute o comando `release/make`: ```shell ./yii-dev release/make package-name ``` -5. Select the version type (major, minor or patch). +5. Selecione o tipo de versão (major, minor ou patch). -6. On the question "Push commits and tags, and release on GitHub?" check a - diff. If the diff is alright, answer "yes." +6. Na pergunta "Push commits and tags, and release on GitHub?", confira o + diff. Se o diff estiver correto, responda "yes". -7. For major and minor releases, add a record with release notes on [Yii - Framework News](https://www.yiiframework.com/news). +7. Para releases major e minor, adicione um registro com as notas de release + em [Yii Framework News](https://www.yiiframework.com/news). diff --git a/src/pt-BR/internals/021-changelog-upgrade.md b/src/pt-BR/internals/021-changelog-upgrade.md index ee291e73..1f9dc5d1 100644 --- a/src/pt-BR/internals/021-changelog-upgrade.md +++ b/src/pt-BR/internals/021-changelog-upgrade.md @@ -1,11 +1,12 @@ -# 021 — Changelog and upgrade +# 021 — Changelog e upgrade -For all released packages, we've a detailed changelog and upgrade guide. +Para todos os pacotes lançados, mantemos um changelog detalhado e um guia de +upgrade. ## Changelog -Changelog is written for each version released. The file name is -`CHANGELOG.md`. The format is the following: +O changelog é escrito para cada versão lançada. O nome do arquivo é +`CHANGELOG.md`. O formato é o seguinte: ```markdown # My package Change Log @@ -23,29 +24,29 @@ Changelog is written for each version released. The file name is - Initial release. ``` -There "My package" is the name of the package, `1.0.1` is the version -released followed by release date. For each version, there are a number of -lines listing the changes. "Bug" refers to a change type. The following -types are used: +Ali, "My package" é o nome do pacote, `1.0.1` é a versão lançada, seguida da +data de release. Para cada versão, há algumas linhas listando as mudanças. +"Bug" indica o tipo da mudança. São usados os seguintes tipos: -- New — New features. -- Chg — General changes. -- Enh — Existing feature enhancements. -- Bug — Bug fixes. +- New — Novas funcionalidades. +- Chg — Mudanças gerais. +- Enh — Melhorias em funcionalidades existentes. +- Bug — Correções de bugs. -In the changelog file lines should be ordered as New, Chg, Enh, Bug. +No arquivo de changelog, as linhas devem ser ordenadas como New, Chg, Enh, +Bug. -"#42" above is the number of issue or pull requests corresponding to the -change. "author1" is the GitHub nickname of the code author. "author2" is an -additional author. An author's nickname MUST be prefixed with `@`. +"#42" acima é o número da issue ou do pull request correspondente à +mudança. "author1" é o nickname no GitHub do autor do código. "author2" é um +autor adicional. O nickname de um autor DEVE ter o prefixo `@`. ## Upgrade -Upgrade guide is created when there is a new major version that isn't -compatible with the previous one. It describes steps necessary to upgrade -application code. +O guia de upgrade é criado quando há uma nova versão major que não é +compatível com a anterior. Ele descreve os passos necessários para fazer o +upgrade do código da aplicação. -The file name is `UPGRADE.md`. The format is the following: +O nome do arquivo é `UPGRADE.md`. O formato é o seguinte: ```markdown # Upgrading Instructions for my package diff --git a/src/pt-BR/internals/022-config-groups.md b/src/pt-BR/internals/022-config-groups.md index 8193bf82..c7a29eb7 100644 --- a/src/pt-BR/internals/022-config-groups.md +++ b/src/pt-BR/internals/022-config-groups.md @@ -1,73 +1,75 @@ -# 022 — Config groups +# 022 — Grupos de configuração -This document defines naming convention for the framework groups used with -[yiisoft/config](https://github.com/yiisoft/config). Note that this isn't a -naming convention for config files. These could be anything and are mapped -to group names via `composer.json`. +Este documento define a convenção de nomes para os grupos do framework +usados com o [yiisoft/config](https://github.com/yiisoft/config). Observe +que esta não é uma convenção de nomes para arquivos de configuração. Eles +podem ter qualquer nome e são mapeados para os nomes de grupo via +`composer.json`. -## Config group name postfixes +## Sufixos dos nomes de grupos de configuração -- "web" postfix applies to web only that's classic server HTML generation, - REST, RPC, etc. -- "console" postfix applies to console -- If there's no postfix, it's "common" and applies to both web and console -- "web" and "console" may override what's defined in "common" +- O sufixo "web" se aplica apenas à web, ou seja, geração clássica de HTML + no servidor, REST, RPC etc. +- O sufixo "console" se aplica ao console +- Se não houver sufixo, o grupo é "common" e se aplica tanto à web quanto ao + console +- "web" e "console" podem sobrescrever o que está definido em "common" -## Parameters +## Parâmetros -Application config parameters that are used in all configs. +Parâmetros de configuração da aplicação usados em todas as configurações. -- `params` — common parameters -- `params-web` — web application parameters -- `params-console` — console application parameters +- `params` — parâmetros comuns +- `params-web` — parâmetros da aplicação web +- `params-console` — parâmetros da aplicação de console ## Container -Configuration for [yiisoft/di](https://github.com/yiisoft/di). +Configuração do [yiisoft/di](https://github.com/yiisoft/di). -### Definitions +### Definições -- `di` — common container definitions -- `di-web` — web container definitions -- `di-console` — console container definitions +- `di` — definições comuns do container +- `di-web` — definições do container para web +- `di-console` — definições do container para console ### Providers -- `di-providers` — common container providers -- `di-providers-web` — web container providers -- `di-providers-console` — console container providers +- `di-providers` — providers comuns do container +- `di-providers-web` — providers do container para web +- `di-providers-console` — providers do container para console ### Delegates -- `di-delegates` — common container delegates -- `di-delegates-web` — web container delegates -- `di-delegates-console` — console container delegates +- `di-delegates` — delegates comuns do container +- `di-delegates-web` — delegates do container para web +- `di-delegates-console` — delegates do container para console ### Tags -- `di-tags` — common container tags -- `di-tags-web` — web container tags -- `di-tags-console` — console container tags +- `di-tags` — tags comuns do container +- `di-tags-web` — tags do container para web +- `di-tags-console` — tags do container para console -## Events +## Eventos -Configuration for [yiisoft/yii-event](https://github.com/yiisoft/yii-event). +Configuração do [yiisoft/yii-event](https://github.com/yiisoft/yii-event). -- `events` — common events -- `events-web` — web events -- `events-console` — console events +- `events` — eventos comuns +- `events-web` — eventos da web +- `events-console` — eventos do console ## Bootstrap -Application bootstrapping for +Bootstrap da aplicação para o [yiisoft/yii-runner](https://github.com/yiisoft/yii-runner). -- `bootstrap` — common bootstrap -- `bootstrap-web` — web bootstrap -- `bootstrap-console` — console bootstrap +- `bootstrap` — bootstrap comum +- `bootstrap-web` — bootstrap da web +- `bootstrap-console` — bootstrap do console -## Others +## Outros -- `routes` — [yiisoft/router](https://github.com/yiisoft/router) routes -- `widgets` — [yiisoft/widget](https://github.com/yiisoft/widget) default - widgets configuration +- `routes` — rotas do [yiisoft/router](https://github.com/yiisoft/router) +- `widgets` — configuração padrão de widgets do + [yiisoft/widget](https://github.com/yiisoft/widget) diff --git a/src/pt-BR/internals/023-github-actions.md b/src/pt-BR/internals/023-github-actions.md index 2376c288..62b0fc63 100644 --- a/src/pt-BR/internals/023-github-actions.md +++ b/src/pt-BR/internals/023-github-actions.md @@ -1,13 +1,13 @@ # 023 — GitHub Actions -This document defines naming convention for the GitHub actions configuration -files. +Este documento define a convenção de nomes para os arquivos de configuração +das GitHub Actions. -## Inputs and Outputs +## Inputs e outputs -Input names and output names must use kebab-case format. +Os nomes de inputs e de outputs devem usar o formato kebab-case. -For example: +Por exemplo: ```yaml inputs: @@ -15,12 +15,12 @@ inputs: description: 'My input' ``` -## Secrets and Environment Variables +## Secrets e variáveis de ambiente -Secret names and environment variable names must use SCREAMING_SNAKE_CASE -format. +Os nomes de secrets e de variáveis de ambiente devem usar o formato +SCREAMING_SNAKE_CASE. -For example: +Por exemplo: ```yaml secrets: From a60741d394fac1d4e65266c3fc445c213d890c3a Mon Sep 17 00:00:00 2001 From: Yuri Neves Date: Fri, 23 Oct 2026 14:18:15 -0300 Subject: [PATCH 09/11] Align pt-BR menu titles with translated pages --- src/.vitepress/config.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/.vitepress/config.js b/src/.vitepress/config.js index a7759b93..f80cfd26 100644 --- a/src/.vitepress/config.js +++ b/src/.vitepress/config.js @@ -1339,8 +1339,8 @@ export default { text: 'Introdução', items: [ {text: 'Sobre o Yii', link: '/pt-BR/guide/intro/what-is-yii'}, - {text: 'Atualizando a partir da versão 1.1', link: '/pt-BR/guide/intro/upgrade-from-v1'}, - {text: 'Atualizando a partir da versão 2', link: '/pt-BR/guide/intro/upgrade-from-v2'} + {text: 'Migrando da versão 1.1', link: '/pt-BR/guide/intro/upgrade-from-v1'}, + {text: 'Migrando da versão 2.0', link: '/pt-BR/guide/intro/upgrade-from-v2'} ] }, { @@ -1438,7 +1438,7 @@ export default { {text: 'Assets', link: '/pt-BR/guide/views/asset'}, {text: 'Scripts, estilos e meta tags', link: '/pt-BR/guide/views/script-style-meta'}, {text: 'Template engines', link: '/pt-BR/guide/views/template-engines'}, - {text: 'Injeções em views', link: '/pt-BR/guide/views/view-injections'}, + {text: 'Injeções de view', link: '/pt-BR/guide/views/view-injections'}, {text: 'Widgets', link: '/pt-BR/guide/views/widget'} ] }, @@ -1458,7 +1458,7 @@ export default { items: [ {text: 'Aplicações de console', link: '/pt-BR/guide/tutorial/console-applications'}, {text: 'Envio de e-mails', link: '/pt-BR/guide/tutorial/mailing'}, - {text: 'Otimização de desempenho', link: '/pt-BR/guide/tutorial/performance-tuning'}, + {text: 'Ajuste de desempenho', link: '/pt-BR/guide/tutorial/performance-tuning'}, {text: 'Usando com event loop', link: '/pt-BR/guide/tutorial/using-with-event-loop'}, {text: 'Usando o Yii com FrankenPHP', link: '/pt-BR/guide/tutorial/using-yii-with-frankenphp'}, {text: 'Usando o Yii com Rapira', link: '/pt-BR/guide/tutorial/using-yii-with-rapira'}, From 831ac4d54cd0cf9c9d982e981c7dc7c71e5d461e Mon Sep 17 00:00:00 2001 From: Yuri Neves Date: Fri, 23 Oct 2026 15:06:30 -0300 Subject: [PATCH 10/11] Fix dead links reported by the link checker --- .markdown-link-check.json | 17 +++ .../es/cookbook_organizing-code_service.md.po | 8 +- _translations/po/es/guide_caching_data.md.po | 4 +- .../po/es/guide_caching_overview.md.po | 6 +- _translations/po/es/guide_glossary.md.po | 2 +- .../po/es/guide_security_best-practices.md.po | 13 +-- _translations/po/es/guide_start_hello.md.po | 6 +- .../po/es/guide_structure_overview.md.po | 7 +- _translations/po/es/internals_014-docs.md.po | 2 +- .../id/cookbook_organizing-code_service.md.po | 8 +- _translations/po/id/guide_caching_data.md.po | 8 +- .../po/id/guide_caching_overview.md.po | 12 +- _translations/po/id/guide_glossary.md.po | 2 +- .../po/id/guide_security_best-practices.md.po | 13 +-- _translations/po/id/guide_start_hello.md.po | 6 +- .../po/id/guide_structure_overview.md.po | 7 +- _translations/po/id/internals_014-docs.md.po | 2 +- .../it/cookbook_organizing-code_service.md.po | 8 +- _translations/po/it/guide_caching_data.md.po | 4 +- .../po/it/guide_caching_overview.md.po | 6 +- _translations/po/it/guide_glossary.md.po | 2 +- .../po/it/guide_security_best-practices.md.po | 13 +-- _translations/po/it/guide_start_hello.md.po | 8 +- .../po/it/guide_structure_overview.md.po | 7 +- _translations/po/it/internals_014-docs.md.po | 2 +- .../cookbook_organizing-code_service.md.po | 4 +- .../po/pt-BR/guide_caching_data.md.po | 8 +- .../po/pt-BR/guide_caching_overview.md.po | 12 +- _translations/po/pt-BR/guide_glossary.md.po | 4 +- .../pt-BR/guide_security_best-practices.md.po | 12 +- .../po/pt-BR/guide_start_hello.md.po | 4 +- .../po/pt-BR/guide_structure_overview.md.po | 8 +- .../po/pt-BR/internals_014-docs.md.po | 4 +- .../ru/cookbook_organizing-code_service.md.po | 8 +- _translations/po/ru/guide_caching_data.md.po | 4 +- .../po/ru/guide_caching_overview.md.po | 6 +- _translations/po/ru/guide_glossary.md.po | 2 +- .../po/ru/guide_security_best-practices.md.po | 19 ++- _translations/po/ru/guide_start_hello.md.po | 8 +- .../po/ru/guide_structure_overview.md.po | 7 +- _translations/po/ru/internals_014-docs.md.po | 2 +- .../cookbook_organizing-code_service.md.po | 8 +- .../po/zh-CN/guide_caching_data.md.po | 8 +- .../po/zh-CN/guide_caching_overview.md.po | 12 +- _translations/po/zh-CN/guide_glossary.md.po | 2 +- .../zh-CN/guide_security_best-practices.md.po | 15 +-- .../po/zh-CN/guide_start_hello.md.po | 8 +- .../po/zh-CN/guide_structure_overview.md.po | 11 +- .../po/zh-CN/internals_014-docs.md.po | 4 +- .../cookbook_organizing-code_service.md.pot | 4 +- _translations/pot/guide_caching_data.md.pot | 108 +++++++++--------- .../pot/guide_caching_overview.md.pot | 8 +- _translations/pot/guide_glossary.md.pot | 4 +- .../pot/guide_security_best-practices.md.pot | 17 +-- _translations/pot/guide_start_hello.md.pot | 4 +- .../pot/guide_structure_overview.md.pot | 63 +++++----- _translations/pot/internals_014-docs.md.pot | 4 +- src/cookbook/organizing-code/service.md | 2 +- src/es/cookbook/organizing-code/service.md | 2 +- src/es/guide/caching/data.md | 4 +- src/es/guide/caching/overview.md | 6 +- src/es/guide/glossary.md | 2 +- src/es/guide/security/best-practices.md | 8 +- src/es/guide/start/hello.md | 2 +- src/es/guide/structure/overview.md | 11 +- src/es/internals/014-docs.md | 2 +- src/guide/caching/data.md | 4 +- src/guide/caching/overview.md | 6 +- src/guide/glossary.md | 2 +- src/guide/security/best-practices.md | 6 +- src/guide/start/hello.md | 2 +- src/guide/structure/overview.md | 4 +- src/id/cookbook/organizing-code/service.md | 2 +- src/id/guide/caching/data.md | 4 +- src/id/guide/caching/overview.md | 6 +- src/id/guide/glossary.md | 2 +- src/id/guide/security/best-practices.md | 8 +- src/id/guide/start/hello.md | 2 +- src/id/guide/structure/overview.md | 11 +- src/id/internals/014-docs.md | 2 +- src/internals/014-docs.md | 2 +- src/it/cookbook/organizing-code/service.md | 2 +- src/it/guide/caching/data.md | 4 +- src/it/guide/caching/overview.md | 6 +- src/it/guide/glossary.md | 2 +- src/it/guide/security/best-practices.md | 8 +- src/it/guide/start/hello.md | 2 +- src/it/guide/structure/overview.md | 11 +- src/it/internals/014-docs.md | 2 +- src/pt-BR/cookbook/organizing-code/service.md | 2 +- src/pt-BR/guide/caching/data.md | 4 +- src/pt-BR/guide/caching/overview.md | 6 +- src/pt-BR/guide/glossary.md | 3 +- src/pt-BR/guide/security/best-practices.md | 8 +- src/pt-BR/guide/start/hello.md | 2 +- src/pt-BR/guide/structure/overview.md | 10 +- src/pt-BR/internals/014-docs.md | 2 +- src/ru/cookbook/organizing-code/service.md | 2 +- src/ru/guide/caching/data.md | 4 +- src/ru/guide/caching/overview.md | 6 +- src/ru/guide/glossary.md | 2 +- src/ru/guide/security/best-practices.md | 6 +- src/ru/guide/start/hello.md | 2 +- src/ru/guide/structure/overview.md | 11 +- src/ru/internals/014-docs.md | 2 +- src/zh-CN/cookbook/organizing-code/service.md | 2 +- src/zh-CN/guide/caching/data.md | 4 +- src/zh-CN/guide/caching/overview.md | 6 +- src/zh-CN/guide/glossary.md | 2 +- src/zh-CN/guide/security/best-practices.md | 6 +- src/zh-CN/guide/start/hello.md | 2 +- src/zh-CN/guide/structure/overview.md | 5 +- src/zh-CN/internals/014-docs.md | 2 +- 113 files changed, 392 insertions(+), 413 deletions(-) diff --git a/.markdown-link-check.json b/.markdown-link-check.json index c93c6753..5d6c8770 100644 --- a/.markdown-link-check.json +++ b/.markdown-link-check.json @@ -1,5 +1,22 @@ { "projectBaseUrl": ".", + "ignorePatterns": [ + { + "pattern": "^https://dev\\.mysql\\.com/" + }, + { + "pattern": "^https://stackoverflow\\.com/" + }, + { + "pattern": "^https://security\\.stackexchange\\.com/" + }, + { + "pattern": "^https://code\\.tutsplus\\.com/" + }, + { + "pattern": "^https://yiiframework\\.ru/" + } + ], "replacementPatterns": [ { "pattern": "^/", diff --git a/_translations/po/es/cookbook_organizing-code_service.md.po b/_translations/po/es/cookbook_organizing-code_service.md.po index 35a3a188..7ac57ac6 100644 --- a/_translations/po/es/cookbook_organizing-code_service.md.po +++ b/_translations/po/es/cookbook_organizing-code_service.md.po @@ -17,15 +17,13 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. type: Bullet: '- ' -#: ../src/cookbook/organizing-code/domain.md -#: ../src/cookbook/organizing-code/service.md +#: ../src/cookbook/organizing-code/domain.md ../src/cookbook/organizing-code/service.md #, no-wrap msgid "Entity" msgstr "" #. type: Title ## -#: ../src/cookbook/organizing-code/domain.md -#: ../src/cookbook/organizing-code/service.md ../src/guide/start/databases.md +#: ../src/cookbook/organizing-code/domain.md ../src/cookbook/organizing-code/service.md ../src/guide/start/databases.md #, no-wrap msgid "Repository" msgstr "" @@ -267,5 +265,5 @@ msgstr "" #. type: Bullet: '- ' #: ../src/cookbook/organizing-code/service.md -msgid "[Middleware](middleware.md)" +msgid "[Middleware](../../guide/structure/middleware.md)" msgstr "" diff --git a/_translations/po/es/guide_caching_data.md.po b/_translations/po/es/guide_caching_data.md.po index 9ef94778..6e75c07a 100644 --- a/_translations/po/es/guide_caching_data.md.po +++ b/_translations/po/es/guide_caching_data.md.po @@ -24,7 +24,7 @@ msgstr "" #. type: Plain text #: ../../guide/en/caching/data.md -msgid "Data caching is about storing some PHP variables in a cache and retrieving them later from the cache. It's also the foundation for more advanced caching features, such as [page caching](page.md)." +msgid "Data caching is about storing some PHP variables in a cache and retrieving them later from the cache. It's also the foundation for more advanced caching features, such as page caching." msgstr "" #. type: Plain text @@ -99,7 +99,7 @@ msgstr "" #. type: Bullet: '- ' #: ../../guide/en/caching/data.md -msgid "[APCu](https://github.com/yiisoft/cache-apcu) - uses a PHP [APC](https://secure.php.net/manual/en/book.apc.php) extension. You can consider this option as the fastest one when dealing with cache for a centralized thick application (e.g., one server, no dedicated load balancers, etc.)." +msgid "[APCu](https://github.com/yiisoft/cache-apcu) - uses a PHP [APC](https://www.php.net/manual/en/book.apcu.php) extension. You can consider this option as the fastest one when dealing with cache for a centralized thick application (e.g., one server, no dedicated load balancers, etc.)." msgstr "" #. type: Bullet: '- ' diff --git a/_translations/po/es/guide_caching_overview.md.po b/_translations/po/es/guide_caching_overview.md.po index ecb3f060..1fcf1ca5 100644 --- a/_translations/po/es/guide_caching_overview.md.po +++ b/_translations/po/es/guide_caching_overview.md.po @@ -44,15 +44,15 @@ msgstr "" #. type: Bullet: '* ' #: ../src/guide/caching/overview.md -msgid "[Fragment caching](fragment.md)" +msgid "Fragment caching" msgstr "" #. type: Bullet: '* ' #: ../src/guide/caching/overview.md -msgid "[Page caching](page.md)" +msgid "Page caching" msgstr "" #. type: Bullet: '* ' #: ../src/guide/caching/overview.md -msgid "[HTTP caching](http.md)" +msgid "HTTP caching" msgstr "" diff --git a/_translations/po/es/guide_glossary.md.po b/_translations/po/es/guide_glossary.md.po index 222be501..bf63cdbb 100644 --- a/_translations/po/es/guide_glossary.md.po +++ b/_translations/po/es/guide_glossary.md.po @@ -467,7 +467,7 @@ msgstr "" #. type: Plain text #: ../src/guide/glossary.md -msgid "Service is a focused object that performs application work or provides infrastructure behavior and is usually stored in the DI container. Read more in [\"Service components\"](structure/service.md)." +msgid "Service is a focused object that performs application work or provides infrastructure behavior and is usually stored in the DI container. Read more in [\"Service components\"](../cookbook/organizing-code/service.md)." msgstr "" #. type: Title ## diff --git a/_translations/po/es/guide_security_best-practices.md.po b/_translations/po/es/guide_security_best-practices.md.po index b7e0c224..7e559980 100644 --- a/_translations/po/es/guide_security_best-practices.md.po +++ b/_translations/po/es/guide_security_best-practices.md.po @@ -17,12 +17,7 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. type: Title ## -#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md -#: ../src/guide/concept/autoloading.md ../src/guide/concept/di-container.md -#: ../src/guide/security/best-practices.md ../src/guide/structure/domain.md -#: ../src/guide/tutorial/console-applications.md -#: ../src/internals/004-namespaces.md ../src/internals/007-exceptions.md -#: ../src/internals/008-interfaces.md +#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md ../src/guide/concept/autoloading.md ../src/guide/concept/di-container.md ../src/guide/security/best-practices.md ../src/guide/structure/domain.md ../src/guide/tutorial/console-applications.md ../src/internals/004-namespaces.md ../src/internals/007-exceptions.md ../src/internals/008-interfaces.md #, no-wrap msgid "References" msgstr "Referencias" @@ -241,7 +236,7 @@ msgstr "" #. type: Plain text #: ../src/guide/security/best-practices.md -msgid "If it should be HTML, you could get some help from [HtmlPurifier](http://htmlpurifier.org/). Note that HtmlPurifier processing is quite heavy, so consider adding caching." +msgid "If it should be HTML, you could get some help from [HtmlPurifier](https://github.com/ezyang/htmlpurifier). Note that HtmlPurifier processing is quite heavy, so consider adding caching." msgstr "" #. type: Title ## @@ -359,12 +354,12 @@ msgstr "" #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md -msgid "" +msgid "" msgstr "" #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md -msgid "" +msgid "" msgstr "" #. type: Title ## diff --git a/_translations/po/es/guide_start_hello.md.po b/_translations/po/es/guide_start_hello.md.po index ce84fb30..80e76490 100644 --- a/_translations/po/es/guide_start_hello.md.po +++ b/_translations/po/es/guide_start_hello.md.po @@ -17,9 +17,7 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. type: Title ## -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md -#: ../src/guide/start/forms.md ../src/guide/start/hello.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md ../src/guide/start/forms.md ../src/guide/start/hello.md #, no-wrap msgid "Summary" msgstr "" @@ -43,7 +41,7 @@ msgstr "" #. type: Plain text #: ../src/guide/start/hello.md -msgid "To achieve this goal, you will define a route and create [a handler](../structure/handler.md) that does the job and forms the response. Then you will improve it to use [view](../views/view.md) for building the response." +msgid "To achieve this goal, you will define a route and create [a handler](../structure/action.md) that does the job and forms the response. Then you will improve it to use [view](../views/view.md) for building the response." msgstr "" #. type: Plain text diff --git a/_translations/po/es/guide_structure_overview.md.po b/_translations/po/es/guide_structure_overview.md.po index 78de4139..46ad1ec0 100644 --- a/_translations/po/es/guide_structure_overview.md.po +++ b/_translations/po/es/guide_structure_overview.md.po @@ -17,8 +17,7 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. type: Title ## -#: ../src/en/guide/structure/overview.md -#: ../src/en/guide/views/script-style-meta.md +#: ../src/en/guide/structure/overview.md ../src/en/guide/views/script-style-meta.md #, no-wrap msgid "Overview" msgstr "" @@ -137,7 +136,7 @@ msgstr "" #. type: Plain text #: ../src/en/guide/structure/overview.md -msgid "A context may have [an entry point known as \"action\" or \"controller\"](action.md). Its job is to take [a request instance](../runtime/request.md), pass it to [domain layer](domain.md) in a suitable format, and create [a response](../runtime/response.md) based on domain layer return." +msgid "A context may have [an entry point known as \"action\" or \"controller\"](action.md). Its job is to take [a request instance](../runtime/request.md), pass it to [domain layer](../../cookbook/organizing-code/domain.md) in a suitable format, and create [a response](../runtime/response.md) based on domain layer return." msgstr "" #. type: Plain text @@ -152,7 +151,7 @@ msgstr "" #. type: Bullet: '* ' #: ../src/en/guide/structure/overview.md -msgid "[services](service.md): they're typically stateless objects registered within dependency container and provide various action methods." +msgid "[services](../../cookbook/organizing-code/service.md): they're typically stateless objects registered within dependency container and provide various action methods." msgstr "" #. type: Bullet: '* ' diff --git a/_translations/po/es/internals_014-docs.md.po b/_translations/po/es/internals_014-docs.md.po index 201e8218..a9a59caa 100644 --- a/_translations/po/es/internals_014-docs.md.po +++ b/_translations/po/es/internals_014-docs.md.po @@ -68,7 +68,7 @@ msgstr "La Guía Definitiva de Yii 3.0" #. type: Plain text #: ../src/internals/014-docs.md -msgid "The definitive guide, [yiisoft/docs/guide](https://github.com/yiisoft/docs/tree/master/guide/en) aims at covering usage of packages as a whole framework. Unlike package documentation, it isn't focused on a single package but is covering certain use-cases." +msgid "The definitive guide, [yiisoft/docs/guide](https://github.com/yiisoft/docs/tree/master/src/guide) aims at covering usage of packages as a whole framework. Unlike package documentation, it isn't focused on a single package but is covering certain use-cases." msgstr "" #. type: Plain text diff --git a/_translations/po/id/cookbook_organizing-code_service.md.po b/_translations/po/id/cookbook_organizing-code_service.md.po index b0dd1ee2..c125327f 100644 --- a/_translations/po/id/cookbook_organizing-code_service.md.po +++ b/_translations/po/id/cookbook_organizing-code_service.md.po @@ -16,15 +16,13 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" #. type: Bullet: '- ' -#: ../src/cookbook/organizing-code/domain.md -#: ../src/cookbook/organizing-code/service.md +#: ../src/cookbook/organizing-code/domain.md ../src/cookbook/organizing-code/service.md #, no-wrap msgid "Entity" msgstr "" #. type: Title ## -#: ../src/cookbook/organizing-code/domain.md -#: ../src/cookbook/organizing-code/service.md ../src/guide/start/databases.md +#: ../src/cookbook/organizing-code/domain.md ../src/cookbook/organizing-code/service.md ../src/guide/start/databases.md #, no-wrap msgid "Repository" msgstr "" @@ -195,5 +193,5 @@ msgstr "" #. type: Bullet: '- ' #: ../src/cookbook/organizing-code/service.md -msgid "[Middleware](middleware.md)" +msgid "[Middleware](../../guide/structure/middleware.md)" msgstr "" diff --git a/_translations/po/id/guide_caching_data.md.po b/_translations/po/id/guide_caching_data.md.po index 5951b68a..777b2139 100644 --- a/_translations/po/id/guide_caching_data.md.po +++ b/_translations/po/id/guide_caching_data.md.po @@ -24,10 +24,10 @@ msgstr "Caching data" #. type: Plain text #: ../../guide/en/caching/data.md -msgid "Data caching is about storing some PHP variables in a cache and retrieving them later from the cache. It's also the foundation for more advanced caching features, such as [page caching](page.md)." +msgid "Data caching is about storing some PHP variables in a cache and retrieving them later from the cache. It's also the foundation for more advanced caching features, such as page caching." msgstr "" "Caching data adalah tentang menyimpan beberapa variabel PHP ke dalam cache dan mengambilnya kembali dari cache.\n" -"Ini juga menjadi fondasi untuk fitur caching yang lebih lanjut, seperti [caching halaman](page.md)." +"Ini juga menjadi fondasi untuk fitur caching yang lebih lanjut, seperti caching halaman." #. type: Plain text #: ../../guide/en/caching/data.md @@ -137,9 +137,9 @@ msgstr "`ArrayCache` — menyediakan caching hanya untuk permintaan saat ini den #. type: Bullet: '- ' #: ../../guide/en/caching/data.md -msgid "[APCu](https://github.com/yiisoft/cache-apcu) - uses a PHP [APC](https://secure.php.net/manual/en/book.apc.php) extension. You can consider this option as the fastest one when dealing with cache for a centralized thick application (e.g., one server, no dedicated load balancers, etc.)." +msgid "[APCu](https://github.com/yiisoft/cache-apcu) - uses a PHP [APC](https://www.php.net/manual/en/book.apcu.php) extension. You can consider this option as the fastest one when dealing with cache for a centralized thick application (e.g., one server, no dedicated load balancers, etc.)." msgstr "" -"[APCu](https://github.com/yiisoft/cache-apcu) — menggunakan ekstensi PHP [APC](https://secure.php.net/manual/en/book.apc.php).\n" +"[APCu](https://github.com/yiisoft/cache-apcu) — menggunakan ekstensi PHP [APC](https://www.php.net/manual/en/book.apcu.php).\n" " Ini bisa dianggap sebagai opsi tercepat saat berurusan dengan cache untuk aplikasi terpusat (mis., satu\n" " server, tanpa load balancer khusus, dll.)." diff --git a/_translations/po/id/guide_caching_overview.md.po b/_translations/po/id/guide_caching_overview.md.po index c6446e2f..7d9ce9aa 100644 --- a/_translations/po/id/guide_caching_overview.md.po +++ b/_translations/po/id/guide_caching_overview.md.po @@ -52,15 +52,15 @@ msgstr "[Data caching](data.md)" #. type: Bullet: '* ' #: ../src/guide/caching/overview.md -msgid "[Fragment caching](fragment.md)" -msgstr "[Fragment caching](fragment.md)" +msgid "Fragment caching" +msgstr "Fragment caching" #. type: Bullet: '* ' #: ../src/guide/caching/overview.md -msgid "[Page caching](page.md)" -msgstr "[Page caching](page.md)" +msgid "Page caching" +msgstr "Page caching" #. type: Bullet: '* ' #: ../src/guide/caching/overview.md -msgid "[HTTP caching](http.md)" -msgstr "[HTTP caching](http.md)" +msgid "HTTP caching" +msgstr "HTTP caching" diff --git a/_translations/po/id/guide_glossary.md.po b/_translations/po/id/guide_glossary.md.po index d3cf2441..93f19cd7 100644 --- a/_translations/po/id/guide_glossary.md.po +++ b/_translations/po/id/guide_glossary.md.po @@ -472,7 +472,7 @@ msgstr "" #. type: Plain text #: ../src/guide/glossary.md -msgid "Service is a focused object that performs application work or provides infrastructure behavior and is usually stored in the DI container. Read more in [\"Service components\"](structure/service.md)." +msgid "Service is a focused object that performs application work or provides infrastructure behavior and is usually stored in the DI container. Read more in [\"Service components\"](../cookbook/organizing-code/service.md)." msgstr "" #. type: Title ## diff --git a/_translations/po/id/guide_security_best-practices.md.po b/_translations/po/id/guide_security_best-practices.md.po index 0b1a553a..30d69ef4 100644 --- a/_translations/po/id/guide_security_best-practices.md.po +++ b/_translations/po/id/guide_security_best-practices.md.po @@ -16,12 +16,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md -#: ../src/guide/concept/autoloading.md ../src/guide/concept/di-container.md -#: ../src/guide/security/best-practices.md ../src/guide/structure/domain.md -#: ../src/guide/tutorial/console-applications.md -#: ../src/internals/004-namespaces.md ../src/internals/007-exceptions.md -#: ../src/internals/008-interfaces.md +#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md ../src/guide/concept/autoloading.md ../src/guide/concept/di-container.md ../src/guide/security/best-practices.md ../src/guide/structure/domain.md ../src/guide/tutorial/console-applications.md ../src/internals/004-namespaces.md ../src/internals/007-exceptions.md ../src/internals/008-interfaces.md #, no-wrap msgid "References" msgstr "Referensi" @@ -240,7 +235,7 @@ msgstr "" #. type: Plain text #: ../src/guide/security/best-practices.md -msgid "If it should be HTML, you could get some help from [HtmlPurifier](http://htmlpurifier.org/). Note that HtmlPurifier processing is quite heavy, so consider adding caching." +msgid "If it should be HTML, you could get some help from [HtmlPurifier](https://github.com/ezyang/htmlpurifier). Note that HtmlPurifier processing is quite heavy, so consider adding caching." msgstr "" #. type: Title ## @@ -358,12 +353,12 @@ msgstr "" #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md -msgid "" +msgid "" msgstr "" #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md -msgid "" +msgid "" msgstr "" #. type: Title ## diff --git a/_translations/po/id/guide_start_hello.md.po b/_translations/po/id/guide_start_hello.md.po index c4ffb409..1cdd3427 100644 --- a/_translations/po/id/guide_start_hello.md.po +++ b/_translations/po/id/guide_start_hello.md.po @@ -16,9 +16,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md -#: ../src/guide/start/forms.md ../src/guide/start/hello.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md ../src/guide/start/forms.md ../src/guide/start/hello.md #, no-wrap msgid "Summary" msgstr "" @@ -42,7 +40,7 @@ msgstr "" #. type: Plain text #: ../src/guide/start/hello.md -msgid "To achieve this goal, you will define a route and create [a handler](../structure/handler.md) that does the job and forms the response. Then you will improve it to use [view](../views/view.md) for building the response." +msgid "To achieve this goal, you will define a route and create [a handler](../structure/action.md) that does the job and forms the response. Then you will improve it to use [view](../views/view.md) for building the response." msgstr "" #. type: Plain text diff --git a/_translations/po/id/guide_structure_overview.md.po b/_translations/po/id/guide_structure_overview.md.po index aea11434..22a736a8 100644 --- a/_translations/po/id/guide_structure_overview.md.po +++ b/_translations/po/id/guide_structure_overview.md.po @@ -16,8 +16,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/en/guide/structure/overview.md -#: ../src/en/guide/views/script-style-meta.md +#: ../src/en/guide/structure/overview.md ../src/en/guide/views/script-style-meta.md #, no-wrap msgid "Overview" msgstr "" @@ -136,7 +135,7 @@ msgstr "" #. type: Plain text #: ../src/en/guide/structure/overview.md -msgid "A context may have [an entry point known as \"action\" or \"controller\"](action.md). Its job is to take [a request instance](../runtime/request.md), pass it to [domain layer](domain.md) in a suitable format, and create [a response](../runtime/response.md) based on domain layer return." +msgid "A context may have [an entry point known as \"action\" or \"controller\"](action.md). Its job is to take [a request instance](../runtime/request.md), pass it to [domain layer](../../cookbook/organizing-code/domain.md) in a suitable format, and create [a response](../runtime/response.md) based on domain layer return." msgstr "" #. type: Plain text @@ -151,7 +150,7 @@ msgstr "" #. type: Bullet: '* ' #: ../src/en/guide/structure/overview.md -msgid "[services](service.md): they're typically stateless objects registered within dependency container and provide various action methods." +msgid "[services](../../cookbook/organizing-code/service.md): they're typically stateless objects registered within dependency container and provide various action methods." msgstr "" #. type: Bullet: '* ' diff --git a/_translations/po/id/internals_014-docs.md.po b/_translations/po/id/internals_014-docs.md.po index 3a5f44dd..46cc75a9 100644 --- a/_translations/po/id/internals_014-docs.md.po +++ b/_translations/po/id/internals_014-docs.md.po @@ -67,7 +67,7 @@ msgstr "Panduan Definitif untuk Yii 3.0" #. type: Plain text #: ../src/internals/014-docs.md -msgid "The definitive guide, [yiisoft/docs/guide](https://github.com/yiisoft/docs/tree/master/guide/en) aims at covering usage of packages as a whole framework. Unlike package documentation, it isn't focused on a single package but is covering certain use-cases." +msgid "The definitive guide, [yiisoft/docs/guide](https://github.com/yiisoft/docs/tree/master/src/guide) aims at covering usage of packages as a whole framework. Unlike package documentation, it isn't focused on a single package but is covering certain use-cases." msgstr "" #. type: Plain text diff --git a/_translations/po/it/cookbook_organizing-code_service.md.po b/_translations/po/it/cookbook_organizing-code_service.md.po index 24b3ea4f..9c80e817 100644 --- a/_translations/po/it/cookbook_organizing-code_service.md.po +++ b/_translations/po/it/cookbook_organizing-code_service.md.po @@ -17,15 +17,13 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. type: Bullet: '- ' -#: ../src/cookbook/organizing-code/domain.md -#: ../src/cookbook/organizing-code/service.md +#: ../src/cookbook/organizing-code/domain.md ../src/cookbook/organizing-code/service.md #, no-wrap msgid "Entity" msgstr "" #. type: Title ## -#: ../src/cookbook/organizing-code/domain.md -#: ../src/cookbook/organizing-code/service.md ../src/guide/start/databases.md +#: ../src/cookbook/organizing-code/domain.md ../src/cookbook/organizing-code/service.md ../src/guide/start/databases.md #, no-wrap msgid "Repository" msgstr "" @@ -224,5 +222,5 @@ msgstr "" #: ../src/cookbook/organizing-code/service.md #, fuzzy #| msgid "[Middleware](structure/middleware.md)" -msgid "[Middleware](middleware.md)" +msgid "[Middleware](../../guide/structure/middleware.md)" msgstr "[Middleware](structure/middleware.md)" diff --git a/_translations/po/it/guide_caching_data.md.po b/_translations/po/it/guide_caching_data.md.po index 5bfc2e6d..719bacc2 100644 --- a/_translations/po/it/guide_caching_data.md.po +++ b/_translations/po/it/guide_caching_data.md.po @@ -25,7 +25,7 @@ msgstr "Caching" #. type: Plain text #: ../../guide/en/caching/data.md -msgid "Data caching is about storing some PHP variables in a cache and retrieving them later from the cache. It's also the foundation for more advanced caching features, such as [page caching](page.md)." +msgid "Data caching is about storing some PHP variables in a cache and retrieving them later from the cache. It's also the foundation for more advanced caching features, such as page caching." msgstr "" #. type: Plain text @@ -100,7 +100,7 @@ msgstr "" #. type: Bullet: '- ' #: ../../guide/en/caching/data.md -msgid "[APCu](https://github.com/yiisoft/cache-apcu) - uses a PHP [APC](https://secure.php.net/manual/en/book.apc.php) extension. You can consider this option as the fastest one when dealing with cache for a centralized thick application (e.g., one server, no dedicated load balancers, etc.)." +msgid "[APCu](https://github.com/yiisoft/cache-apcu) - uses a PHP [APC](https://www.php.net/manual/en/book.apcu.php) extension. You can consider this option as the fastest one when dealing with cache for a centralized thick application (e.g., one server, no dedicated load balancers, etc.)." msgstr "" #. type: Bullet: '- ' diff --git a/_translations/po/it/guide_caching_overview.md.po b/_translations/po/it/guide_caching_overview.md.po index 8c57a7c8..de0327b7 100644 --- a/_translations/po/it/guide_caching_overview.md.po +++ b/_translations/po/it/guide_caching_overview.md.po @@ -48,19 +48,19 @@ msgstr "[Caching dei dati](caching/data.md)" #: ../src/guide/caching/overview.md #, fuzzy #| msgid "[Fragment caching](caching/fragment.md) TODO" -msgid "[Fragment caching](fragment.md)" +msgid "Fragment caching" msgstr "[Caching dei frammenti](caching/fragment.md) TODO" #. type: Bullet: '* ' #: ../src/guide/caching/overview.md #, fuzzy #| msgid "[Page caching](caching/page.md) TODO" -msgid "[Page caching](page.md)" +msgid "Page caching" msgstr "[Caching delle pagine](caching/page.md) TODO" #. type: Bullet: '* ' #: ../src/guide/caching/overview.md #, fuzzy #| msgid "[HTTP caching](caching/http.md) TODO" -msgid "[HTTP caching](http.md)" +msgid "HTTP caching" msgstr "[Caching HTTP](caching/http.md) TODO" diff --git a/_translations/po/it/guide_glossary.md.po b/_translations/po/it/guide_glossary.md.po index 470eafbb..ab421e75 100644 --- a/_translations/po/it/guide_glossary.md.po +++ b/_translations/po/it/guide_glossary.md.po @@ -468,7 +468,7 @@ msgstr "" #. type: Plain text #: ../src/guide/glossary.md -msgid "Service is a focused object that performs application work or provides infrastructure behavior and is usually stored in the DI container. Read more in [\"Service components\"](structure/service.md)." +msgid "Service is a focused object that performs application work or provides infrastructure behavior and is usually stored in the DI container. Read more in [\"Service components\"](../cookbook/organizing-code/service.md)." msgstr "" #. type: Title ## diff --git a/_translations/po/it/guide_security_best-practices.md.po b/_translations/po/it/guide_security_best-practices.md.po index 930b0fc8..e04654d8 100644 --- a/_translations/po/it/guide_security_best-practices.md.po +++ b/_translations/po/it/guide_security_best-practices.md.po @@ -17,12 +17,7 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. type: Title ## -#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md -#: ../src/guide/concept/autoloading.md ../src/guide/concept/di-container.md -#: ../src/guide/security/best-practices.md ../src/guide/structure/domain.md -#: ../src/guide/tutorial/console-applications.md -#: ../src/internals/004-namespaces.md ../src/internals/007-exceptions.md -#: ../src/internals/008-interfaces.md +#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md ../src/guide/concept/autoloading.md ../src/guide/concept/di-container.md ../src/guide/security/best-practices.md ../src/guide/structure/domain.md ../src/guide/tutorial/console-applications.md ../src/internals/004-namespaces.md ../src/internals/007-exceptions.md ../src/internals/008-interfaces.md #, no-wrap msgid "References" msgstr "" @@ -241,7 +236,7 @@ msgstr "" #. type: Plain text #: ../src/guide/security/best-practices.md -msgid "If it should be HTML, you could get some help from [HtmlPurifier](http://htmlpurifier.org/). Note that HtmlPurifier processing is quite heavy, so consider adding caching." +msgid "If it should be HTML, you could get some help from [HtmlPurifier](https://github.com/ezyang/htmlpurifier). Note that HtmlPurifier processing is quite heavy, so consider adding caching." msgstr "" #. type: Title ## @@ -359,12 +354,12 @@ msgstr "" #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md -msgid "" +msgid "" msgstr "" #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md -msgid "" +msgid "" msgstr "" #. type: Title ## diff --git a/_translations/po/it/guide_start_hello.md.po b/_translations/po/it/guide_start_hello.md.po index 48f67b11..9e7c392e 100644 --- a/_translations/po/it/guide_start_hello.md.po +++ b/_translations/po/it/guide_start_hello.md.po @@ -18,9 +18,7 @@ msgstr "" "X-Generator: Poedit 3.8\n" #. type: Title ## -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md -#: ../src/guide/start/forms.md ../src/guide/start/hello.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md ../src/guide/start/forms.md ../src/guide/start/hello.md #, no-wrap msgid "Summary" msgstr "" @@ -44,8 +42,8 @@ msgstr "Questa sezione descrive come creare una nuova pagina “Hello” nella t #. type: Plain text #: ../src/guide/start/hello.md -msgid "To achieve this goal, you will define a route and create [a handler](../structure/handler.md) that does the job and forms the response. Then you will improve it to use [view](../views/view.md) for building the response." -msgstr "Per raggiungere questo obiettivo, definirai una rotta e creerai [un gestore di richieste](../structure/handler.md) che esegue il lavoro e forma la risposta. Poi lo migliorerai per usare [una vista](../views/view.md) per costruire la risposta." +msgid "To achieve this goal, you will define a route and create [a handler](../structure/action.md) that does the job and forms the response. Then you will improve it to use [view](../views/view.md) for building the response." +msgstr "Per raggiungere questo obiettivo, definirai una rotta e creerai [un gestore di richieste](../structure/action.md) che esegue il lavoro e forma la risposta. Poi lo migliorerai per usare [una vista](../views/view.md) per costruire la risposta." #. type: Plain text #: ../src/guide/start/hello.md diff --git a/_translations/po/it/guide_structure_overview.md.po b/_translations/po/it/guide_structure_overview.md.po index edb6c96e..635987d2 100644 --- a/_translations/po/it/guide_structure_overview.md.po +++ b/_translations/po/it/guide_structure_overview.md.po @@ -17,8 +17,7 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. type: Title ## -#: ../src/en/guide/structure/overview.md -#: ../src/en/guide/views/script-style-meta.md +#: ../src/en/guide/structure/overview.md ../src/en/guide/views/script-style-meta.md #, no-wrap msgid "Overview" msgstr "" @@ -139,7 +138,7 @@ msgstr "" #. type: Plain text #: ../src/en/guide/structure/overview.md -msgid "A context may have [an entry point known as \"action\" or \"controller\"](action.md). Its job is to take [a request instance](../runtime/request.md), pass it to [domain layer](domain.md) in a suitable format, and create [a response](../runtime/response.md) based on domain layer return." +msgid "A context may have [an entry point known as \"action\" or \"controller\"](action.md). Its job is to take [a request instance](../runtime/request.md), pass it to [domain layer](../../cookbook/organizing-code/domain.md) in a suitable format, and create [a response](../runtime/response.md) based on domain layer return." msgstr "" #. type: Plain text @@ -154,7 +153,7 @@ msgstr "" #. type: Bullet: '* ' #: ../src/en/guide/structure/overview.md -msgid "[services](service.md): they're typically stateless objects registered within dependency container and provide various action methods." +msgid "[services](../../cookbook/organizing-code/service.md): they're typically stateless objects registered within dependency container and provide various action methods." msgstr "" #. type: Bullet: '* ' diff --git a/_translations/po/it/internals_014-docs.md.po b/_translations/po/it/internals_014-docs.md.po index 6befbc5c..92b5c57a 100644 --- a/_translations/po/it/internals_014-docs.md.po +++ b/_translations/po/it/internals_014-docs.md.po @@ -68,7 +68,7 @@ msgstr "La guida definitiva a Yii3" #. type: Plain text #: ../src/internals/014-docs.md -msgid "The definitive guide, [yiisoft/docs/guide](https://github.com/yiisoft/docs/tree/master/guide/en) aims at covering usage of packages as a whole framework. Unlike package documentation, it isn't focused on a single package but is covering certain use-cases." +msgid "The definitive guide, [yiisoft/docs/guide](https://github.com/yiisoft/docs/tree/master/src/guide) aims at covering usage of packages as a whole framework. Unlike package documentation, it isn't focused on a single package but is covering certain use-cases." msgstr "" #. type: Plain text diff --git a/_translations/po/pt-BR/cookbook_organizing-code_service.md.po b/_translations/po/pt-BR/cookbook_organizing-code_service.md.po index ea8ccddb..289d4b3c 100644 --- a/_translations/po/pt-BR/cookbook_organizing-code_service.md.po +++ b/_translations/po/pt-BR/cookbook_organizing-code_service.md.po @@ -243,5 +243,5 @@ msgstr "Widget" #. type: Bullet: '- ' #: ../src/cookbook/organizing-code/service.md -msgid "[Middleware](middleware.md)" -msgstr "[Middleware](middleware.md)" +msgid "[Middleware](../../guide/structure/middleware.md)" +msgstr "[Middleware](../../guide/structure/middleware.md)" diff --git a/_translations/po/pt-BR/guide_caching_data.md.po b/_translations/po/pt-BR/guide_caching_data.md.po index 8fc3625c..ebd7f56b 100644 --- a/_translations/po/pt-BR/guide_caching_data.md.po +++ b/_translations/po/pt-BR/guide_caching_data.md.po @@ -23,8 +23,8 @@ msgstr "Cache de dados" #. type: Plain text #: ../../guide/en/caching/data.md -msgid "Data caching is about storing some PHP variables in a cache and retrieving them later from the cache. It's also the foundation for more advanced caching features, such as [page caching](page.md)." -msgstr "O cache de dados consiste em guardar algumas variáveis PHP no cache e recuperá-las dele mais tarde. Ele também é a base para recursos de cache mais avançados, como o [cache de páginas](page.md)." +msgid "Data caching is about storing some PHP variables in a cache and retrieving them later from the cache. It's also the foundation for more advanced caching features, such as page caching." +msgstr "O cache de dados consiste em guardar algumas variáveis PHP no cache e recuperá-las dele mais tarde. Ele também é a base para recursos de cache mais avançados, como o cache de páginas." #. type: Plain text #: ../../guide/en/caching/data.md @@ -110,8 +110,8 @@ msgstr "`ArrayCache` — faz cache apenas durante a requisição atual, guardand #. type: Bullet: '- ' #: ../../guide/en/caching/data.md -msgid "[APCu](https://github.com/yiisoft/cache-apcu) - uses a PHP [APC](https://secure.php.net/manual/en/book.apc.php) extension. You can consider this option as the fastest one when dealing with cache for a centralized thick application (e.g., one server, no dedicated load balancers, etc.)." -msgstr "[APCu](https://github.com/yiisoft/cache-apcu) - usa a extensão [APC](https://secure.php.net/manual/en/book.apc.php) do PHP. Você pode considerar esta a opção mais rápida ao lidar com cache em uma aplicação centralizada e robusta (por exemplo, um servidor, sem load balancers dedicados etc.)." +msgid "[APCu](https://github.com/yiisoft/cache-apcu) - uses a PHP [APC](https://www.php.net/manual/en/book.apcu.php) extension. You can consider this option as the fastest one when dealing with cache for a centralized thick application (e.g., one server, no dedicated load balancers, etc.)." +msgstr "[APCu](https://github.com/yiisoft/cache-apcu) - usa a extensão [APC](https://www.php.net/manual/en/book.apcu.php) do PHP. Você pode considerar esta a opção mais rápida ao lidar com cache em uma aplicação centralizada e robusta (por exemplo, um servidor, sem load balancers dedicados etc.)." #. type: Bullet: '- ' #: ../../guide/en/caching/data.md diff --git a/_translations/po/pt-BR/guide_caching_overview.md.po b/_translations/po/pt-BR/guide_caching_overview.md.po index 86faf8a7..7b4d3ed9 100644 --- a/_translations/po/pt-BR/guide_caching_overview.md.po +++ b/_translations/po/pt-BR/guide_caching_overview.md.po @@ -43,15 +43,15 @@ msgstr "[Cache de dados](data.md)" #. type: Bullet: '* ' #: ../src/guide/caching/overview.md -msgid "[Fragment caching](fragment.md)" -msgstr "[Cache de fragmentos](fragment.md)" +msgid "Fragment caching" +msgstr "Cache de fragmentos" #. type: Bullet: '* ' #: ../src/guide/caching/overview.md -msgid "[Page caching](page.md)" -msgstr "[Cache de páginas](page.md)" +msgid "Page caching" +msgstr "Cache de páginas" #. type: Bullet: '* ' #: ../src/guide/caching/overview.md -msgid "[HTTP caching](http.md)" -msgstr "[Cache HTTP](http.md)" +msgid "HTTP caching" +msgstr "Cache HTTP" diff --git a/_translations/po/pt-BR/guide_glossary.md.po b/_translations/po/pt-BR/guide_glossary.md.po index 9e1c6149..476c22fe 100644 --- a/_translations/po/pt-BR/guide_glossary.md.po +++ b/_translations/po/pt-BR/guide_glossary.md.po @@ -459,8 +459,8 @@ msgstr "serviço" #. type: Plain text #: ../src/guide/glossary.md -msgid "Service is a focused object that performs application work or provides infrastructure behavior and is usually stored in the DI container. Read more in [\"Service components\"](structure/service.md)." -msgstr "Serviço é um objeto focado que realiza trabalho da aplicação ou fornece comportamento de infraestrutura e normalmente fica registrado no container de DI. Leia mais em [\"Componentes de serviço\"](structure/service.md)." +msgid "Service is a focused object that performs application work or provides infrastructure behavior and is usually stored in the DI container. Read more in [\"Service components\"](../cookbook/organizing-code/service.md)." +msgstr "Serviço é um objeto focado que realiza trabalho da aplicação ou fornece comportamento de infraestrutura e normalmente fica registrado no container de DI. Leia mais em [\"Componentes de serviço\"](../cookbook/organizing-code/service.md)." #. type: Title ## #: ../src/guide/glossary.md diff --git a/_translations/po/pt-BR/guide_security_best-practices.md.po b/_translations/po/pt-BR/guide_security_best-practices.md.po index 2199372c..2070db4c 100644 --- a/_translations/po/pt-BR/guide_security_best-practices.md.po +++ b/_translations/po/pt-BR/guide_security_best-practices.md.po @@ -259,8 +259,8 @@ msgstr "\n" #. type: Plain text #: ../src/guide/security/best-practices.md -msgid "If it should be HTML, you could get some help from [HtmlPurifier](http://htmlpurifier.org/). Note that HtmlPurifier processing is quite heavy, so consider adding caching." -msgstr "Se precisar ser HTML, você pode ter a ajuda do [HtmlPurifier](http://htmlpurifier.org/). Note que o processamento do HtmlPurifier é bem pesado, então considere usar cache." +msgid "If it should be HTML, you could get some help from [HtmlPurifier](https://github.com/ezyang/htmlpurifier). Note that HtmlPurifier processing is quite heavy, so consider adding caching." +msgstr "Se precisar ser HTML, você pode ter a ajuda do [HtmlPurifier](https://github.com/ezyang/htmlpurifier). Note que o processamento do HtmlPurifier é bem pesado, então considere usar cache." #. type: Title ## #: ../src/guide/security/best-practices.md @@ -394,13 +394,13 @@ msgstr "Evite a barra de debug em produção, a menos que seja necessário. Ela #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md -msgid "" -msgstr "" +msgid "" +msgstr "" #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md -msgid "" -msgstr "" +msgid "" +msgstr "" #. type: Title ## #: ../src/guide/security/best-practices.md diff --git a/_translations/po/pt-BR/guide_start_hello.md.po b/_translations/po/pt-BR/guide_start_hello.md.po index ae2d01c8..ba17a6b6 100644 --- a/_translations/po/pt-BR/guide_start_hello.md.po +++ b/_translations/po/pt-BR/guide_start_hello.md.po @@ -40,8 +40,8 @@ msgstr "Esta seção descreve como criar uma nova página \"Hello\" na sua aplic #. type: Plain text #: ../src/guide/start/hello.md -msgid "To achieve this goal, you will define a route and create [a handler](../structure/handler.md) that does the job and forms the response. Then you will improve it to use [view](../views/view.md) for building the response." -msgstr "Para isso, você vai definir uma rota e criar [um handler](../structure/handler.md) que faz o trabalho e monta a resposta. Depois, vai melhorá-lo para usar uma [view](../views/view.md) na construção da resposta." +msgid "To achieve this goal, you will define a route and create [a handler](../structure/action.md) that does the job and forms the response. Then you will improve it to use [view](../views/view.md) for building the response." +msgstr "Para isso, você vai definir uma rota e criar [um handler](../structure/action.md) que faz o trabalho e monta a resposta. Depois, vai melhorá-lo para usar uma [view](../views/view.md) na construção da resposta." #. type: Plain text #: ../src/guide/start/hello.md diff --git a/_translations/po/pt-BR/guide_structure_overview.md.po b/_translations/po/pt-BR/guide_structure_overview.md.po index 8d4ffbaf..3f996de9 100644 --- a/_translations/po/pt-BR/guide_structure_overview.md.po +++ b/_translations/po/pt-BR/guide_structure_overview.md.po @@ -151,8 +151,8 @@ msgstr "Um contexto pode incluir subcontextos. Se uma classe é compartilhada po #. type: Plain text #: ../src/en/guide/structure/overview.md -msgid "A context may have [an entry point known as \"action\" or \"controller\"](action.md). Its job is to take [a request instance](../runtime/request.md), pass it to [domain layer](domain.md) in a suitable format, and create [a response](../runtime/response.md) based on domain layer return." -msgstr "Um contexto pode ter [um ponto de entrada conhecido como \"action\" ou \"controller\"](action.md). A função dele é receber [uma instância de requisição](../runtime/request.md), passá-la para a [camada de domínio](domain.md) em um formato adequado e criar [uma resposta](../runtime/response.md) com base no retorno da camada de domínio." +msgid "A context may have [an entry point known as \"action\" or \"controller\"](action.md). Its job is to take [a request instance](../runtime/request.md), pass it to [domain layer](../../cookbook/organizing-code/domain.md) in a suitable format, and create [a response](../runtime/response.md) based on domain layer return." +msgstr "Um contexto pode ter [um ponto de entrada conhecido como \"action\" ou \"controller\"](action.md). A função dele é receber [uma instância de requisição](../runtime/request.md), passá-la para a [camada de domínio](../../cookbook/organizing-code/domain.md) em um formato adequado e criar [uma resposta](../runtime/response.md) com base no retorno da camada de domínio." #. type: Plain text #: ../src/en/guide/structure/overview.md @@ -166,8 +166,8 @@ msgstr "[scripts de entrada](entry-script.md): são scripts PHP acessíveis dire #. type: Bullet: '* ' #: ../src/en/guide/structure/overview.md -msgid "[services](service.md): they're typically stateless objects registered within dependency container and provide various action methods." -msgstr "[serviços](service.md): normalmente são objetos sem estado registrados no container de dependências que fornecem diversos métodos de ação." +msgid "[services](../../cookbook/organizing-code/service.md): they're typically stateless objects registered within dependency container and provide various action methods." +msgstr "[serviços](../../cookbook/organizing-code/service.md): normalmente são objetos sem estado registrados no container de dependências que fornecem diversos métodos de ação." #. type: Bullet: '* ' #: ../src/en/guide/structure/overview.md diff --git a/_translations/po/pt-BR/internals_014-docs.md.po b/_translations/po/pt-BR/internals_014-docs.md.po index 76ecd467..8ee3df95 100644 --- a/_translations/po/pt-BR/internals_014-docs.md.po +++ b/_translations/po/pt-BR/internals_014-docs.md.po @@ -65,8 +65,8 @@ msgstr "Guia definitivo" #. type: Plain text #: ../src/internals/014-docs.md -msgid "The definitive guide, [yiisoft/docs/guide](https://github.com/yiisoft/docs/tree/master/guide/en) aims at covering usage of packages as a whole framework. Unlike package documentation, it isn't focused on a single package but is covering certain use-cases." -msgstr "O guia definitivo, [yiisoft/docs/guide](https://github.com/yiisoft/docs/tree/master/guide/en) tem como objetivo cobrir o uso dos pacotes como um framework completo. Diferente da documentação dos pacotes, ele não se concentra em um único pacote, e sim em determinados casos de uso." +msgid "The definitive guide, [yiisoft/docs/guide](https://github.com/yiisoft/docs/tree/master/src/guide) aims at covering usage of packages as a whole framework. Unlike package documentation, it isn't focused on a single package but is covering certain use-cases." +msgstr "O guia definitivo, [yiisoft/docs/guide](https://github.com/yiisoft/docs/tree/master/src/guide) tem como objetivo cobrir o uso dos pacotes como um framework completo. Diferente da documentação dos pacotes, ele não se concentra em um único pacote, e sim em determinados casos de uso." #. type: Plain text #: ../src/internals/014-docs.md diff --git a/_translations/po/ru/cookbook_organizing-code_service.md.po b/_translations/po/ru/cookbook_organizing-code_service.md.po index 8c0e1c23..a0dea9e0 100644 --- a/_translations/po/ru/cookbook_organizing-code_service.md.po +++ b/_translations/po/ru/cookbook_organizing-code_service.md.po @@ -17,15 +17,13 @@ msgstr "" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" #. type: Bullet: '- ' -#: ../src/cookbook/organizing-code/domain.md -#: ../src/cookbook/organizing-code/service.md +#: ../src/cookbook/organizing-code/domain.md ../src/cookbook/organizing-code/service.md #, fuzzy, no-wrap msgid "Entity" msgstr "Сущность" #. type: Title ## -#: ../src/cookbook/organizing-code/domain.md -#: ../src/cookbook/organizing-code/service.md ../src/guide/start/databases.md +#: ../src/cookbook/organizing-code/domain.md ../src/cookbook/organizing-code/service.md ../src/guide/start/databases.md #, no-wrap msgid "Repository" msgstr "Репозиторий" @@ -238,5 +236,5 @@ msgstr "" #. type: Bullet: '- ' #: ../src/cookbook/organizing-code/service.md -msgid "[Middleware](middleware.md)" +msgid "[Middleware](../../guide/structure/middleware.md)" msgstr "" diff --git a/_translations/po/ru/guide_caching_data.md.po b/_translations/po/ru/guide_caching_data.md.po index 9e5206f9..67e48872 100644 --- a/_translations/po/ru/guide_caching_data.md.po +++ b/_translations/po/ru/guide_caching_data.md.po @@ -24,7 +24,7 @@ msgstr "" #. type: Plain text #: ../../guide/en/caching/data.md -msgid "Data caching is about storing some PHP variables in a cache and retrieving them later from the cache. It's also the foundation for more advanced caching features, such as [page caching](page.md)." +msgid "Data caching is about storing some PHP variables in a cache and retrieving them later from the cache. It's also the foundation for more advanced caching features, such as page caching." msgstr "" #. type: Plain text @@ -100,7 +100,7 @@ msgstr "" #. type: Bullet: '- ' #: ../../guide/en/caching/data.md -msgid "[APCu](https://github.com/yiisoft/cache-apcu) - uses a PHP [APC](https://secure.php.net/manual/en/book.apc.php) extension. You can consider this option as the fastest one when dealing with cache for a centralized thick application (e.g., one server, no dedicated load balancers, etc.)." +msgid "[APCu](https://github.com/yiisoft/cache-apcu) - uses a PHP [APC](https://www.php.net/manual/en/book.apcu.php) extension. You can consider this option as the fastest one when dealing with cache for a centralized thick application (e.g., one server, no dedicated load balancers, etc.)." msgstr "" #. type: Bullet: '- ' diff --git a/_translations/po/ru/guide_caching_overview.md.po b/_translations/po/ru/guide_caching_overview.md.po index c56ab7c7..c70dde04 100644 --- a/_translations/po/ru/guide_caching_overview.md.po +++ b/_translations/po/ru/guide_caching_overview.md.po @@ -44,15 +44,15 @@ msgstr "" #. type: Bullet: '* ' #: ../src/guide/caching/overview.md -msgid "[Fragment caching](fragment.md)" +msgid "Fragment caching" msgstr "" #. type: Bullet: '* ' #: ../src/guide/caching/overview.md -msgid "[Page caching](page.md)" +msgid "Page caching" msgstr "" #. type: Bullet: '* ' #: ../src/guide/caching/overview.md -msgid "[HTTP caching](http.md)" +msgid "HTTP caching" msgstr "" diff --git a/_translations/po/ru/guide_glossary.md.po b/_translations/po/ru/guide_glossary.md.po index e96f1d15..e8d07000 100644 --- a/_translations/po/ru/guide_glossary.md.po +++ b/_translations/po/ru/guide_glossary.md.po @@ -472,7 +472,7 @@ msgstr "" #. type: Plain text #: ../src/guide/glossary.md -msgid "Service is a focused object that performs application work or provides infrastructure behavior and is usually stored in the DI container. Read more in [\"Service components\"](structure/service.md)." +msgid "Service is a focused object that performs application work or provides infrastructure behavior and is usually stored in the DI container. Read more in [\"Service components\"](../cookbook/organizing-code/service.md)." msgstr "" #. type: Title ## diff --git a/_translations/po/ru/guide_security_best-practices.md.po b/_translations/po/ru/guide_security_best-practices.md.po index 3b2f48b1..60f78576 100644 --- a/_translations/po/ru/guide_security_best-practices.md.po +++ b/_translations/po/ru/guide_security_best-practices.md.po @@ -18,12 +18,7 @@ msgstr "" "X-Generator: Poedit 3.7\n" #. type: Title ## -#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md -#: ../src/guide/concept/autoloading.md ../src/guide/concept/di-container.md -#: ../src/guide/security/best-practices.md ../src/guide/structure/domain.md -#: ../src/guide/tutorial/console-applications.md -#: ../src/internals/004-namespaces.md ../src/internals/007-exceptions.md -#: ../src/internals/008-interfaces.md +#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md ../src/guide/concept/autoloading.md ../src/guide/concept/di-container.md ../src/guide/security/best-practices.md ../src/guide/structure/domain.md ../src/guide/tutorial/console-applications.md ../src/internals/004-namespaces.md ../src/internals/007-exceptions.md ../src/internals/008-interfaces.md #, no-wrap msgid "References" msgstr "Ссылки" @@ -273,9 +268,9 @@ msgstr "\n" #. type: Plain text #: ../src/guide/security/best-practices.md -msgid "If it should be HTML, you could get some help from [HtmlPurifier](http://htmlpurifier.org/). Note that HtmlPurifier processing is quite heavy, so consider adding caching." +msgid "If it should be HTML, you could get some help from [HtmlPurifier](https://github.com/ezyang/htmlpurifier). Note that HtmlPurifier processing is quite heavy, so consider adding caching." msgstr "" -"Если нужно вывести HTML, вам лучше воспользоваться [HtmlPurifier](http://htmlpurifier.org/).\n" +"Если нужно вывести HTML, вам лучше воспользоваться [HtmlPurifier](https://github.com/ezyang/htmlpurifier).\n" "Обратите внимание, что обработка с помощью HtmlPurifier довольно тяжела, поэтому рассмотрите возможность использования кеширования." #. type: Title ## @@ -425,13 +420,13 @@ msgstr "" #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md -msgid "" -msgstr "" +msgid "" +msgstr "" #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md -msgid "" -msgstr "" +msgid "" +msgstr "" #. type: Title ## #: ../src/guide/security/best-practices.md diff --git a/_translations/po/ru/guide_start_hello.md.po b/_translations/po/ru/guide_start_hello.md.po index 1330aa26..117561eb 100644 --- a/_translations/po/ru/guide_start_hello.md.po +++ b/_translations/po/ru/guide_start_hello.md.po @@ -18,9 +18,7 @@ msgstr "" "X-Generator: Poedit 3.9\n" #. type: Title ## -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md -#: ../src/guide/start/forms.md ../src/guide/start/hello.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md ../src/guide/start/forms.md ../src/guide/start/hello.md #, no-wrap msgid "Summary" msgstr "Краткое содержание" @@ -44,8 +42,8 @@ msgstr "В этом разделе описывается, как создать #. type: Plain text #: ../src/guide/start/hello.md -msgid "To achieve this goal, you will define a route and create [a handler](../structure/handler.md) that does the job and forms the response. Then you will improve it to use [view](../views/view.md) for building the response." -msgstr "Чтобы этого добиться, вы определите маршрут и создадите [обработчик](../structure/handler.md), который выполнит задачу и сформирует ответ. Затем вы улучшите решение, используя [представление](../views/view.md) для построения ответа." +msgid "To achieve this goal, you will define a route and create [a handler](../structure/action.md) that does the job and forms the response. Then you will improve it to use [view](../views/view.md) for building the response." +msgstr "Чтобы этого добиться, вы определите маршрут и создадите [обработчик](../structure/action.md), который выполнит задачу и сформирует ответ. Затем вы улучшите решение, используя [представление](../views/view.md) для построения ответа." #. type: Plain text #: ../src/guide/start/hello.md diff --git a/_translations/po/ru/guide_structure_overview.md.po b/_translations/po/ru/guide_structure_overview.md.po index 3ba138d4..e1fc70fa 100644 --- a/_translations/po/ru/guide_structure_overview.md.po +++ b/_translations/po/ru/guide_structure_overview.md.po @@ -17,8 +17,7 @@ msgstr "" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" #. type: Title ## -#: ../src/en/guide/structure/overview.md -#: ../src/en/guide/views/script-style-meta.md +#: ../src/en/guide/structure/overview.md ../src/en/guide/views/script-style-meta.md #, no-wrap msgid "Overview" msgstr "" @@ -137,7 +136,7 @@ msgstr "" #. type: Plain text #: ../src/en/guide/structure/overview.md -msgid "A context may have [an entry point known as \"action\" or \"controller\"](action.md). Its job is to take [a request instance](../runtime/request.md), pass it to [domain layer](domain.md) in a suitable format, and create [a response](../runtime/response.md) based on domain layer return." +msgid "A context may have [an entry point known as \"action\" or \"controller\"](action.md). Its job is to take [a request instance](../runtime/request.md), pass it to [domain layer](../../cookbook/organizing-code/domain.md) in a suitable format, and create [a response](../runtime/response.md) based on domain layer return." msgstr "" #. type: Plain text @@ -152,7 +151,7 @@ msgstr "" #. type: Bullet: '* ' #: ../src/en/guide/structure/overview.md -msgid "[services](service.md): they're typically stateless objects registered within dependency container and provide various action methods." +msgid "[services](../../cookbook/organizing-code/service.md): they're typically stateless objects registered within dependency container and provide various action methods." msgstr "" #. type: Bullet: '* ' diff --git a/_translations/po/ru/internals_014-docs.md.po b/_translations/po/ru/internals_014-docs.md.po index e0c5139d..ff20d098 100644 --- a/_translations/po/ru/internals_014-docs.md.po +++ b/_translations/po/ru/internals_014-docs.md.po @@ -67,7 +67,7 @@ msgstr "" #. type: Plain text #: ../src/internals/014-docs.md -msgid "The definitive guide, [yiisoft/docs/guide](https://github.com/yiisoft/docs/tree/master/guide/en) aims at covering usage of packages as a whole framework. Unlike package documentation, it isn't focused on a single package but is covering certain use-cases." +msgid "The definitive guide, [yiisoft/docs/guide](https://github.com/yiisoft/docs/tree/master/src/guide) aims at covering usage of packages as a whole framework. Unlike package documentation, it isn't focused on a single package but is covering certain use-cases." msgstr "" #. type: Plain text diff --git a/_translations/po/zh-CN/cookbook_organizing-code_service.md.po b/_translations/po/zh-CN/cookbook_organizing-code_service.md.po index c3e1b36f..dd36e5d9 100644 --- a/_translations/po/zh-CN/cookbook_organizing-code_service.md.po +++ b/_translations/po/zh-CN/cookbook_organizing-code_service.md.po @@ -16,15 +16,13 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" #. type: Bullet: '- ' -#: ../src/cookbook/organizing-code/domain.md -#: ../src/cookbook/organizing-code/service.md +#: ../src/cookbook/organizing-code/domain.md ../src/cookbook/organizing-code/service.md #, fuzzy, no-wrap msgid "Entity" msgstr "实体" #. type: Title ## -#: ../src/cookbook/organizing-code/domain.md -#: ../src/cookbook/organizing-code/service.md ../src/guide/start/databases.md +#: ../src/cookbook/organizing-code/domain.md ../src/cookbook/organizing-code/service.md ../src/guide/start/databases.md #, no-wrap msgid "Repository" msgstr "仓库" @@ -199,5 +197,5 @@ msgstr "小部件" #: ../src/cookbook/organizing-code/service.md #, fuzzy #| msgid "[Middleware](structure/middleware.md)" -msgid "[Middleware](middleware.md)" +msgid "[Middleware](../../guide/structure/middleware.md)" msgstr "[中间件](structure/middleware.md)" diff --git a/_translations/po/zh-CN/guide_caching_data.md.po b/_translations/po/zh-CN/guide_caching_data.md.po index c079ff93..5991a85f 100644 --- a/_translations/po/zh-CN/guide_caching_data.md.po +++ b/_translations/po/zh-CN/guide_caching_data.md.po @@ -23,8 +23,8 @@ msgstr "数据缓存" #. type: Plain text #: ../../guide/en/caching/data.md -msgid "Data caching is about storing some PHP variables in a cache and retrieving them later from the cache. It's also the foundation for more advanced caching features, such as [page caching](page.md)." -msgstr "数据缓存是将一些 PHP 变量存储在缓存中,然后稍后从缓存中检索它们。它也是更高级缓存功能(如 [页面缓存](page.md))的基础。" +msgid "Data caching is about storing some PHP variables in a cache and retrieving them later from the cache. It's also the foundation for more advanced caching features, such as page caching." +msgstr "数据缓存是将一些 PHP 变量存储在缓存中,然后稍后从缓存中检索它们。它也是更高级缓存功能(如 页面缓存)的基础。" #. type: Plain text #: ../../guide/en/caching/data.md @@ -98,8 +98,8 @@ msgstr "`ArrayCache` — 通过将值存储在数组中,仅为当前请求提 #. type: Bullet: '- ' #: ../../guide/en/caching/data.md -msgid "[APCu](https://github.com/yiisoft/cache-apcu) - uses a PHP [APC](https://secure.php.net/manual/en/book.apc.php) extension. You can consider this option as the fastest one when dealing with cache for a centralized thick application (e.g., one server, no dedicated load balancers, etc.)." -msgstr "[APCu](https://github.com/yiisoft/cache-apcu) - 使用 PHP [APC](https://secure.php.net/manual/en/book.apc.php) 扩展。在处理集中式厚应用程序(例如,单服务器,无专用负载均衡器等)的缓存时,您可以将此选项视为最快的选项。" +msgid "[APCu](https://github.com/yiisoft/cache-apcu) - uses a PHP [APC](https://www.php.net/manual/en/book.apcu.php) extension. You can consider this option as the fastest one when dealing with cache for a centralized thick application (e.g., one server, no dedicated load balancers, etc.)." +msgstr "[APCu](https://github.com/yiisoft/cache-apcu) - 使用 PHP [APC](https://www.php.net/manual/en/book.apcu.php) 扩展。在处理集中式厚应用程序(例如,单服务器,无专用负载均衡器等)的缓存时,您可以将此选项视为最快的选项。" #. type: Bullet: '- ' #: ../../guide/en/caching/data.md diff --git a/_translations/po/zh-CN/guide_caching_overview.md.po b/_translations/po/zh-CN/guide_caching_overview.md.po index 57ebf1f7..5af10747 100644 --- a/_translations/po/zh-CN/guide_caching_overview.md.po +++ b/_translations/po/zh-CN/guide_caching_overview.md.po @@ -43,15 +43,15 @@ msgstr "[数据缓存](data.md)" #. type: Bullet: '* ' #: ../src/guide/caching/overview.md -msgid "[Fragment caching](fragment.md)" -msgstr "[片段缓存](fragment.md)" +msgid "Fragment caching" +msgstr "片段缓存" #. type: Bullet: '* ' #: ../src/guide/caching/overview.md -msgid "[Page caching](page.md)" -msgstr "[页面缓存](page.md)" +msgid "Page caching" +msgstr "页面缓存" #. type: Bullet: '* ' #: ../src/guide/caching/overview.md -msgid "[HTTP caching](http.md)" -msgstr "[HTTP 缓存](http.md)" +msgid "HTTP caching" +msgstr "HTTP 缓存" diff --git a/_translations/po/zh-CN/guide_glossary.md.po b/_translations/po/zh-CN/guide_glossary.md.po index 4ab8d76b..928cce6c 100644 --- a/_translations/po/zh-CN/guide_glossary.md.po +++ b/_translations/po/zh-CN/guide_glossary.md.po @@ -487,7 +487,7 @@ msgstr "服务" #. type: Plain text #: ../src/guide/glossary.md -msgid "Service is a focused object that performs application work or provides infrastructure behavior and is usually stored in the DI container. Read more in [\"Service components\"](structure/service.md)." +msgid "Service is a focused object that performs application work or provides infrastructure behavior and is usually stored in the DI container. Read more in [\"Service components\"](../cookbook/organizing-code/service.md)." msgstr "" #. type: Title ## diff --git a/_translations/po/zh-CN/guide_security_best-practices.md.po b/_translations/po/zh-CN/guide_security_best-practices.md.po index e8afe6de..9b1ef40a 100644 --- a/_translations/po/zh-CN/guide_security_best-practices.md.po +++ b/_translations/po/zh-CN/guide_security_best-practices.md.po @@ -16,12 +16,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md -#: ../src/guide/concept/autoloading.md ../src/guide/concept/di-container.md -#: ../src/guide/security/best-practices.md ../src/guide/structure/domain.md -#: ../src/guide/tutorial/console-applications.md -#: ../src/internals/004-namespaces.md ../src/internals/007-exceptions.md -#: ../src/internals/008-interfaces.md +#: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md ../src/guide/concept/autoloading.md ../src/guide/concept/di-container.md ../src/guide/security/best-practices.md ../src/guide/structure/domain.md ../src/guide/tutorial/console-applications.md ../src/internals/004-namespaces.md ../src/internals/007-exceptions.md ../src/internals/008-interfaces.md #, no-wrap msgid "References" msgstr "参考资料" @@ -250,8 +245,8 @@ msgstr "" #. type: Plain text #: ../src/guide/security/best-practices.md -msgid "If it should be HTML, you could get some help from [HtmlPurifier](http://htmlpurifier.org/). Note that HtmlPurifier processing is quite heavy, so consider adding caching." -msgstr "如果它应该是 HTML,您可以从 [HtmlPurifier](http://htmlpurifier.org/) 获得一些帮助。请注意,HtmlPurifier 处理相当繁重,因此请考虑添加缓存。" +msgid "If it should be HTML, you could get some help from [HtmlPurifier](https://github.com/ezyang/htmlpurifier). Note that HtmlPurifier processing is quite heavy, so consider adding caching." +msgstr "如果它应该是 HTML,您可以从 [HtmlPurifier](https://github.com/ezyang/htmlpurifier) 获得一些帮助。请注意,HtmlPurifier 处理相当繁重,因此请考虑添加缓存。" #. type: Title ## #: ../src/guide/security/best-practices.md @@ -385,12 +380,12 @@ msgstr "除非必要,否则应避免在生产环境中使用调试工具栏。 #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md -msgid "" +msgid "" msgstr "" #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md -msgid "" +msgid "" msgstr "" #. type: Title ## diff --git a/_translations/po/zh-CN/guide_start_hello.md.po b/_translations/po/zh-CN/guide_start_hello.md.po index fdc2668a..fcbd1437 100644 --- a/_translations/po/zh-CN/guide_start_hello.md.po +++ b/_translations/po/zh-CN/guide_start_hello.md.po @@ -16,9 +16,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/cookbook/deployment/docker-swarm-caddy.md -#: ../src/cookbook/deployment/docker-swarm-traefik.md -#: ../src/guide/start/forms.md ../src/guide/start/hello.md +#: ../src/cookbook/deployment/docker-swarm-caddy.md ../src/cookbook/deployment/docker-swarm-traefik.md ../src/guide/start/forms.md ../src/guide/start/hello.md #, no-wrap msgid "Summary" msgstr "总结" @@ -42,8 +40,8 @@ msgstr "本节描述如何在应用程序中创建一个新的“Hello”页面 #. type: Plain text #: ../src/guide/start/hello.md -msgid "To achieve this goal, you will define a route and create [a handler](../structure/handler.md) that does the job and forms the response. Then you will improve it to use [view](../views/view.md) for building the response." -msgstr "为实现这个目标,您将定义一个路由并创建一个 [处理器](../structure/handler.md) 来完成工作并形成响应。然后您将改进它,使用[视图](../views/view.md)来构建响应。" +msgid "To achieve this goal, you will define a route and create [a handler](../structure/action.md) that does the job and forms the response. Then you will improve it to use [view](../views/view.md) for building the response." +msgstr "为实现这个目标,您将定义一个路由并创建一个 [处理器](../structure/action.md) 来完成工作并形成响应。然后您将改进它,使用[视图](../views/view.md)来构建响应。" #. type: Plain text #: ../src/guide/start/hello.md diff --git a/_translations/po/zh-CN/guide_structure_overview.md.po b/_translations/po/zh-CN/guide_structure_overview.md.po index 67b21cc7..e1db7a9b 100644 --- a/_translations/po/zh-CN/guide_structure_overview.md.po +++ b/_translations/po/zh-CN/guide_structure_overview.md.po @@ -16,8 +16,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/en/guide/structure/overview.md -#: ../src/en/guide/views/script-style-meta.md +#: ../src/en/guide/structure/overview.md ../src/en/guide/views/script-style-meta.md #, no-wrap msgid "Overview" msgstr "概述" @@ -152,8 +151,8 @@ msgstr "一个上下文可以包含子上下文。如果一个类被多个上下 #. type: Plain text #: ../src/en/guide/structure/overview.md -msgid "A context may have [an entry point known as \"action\" or \"controller\"](action.md). Its job is to take [a request instance](../runtime/request.md), pass it to [domain layer](domain.md) in a suitable format, and create [a response](../runtime/response.md) based on domain layer return." -msgstr "一个上下文可以有 [一个称为“动作”或“控制器”的入口点](action.md)。它的工作是获取[请求实例](../runtime/request.md),以适当的格式将其传递给 [领域层](domain.md),并根据领域层的返回创建 [响应](../runtime/response.md)。" +msgid "A context may have [an entry point known as \"action\" or \"controller\"](action.md). Its job is to take [a request instance](../runtime/request.md), pass it to [domain layer](../../cookbook/organizing-code/domain.md) in a suitable format, and create [a response](../runtime/response.md) based on domain layer return." +msgstr "一个上下文可以有 [一个称为“动作”或“控制器”的入口点](action.md)。它的工作是获取[请求实例](../runtime/request.md),以适当的格式将其传递给 [领域层](../../cookbook/organizing-code/domain.md),并根据领域层的返回创建 [响应](../runtime/response.md)。" #. type: Plain text #: ../src/en/guide/structure/overview.md @@ -167,8 +166,8 @@ msgstr "[入口脚本](entry-script.md):它们是最终用户可以直接访 #. type: Bullet: '* ' #: ../src/en/guide/structure/overview.md -msgid "[services](service.md): they're typically stateless objects registered within dependency container and provide various action methods." -msgstr "[服务](service.md):它们通常是在依赖容器中注册的无状态对象,并提供各种操作方法。" +msgid "[services](../../cookbook/organizing-code/service.md): they're typically stateless objects registered within dependency container and provide various action methods." +msgstr "[服务](../../cookbook/organizing-code/service.md):它们通常是在依赖容器中注册的无状态对象,并提供各种操作方法。" #. type: Bullet: '* ' #: ../src/en/guide/structure/overview.md diff --git a/_translations/po/zh-CN/internals_014-docs.md.po b/_translations/po/zh-CN/internals_014-docs.md.po index d0b52c1d..a58a2399 100644 --- a/_translations/po/zh-CN/internals_014-docs.md.po +++ b/_translations/po/zh-CN/internals_014-docs.md.po @@ -65,8 +65,8 @@ msgstr "权威指南" #. type: Plain text #: ../src/internals/014-docs.md -msgid "The definitive guide, [yiisoft/docs/guide](https://github.com/yiisoft/docs/tree/master/guide/en) aims at covering usage of packages as a whole framework. Unlike package documentation, it isn't focused on a single package but is covering certain use-cases." -msgstr "权威指南 [yiisoft/docs/guide](https://github.com/yiisoft/docs/tree/master/guide/en) 旨在涵盖作为整个框架的包的使用。与包文档不同,它不专注于单个包,而是涵盖某些用例。" +msgid "The definitive guide, [yiisoft/docs/guide](https://github.com/yiisoft/docs/tree/master/src/guide) aims at covering usage of packages as a whole framework. Unlike package documentation, it isn't focused on a single package but is covering certain use-cases." +msgstr "权威指南 [yiisoft/docs/guide](https://github.com/yiisoft/docs/tree/master/src/guide) 旨在涵盖作为整个框架的包的使用。与包文档不同,它不专注于单个包,而是涵盖某些用例。" #. type: Plain text #: ../src/internals/014-docs.md diff --git a/_translations/pot/cookbook_organizing-code_service.md.pot b/_translations/pot/cookbook_organizing-code_service.md.pot index 48c070d6..03958078 100644 --- a/_translations/pot/cookbook_organizing-code_service.md.pot +++ b/_translations/pot/cookbook_organizing-code_service.md.pot @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2026-10-11 10:37+0000\n" +"POT-Creation-Date: 2026-10-23 18:03+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -225,5 +225,5 @@ msgstr "" #. type: Bullet: '- ' #: ../src/cookbook/organizing-code/service.md -msgid "[Middleware](middleware.md)" +msgid "[Middleware](../../guide/structure/middleware.md)" msgstr "" diff --git a/_translations/pot/guide_caching_data.md.pot b/_translations/pot/guide_caching_data.md.pot index 5b8f8591..b99982f6 100644 --- a/_translations/pot/guide_caching_data.md.pot +++ b/_translations/pot/guide_caching_data.md.pot @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2025-09-11 10:15+0500\n" +"POT-Creation-Date: 2026-10-23 18:03+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,41 +17,41 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" #. type: Title # -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md #, no-wrap msgid "Data caching" msgstr "" #. type: Plain text -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md msgid "" "Data caching is about storing some PHP variables in a cache and retrieving " "them later from the cache. It's also the foundation for more advanced " -"caching features, such as [page caching](page.md)." +"caching features, such as page caching." msgstr "" #. type: Plain text -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md msgid "" "To use cache, install [yiisoft/cache](https://github.com/yiisoft/cache) " "package:" msgstr "" #. type: Fenced code block (shell) -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md #, no-wrap msgid "composer require yiisoft/cache\n" msgstr "" #. type: Plain text -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md msgid "" "The following code is a typical usage pattern of data caching, where " "`$cache` refers to a `Cache` instance from the package:" msgstr "" #. type: Fenced code block (php) -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md #, no-wrap msgid "" "public function getTopProducts(\\Yiisoft\\Cache\\CacheInterface $cache): array\n" @@ -69,7 +69,7 @@ msgid "" msgstr "" #. type: Plain text -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md msgid "" "When cache has data associated with the `$key`, it returns the cached " "value. Otherwise, it executes the passed anonymous function to calculate " @@ -77,20 +77,20 @@ msgid "" msgstr "" #. type: Plain text -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md msgid "" "If the anonymous function requires some data from the outer scope, you can " "pass it with the `use` statement." msgstr "" #. type: Title ## -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md #, no-wrap msgid "Cache handlers" msgstr "" #. type: Plain text -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md msgid "" "The cache service uses [PSR-16](https://www.php-fig.org/psr/psr-16/) " "compatible cache handlers which represent various cache storages, such as " @@ -98,12 +98,12 @@ msgid "" msgstr "" #. type: Plain text -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md msgid "Yii provides the following handlers:" msgstr "" #. type: Bullet: '- ' -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md msgid "" "`NullCache` — a cache placeholder which does no real caching. The purpose of " "this handler is to simplify the code that needs to check the availability of " @@ -115,30 +115,30 @@ msgid "" msgstr "" #. type: Bullet: '- ' -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md msgid "" "`ArrayCache` — provides caching for the current request only by storing the " "values in an array." msgstr "" #. type: Bullet: '- ' -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md msgid "" "[APCu](https://github.com/yiisoft/cache-apcu) - uses a PHP [APC](https://" -"secure.php.net/manual/en/book.apc.php) extension. You can consider this " +"www.php.net/manual/en/book.apcu.php) extension. You can consider this " "option as the fastest one when dealing with cache for a centralized thick " "application (e.g., one server, no dedicated load balancers, etc.)." msgstr "" #. type: Bullet: '- ' -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md msgid "" "[Database](https://github.com/yiisoft/cache-db) — uses a database table to " "store cached data." msgstr "" #. type: Bullet: '- ' -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md msgid "" "[File](https://github.com/yiisoft/cache-file) — uses standard files to store " "cached data. This is particularly suitable to cache large chunks of data, " @@ -146,7 +146,7 @@ msgid "" msgstr "" #. type: Bullet: '- ' -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md msgid "" "[Memcached](https://github.com/yiisoft/cache-memcached) — uses a PHP " "[memcached](https://secure.php.net/manual/en/book.memcached.php) extension. " @@ -155,7 +155,7 @@ msgid "" msgstr "" #. type: Plain text -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md #, no-wrap msgid "" " (e.g., with several servers, load balancers, etc.)\n" @@ -164,14 +164,14 @@ msgid "" msgstr "" #. type: Plain text -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md msgid "" "[You could find more handlers at packagist.org](https://packagist.org/" "providers/psr/simple-cache-implementation)." msgstr "" #. type: Plain text -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md #, no-wrap msgid "" "> [!TIP]\n" @@ -181,7 +181,7 @@ msgid "" msgstr "" #. type: Plain text -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md msgid "" "Cache handlers are usually set up in a [dependency injection container](../" "concept/di-container.md) so that they can be globally configurable and " @@ -189,7 +189,7 @@ msgid "" msgstr "" #. type: Plain text -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md msgid "" "Because all cache handlers support the same set of APIs, you can swap the " "underlying cache handler with a different one. You can do it by " @@ -197,13 +197,13 @@ msgid "" msgstr "" #. type: Title ### -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md #, no-wrap msgid "Cache keys" msgstr "" #. type: Plain text -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md msgid "" "A key uniquely identifies each data item stored in the cache. When you store " "a data item, you have to specify a key for it. Later, when you retrieve the " @@ -211,21 +211,21 @@ msgid "" msgstr "" #. type: Plain text -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md msgid "" "You may use a string or an arbitrary value as a cache key. When a key isn't " "a string, it will be automatically serialized into a string." msgstr "" #. type: Plain text -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md msgid "" "A common strategy of defining a cache key is to include all determining " "factors in terms of an array." msgstr "" #. type: Plain text -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md msgid "" "When different applications use the same cache storage, you should specify a " "unique cache key prefix for each application to avoid conflicts of cache " @@ -233,7 +233,7 @@ msgid "" msgstr "" #. type: Fenced code block (php) -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md #, no-wrap msgid "" "$arrayCacheWithPrefix = new \\Yiisoft\\Cache\\PrefixedCache(new \\Yiisoft\\Cache\\ArrayCache(), 'myapp_');\n" @@ -241,13 +241,13 @@ msgid "" msgstr "" #. type: Title ### -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md #, no-wrap msgid "Cache expiration" msgstr "" #. type: Plain text -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md msgid "" "A data item stored in a cache will remain there forever unless it's removed " "because of some caching policy enforcement. For example, caching space is " @@ -256,7 +256,7 @@ msgid "" msgstr "" #. type: Fenced code block (php) -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md #, no-wrap msgid "" "$ttl = 3600;\n" @@ -266,7 +266,7 @@ msgid "" msgstr "" #. type: Plain text -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md msgid "" "The `$ttl` parameter indicates for how many seconds the data item can remain " "valid in the cache. When you retrieve the data item, if it has passed the " @@ -275,35 +275,35 @@ msgid "" msgstr "" #. type: Plain text -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md msgid "You may set the default TTL for the cache:" msgstr "" #. type: Fenced code block (php) -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md #, no-wrap msgid "$cache = new \\Yiisoft\\Cache\\Cache($arrayCache, 60 * 60); // 1 hour\n" msgstr "" #. type: Plain text -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md msgid "Additionally, you can invalidate a cache key explicitly:" msgstr "" #. type: Fenced code block (php) -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md #, no-wrap msgid "$cache->remove($key);\n" msgstr "" #. type: Title ### -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md #, no-wrap msgid "Invalidation dependencies" msgstr "" #. type: Plain text -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md msgid "" "Besides the expiration setting, changes of the so-called **invalidation " "dependencies** may also invalidate cached data item. For example, " @@ -314,7 +314,7 @@ msgid "" msgstr "" #. type: Plain text -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md msgid "" "Cache dependencies are objects of `\\Yiisoft\\Cache\\Dependency\\Dependency` " "descendant classes. When you store a data item in the cache, you can pass " @@ -322,7 +322,7 @@ msgid "" msgstr "" #. type: Fenced code block (php) -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md #, no-wrap msgid "" "/**\n" @@ -341,33 +341,33 @@ msgid "" msgstr "" #. type: Plain text -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md msgid "Below is a summary of the available cache dependencies:" msgstr "" #. type: Bullet: '- ' -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md msgid "" "`\\Yiisoft\\Cache\\Dependency\\ValueDependency`: invalidates the cache when " "specified value changes." msgstr "" #. type: Bullet: '- ' -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md msgid "" "`\\Yiisoft\\Cache\\Dependency\\CallbackDependency`: invalidates the cache " "when the result of the specified PHP callback is different." msgstr "" #. type: Bullet: '- ' -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md msgid "" "`\\Yiisoft\\Cache\\Dependency\\FileDependency`: invalidates the cache when " "the file's last modification time is different." msgstr "" #. type: Bullet: '- ' -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md msgid "" "`\\Yiisoft\\Cache\\Dependency\\TagDependency`: associates a cached data item " "with one or many tags. You may invalidate the cached data items with the " @@ -375,7 +375,7 @@ msgid "" msgstr "" #. type: Plain text -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md msgid "" "You may combine many dependencies using " "`\\Yiisoft\\Cache\\Dependency\\AnyDependency` or " @@ -383,20 +383,20 @@ msgid "" msgstr "" #. type: Plain text -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md msgid "" "To implement your own dependency, extend from " "`\\Yiisoft\\Cache\\Dependency\\Dependency`." msgstr "" #. type: Title ### -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md #, no-wrap msgid "Cache stampede prevention" msgstr "" #. type: Plain text -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md msgid "" "[A cache stampede](https://en.wikipedia.org/wiki/Cache_stampede) is a type " "of cascading failure that can occur when massively parallel computing " @@ -405,7 +405,7 @@ msgid "" msgstr "" #. type: Plain text -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md msgid "" "The `\\Yiisoft\\Cache\\Cache` uses a built-in \"Probably early expiration\" " "algorithm that prevents cache stampede. This algorithm randomly fakes a " @@ -416,7 +416,7 @@ msgid "" msgstr "" #. type: Fenced code block (php) -#: ../../guide/en/caching/data.md +#: ../src/guide/caching/data.md #, no-wrap msgid "" "/**\n" diff --git a/_translations/pot/guide_caching_overview.md.pot b/_translations/pot/guide_caching_overview.md.pot index 05f5893f..b1578150 100644 --- a/_translations/pot/guide_caching_overview.md.pot +++ b/_translations/pot/guide_caching_overview.md.pot @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2025-12-24 08:23+0000\n" +"POT-Creation-Date: 2026-10-23 18:03+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -55,15 +55,15 @@ msgstr "" #. type: Bullet: '* ' #: ../src/guide/caching/overview.md -msgid "[Fragment caching](fragment.md)" +msgid "Fragment caching" msgstr "" #. type: Bullet: '* ' #: ../src/guide/caching/overview.md -msgid "[Page caching](page.md)" +msgid "Page caching" msgstr "" #. type: Bullet: '* ' #: ../src/guide/caching/overview.md -msgid "[HTTP caching](http.md)" +msgid "HTTP caching" msgstr "" diff --git a/_translations/pot/guide_glossary.md.pot b/_translations/pot/guide_glossary.md.pot index 146a2a64..0b5533f1 100644 --- a/_translations/pot/guide_glossary.md.pot +++ b/_translations/pot/guide_glossary.md.pot @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2026-05-30 06:43+0000\n" +"POT-Creation-Date: 2026-10-23 18:03+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -551,7 +551,7 @@ msgstr "" msgid "" "Service is a focused object that performs application work or provides " "infrastructure behavior and is usually stored in the DI container. Read " -"more in [\"Service components\"](structure/service.md)." +"more in [\"Service components\"](../cookbook/organizing-code/service.md)." msgstr "" #. type: Title ## diff --git a/_translations/pot/guide_security_best-practices.md.pot b/_translations/pot/guide_security_best-practices.md.pot index c1e37d3f..7575cd7b 100644 --- a/_translations/pot/guide_security_best-practices.md.pot +++ b/_translations/pot/guide_security_best-practices.md.pot @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2026-06-29 17:10+0000\n" +"POT-Creation-Date: 2026-10-23 18:03+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,9 +17,10 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## +#: ../src/cookbook/organizing-code/domain.md #: ../src/cookbook/organizing-code/structuring-by-use-case-with-vertical-slices.md #: ../src/guide/concept/autoloading.md ../src/guide/concept/di-container.md -#: ../src/guide/security/best-practices.md ../src/guide/structure/domain.md +#: ../src/guide/security/best-practices.md #: ../src/guide/tutorial/console-applications.md #: ../src/internals/004-namespaces.md ../src/internals/007-exceptions.md #: ../src/internals/008-interfaces.md @@ -272,9 +273,9 @@ msgstr "" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "" -"If it should be HTML, you could get some help from [HtmlPurifier](http://" -"htmlpurifier.org/). Note that HtmlPurifier processing is quite heavy, so " -"consider adding caching." +"If it should be HTML, you could get some help from [HtmlPurifier](https://" +"github.com/ezyang/htmlpurifier). Note that HtmlPurifier processing is quite " +"heavy, so consider adding caching." msgstr "" #. type: Title ## @@ -419,12 +420,14 @@ msgstr "" #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md -msgid "" +msgid "" +"" msgstr "" #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md -msgid "" +msgid "" msgstr "" #. type: Title ## diff --git a/_translations/pot/guide_start_hello.md.pot b/_translations/pot/guide_start_hello.md.pot index d3f7726c..53ea7256 100644 --- a/_translations/pot/guide_start_hello.md.pot +++ b/_translations/pot/guide_start_hello.md.pot @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2026-06-05 20:33+0000\n" +"POT-Creation-Date: 2026-10-23 18:03+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -48,7 +48,7 @@ msgstr "" #: ../src/guide/start/hello.md msgid "" "To achieve this goal, you will define a route and create [a handler](../" -"structure/handler.md) that does the job and forms the response. Then you " +"structure/action.md) that does the job and forms the response. Then you " "will improve it to use [view](../views/view.md) for building the response." msgstr "" diff --git a/_translations/pot/guide_structure_overview.md.pot b/_translations/pot/guide_structure_overview.md.pot index 1a624f5d..58ad2663 100644 --- a/_translations/pot/guide_structure_overview.md.pot +++ b/_translations/pot/guide_structure_overview.md.pot @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2025-12-24 08:02+0000\n" +"POT-Creation-Date: 2026-10-23 18:03+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,104 +17,103 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: ../src/en/guide/structure/overview.md -#: ../src/en/guide/views/script-style-meta.md +#: ../src/guide/structure/overview.md ../src/guide/views/script-style-meta.md #, no-wrap msgid "Overview" msgstr "" #. type: Plain text -#: ../src/en/guide/structure/overview.md +#: ../src/guide/structure/overview.md msgid "" "Yii applications code is typically grouped into modules by context. In each " "module there could be grouping by type." msgstr "" #. type: Plain text -#: ../src/en/guide/structure/overview.md +#: ../src/guide/structure/overview.md msgid "" "For example, if the application is an online store, the context could be:" msgstr "" #. type: Bullet: '- ' -#: ../src/en/guide/structure/overview.md +#: ../src/guide/structure/overview.md msgid "Customer" msgstr "" #. type: Bullet: ' - ' -#: ../src/en/guide/structure/overview.md +#: ../src/guide/structure/overview.md msgid "Profile" msgstr "" #. type: Bullet: ' - ' -#: ../src/en/guide/structure/overview.md +#: ../src/guide/structure/overview.md msgid "Products list" msgstr "" #. type: Bullet: ' - ' -#: ../src/en/guide/structure/overview.md +#: ../src/guide/structure/overview.md msgid "Checkout" msgstr "" #. type: Bullet: '- ' -#: ../src/en/guide/structure/overview.md +#: ../src/guide/structure/overview.md msgid "Logistics" msgstr "" #. type: Bullet: '- ' -#: ../src/en/guide/structure/overview.md +#: ../src/guide/structure/overview.md msgid "Delivery" msgstr "" #. type: Bullet: ' - ' -#: ../src/en/guide/structure/overview.md +#: ../src/guide/structure/overview.md msgid "Addresses" msgstr "" #. type: Bullet: '- ' -#: ../src/en/guide/structure/overview.md +#: ../src/guide/structure/overview.md msgid "Helpdesk" msgstr "" #. type: Bullet: ' - ' -#: ../src/en/guide/structure/overview.md +#: ../src/guide/structure/overview.md msgid "Support" msgstr "" #. type: Bullet: ' - ' -#: ../src/en/guide/structure/overview.md +#: ../src/guide/structure/overview.md msgid "Claims" msgstr "" #. type: Bullet: ' - ' -#: ../src/en/guide/structure/overview.md +#: ../src/guide/structure/overview.md msgid "Returns" msgstr "" #. type: Bullet: '- ' -#: ../src/en/guide/structure/overview.md +#: ../src/guide/structure/overview.md msgid "Accounting" msgstr "" #. type: Bullet: ' - ' -#: ../src/en/guide/structure/overview.md +#: ../src/guide/structure/overview.md msgid "Transactions" msgstr "" #. type: Bullet: ' - ' -#: ../src/en/guide/structure/overview.md +#: ../src/guide/structure/overview.md msgid "Taxes" msgstr "" #. type: Plain text -#: ../src/en/guide/structure/overview.md +#: ../src/guide/structure/overview.md msgid "" "For a \"Customer\" context, residing under `App\\Customer` namespace, " "structure would be:" msgstr "" #. type: Fenced code block -#: ../src/en/guide/structure/overview.md +#: ../src/guide/structure/overview.md #, no-wrap msgid "" "App/\n" @@ -136,28 +135,29 @@ msgid "" msgstr "" #. type: Plain text -#: ../src/en/guide/structure/overview.md +#: ../src/guide/structure/overview.md msgid "" "A context may include sub-contexts. If a class is shared by multiple " "contexts, it's moved to the ancestor of both contexts." msgstr "" #. type: Plain text -#: ../src/en/guide/structure/overview.md +#: ../src/guide/structure/overview.md msgid "" "A context may have [an entry point known as \"action\" or \"controller\"]" "(action.md). Its job is to take [a request instance](../runtime/request.md), " -"pass it to [domain layer](domain.md) in a suitable format, and create [a " -"response](../runtime/response.md) based on domain layer return." +"pass it to [domain layer](../../cookbook/organizing-code/domain.md) in a " +"suitable format, and create [a response](../runtime/response.md) based on " +"domain layer return." msgstr "" #. type: Plain text -#: ../src/en/guide/structure/overview.md +#: ../src/guide/structure/overview.md msgid "Besides, Yii applications also have the following:" msgstr "" #. type: Bullet: '* ' -#: ../src/en/guide/structure/overview.md +#: ../src/guide/structure/overview.md msgid "" "[entry scripts](entry-script.md): they're PHP scripts that are directly " "accessible by end users. They're responsible for starting a request " @@ -166,14 +166,15 @@ msgid "" msgstr "" #. type: Bullet: '* ' -#: ../src/en/guide/structure/overview.md +#: ../src/guide/structure/overview.md msgid "" -"[services](service.md): they're typically stateless objects registered " -"within dependency container and provide various action methods." +"[services](../../cookbook/organizing-code/service.md): they're typically " +"stateless objects registered within dependency container and provide various " +"action methods." msgstr "" #. type: Bullet: '* ' -#: ../src/en/guide/structure/overview.md +#: ../src/guide/structure/overview.md msgid "" "[middleware](middleware.md): they represent a code that needs to be invoked " "before and after the actual handling of each request by action handlers." diff --git a/_translations/pot/internals_014-docs.md.pot b/_translations/pot/internals_014-docs.md.pot index b46c2ade..eff7fb85 100644 --- a/_translations/pot/internals_014-docs.md.pot +++ b/_translations/pot/internals_014-docs.md.pot @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2026-05-05 22:22+0000\n" +"POT-Creation-Date: 2026-10-23 18:03+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -75,7 +75,7 @@ msgstr "" #: ../src/internals/014-docs.md msgid "" "The definitive guide, [yiisoft/docs/guide](https://github.com/yiisoft/docs/" -"tree/master/guide/en) aims at covering usage of packages as a whole " +"tree/master/src/guide) aims at covering usage of packages as a whole " "framework. Unlike package documentation, it isn't focused on a single " "package but is covering certain use-cases." msgstr "" diff --git a/src/cookbook/organizing-code/service.md b/src/cookbook/organizing-code/service.md index 725393c6..ddfe25c2 100644 --- a/src/cookbook/organizing-code/service.md +++ b/src/cookbook/organizing-code/service.md @@ -105,5 +105,5 @@ Often it makes sense to choose another class type to place your code into. Check - Repository - Widget -- [Middleware](middleware.md) +- [Middleware](../../guide/structure/middleware.md) - Entity diff --git a/src/es/cookbook/organizing-code/service.md b/src/es/cookbook/organizing-code/service.md index 0baee5d5..98a99d1d 100644 --- a/src/es/cookbook/organizing-code/service.md +++ b/src/es/cookbook/organizing-code/service.md @@ -115,5 +115,5 @@ into. Check: - Repository - Widget -- [Middleware](middleware.md) +- [Middleware](../../guide/structure/middleware.md) - Entity diff --git a/src/es/guide/caching/data.md b/src/es/guide/caching/data.md index 0b7d1a62..86d7aee1 100644 --- a/src/es/guide/caching/data.md +++ b/src/es/guide/caching/data.md @@ -2,7 +2,7 @@ Data caching is about storing some PHP variables in a cache and retrieving them later from the cache. It's also the foundation for more advanced -caching features, such as [page caching](page.md). +caching features, such as page caching. To use cache, install [yiisoft/cache](https://github.com/yiisoft/cache) package: @@ -54,7 +54,7 @@ Yii provides the following handlers: - `ArrayCache` — provides caching for the current request only by storing the values in an array. - [APCu](https://github.com/yiisoft/cache-apcu) - uses a PHP - [APC](https://secure.php.net/manual/en/book.apc.php) extension. You can + [APC](https://www.php.net/manual/en/book.apcu.php) extension. You can consider this option as the fastest one when dealing with cache for a centralized thick application (e.g., one server, no dedicated load balancers, etc.). diff --git a/src/es/guide/caching/overview.md b/src/es/guide/caching/overview.md index 2e2d4845..bf15f442 100644 --- a/src/es/guide/caching/overview.md +++ b/src/es/guide/caching/overview.md @@ -16,6 +16,6 @@ content in the browser cache. Yii supports all these caching mechanisms: * [Data caching](data.md) -* [Fragment caching](fragment.md) -* [Page caching](page.md) -* [HTTP caching](http.md) +* Fragment caching +* Page caching +* HTTP caching diff --git a/src/es/guide/glossary.md b/src/es/guide/glossary.md index bbf357a0..da4a6971 100644 --- a/src/es/guide/glossary.md +++ b/src/es/guide/glossary.md @@ -213,7 +213,7 @@ does the actual processing. Service is a focused object that performs application work or provides infrastructure behavior and is usually stored in the DI container. Read -more in ["Service components"](structure/service.md). +more in ["Service components"](../cookbook/organizing-code/service.md). ## service provider diff --git a/src/es/guide/security/best-practices.md b/src/es/guide/security/best-practices.md index 6f21dcaa..fc558947 100644 --- a/src/es/guide/security/best-practices.md +++ b/src/es/guide/security/best-practices.md @@ -121,8 +121,8 @@ If all you need is plain text, then escaping is as easy as the following: ``` If it should be HTML, you could get some help from -[HtmlPurifier](http://htmlpurifier.org/). Note that HtmlPurifier processing -is quite heavy, so consider adding caching. +[HtmlPurifier](https://github.com/ezyang/htmlpurifier). Note that +HtmlPurifier processing is quite heavy, so consider adding caching. Further reading on the topic: @@ -202,8 +202,8 @@ need it, check twice you restrict access to your IP only. Further reading on the topic: -- -- +- +- ## Using secure connection over TLS diff --git a/src/es/guide/start/hello.md b/src/es/guide/start/hello.md index d3e506e5..08eaf058 100644 --- a/src/es/guide/start/hello.md +++ b/src/es/guide/start/hello.md @@ -5,7 +5,7 @@ application. It's a simple page that will echo back whatever you pass to it or, if nothing passed, will just say "Hello!". To achieve this goal, you will define a route and create [a -handler](../structure/handler.md) that does the job and forms the response. +handler](../structure/action.md) that does the job and forms the response. Then you will improve it to use [view](../views/view.md) for building the response. diff --git a/src/es/guide/structure/overview.md b/src/es/guide/structure/overview.md index 3d8f5d9d..19195461 100644 --- a/src/es/guide/structure/overview.md +++ b/src/es/guide/structure/overview.md @@ -48,9 +48,9 @@ contexts, it's moved to the ancestor of both contexts. A context may have [an entry point known as "action" or "controller"](action.md). Its job is to take [a request -instance](../runtime/request.md), pass it to [domain layer](domain.md) in a -suitable format, and create [a response](../runtime/response.md) based on -domain layer return. +instance](../runtime/request.md), pass it to [domain +layer](../../cookbook/organizing-code/domain.md) in a suitable format, and +create [a response](../runtime/response.md) based on domain layer return. Besides, Yii applications also have the following: @@ -58,8 +58,9 @@ Besides, Yii applications also have the following: accessible by end users. They're responsible for starting a request handling cycle. Typically, a single entry script is handling the whole application. -* [services](service.md): they're typically stateless objects registered - within dependency container and provide various action methods. +* [services](../../cookbook/organizing-code/service.md): they're typically + stateless objects registered within dependency container and provide + various action methods. * [middleware](middleware.md): they represent a code that needs to be invoked before and after the actual handling of each request by action handlers. diff --git a/src/es/internals/014-docs.md b/src/es/internals/014-docs.md index 76c3ea24..88b83b32 100644 --- a/src/es/internals/014-docs.md +++ b/src/es/internals/014-docs.md @@ -21,7 +21,7 @@ keep documentation in the readme. ## Definitive guide The definitive guide, -[yiisoft/docs/guide](https://github.com/yiisoft/docs/tree/master/guide/en) +[yiisoft/docs/guide](https://github.com/yiisoft/docs/tree/master/src/guide) aims at covering usage of packages as a whole framework. Unlike package documentation, it isn't focused on a single package but is covering certain use-cases. diff --git a/src/guide/caching/data.md b/src/guide/caching/data.md index d8cede02..eecc5629 100644 --- a/src/guide/caching/data.md +++ b/src/guide/caching/data.md @@ -1,7 +1,7 @@ # Data caching Data caching is about storing some PHP variables in a cache and retrieving them later from the cache. -It's also the foundation for more advanced caching features, such as [page caching](page.md). +It's also the foundation for more advanced caching features, such as page caching. To use cache, install [yiisoft/cache](https://github.com/yiisoft/cache) package: @@ -45,7 +45,7 @@ Yii provides the following handlers: When you enable actual cache support, you can switch to using the corresponding cache handler. In both cases, you may use the same code without extra checks. - `ArrayCache` — provides caching for the current request only by storing the values in an array. -- [APCu](https://github.com/yiisoft/cache-apcu) - uses a PHP [APC](https://secure.php.net/manual/en/book.apc.php) extension. +- [APCu](https://github.com/yiisoft/cache-apcu) - uses a PHP [APC](https://www.php.net/manual/en/book.apcu.php) extension. You can consider this option as the fastest one when dealing with cache for a centralized thick application (e.g., one server, no dedicated load balancers, etc.). - [Database](https://github.com/yiisoft/cache-db) — uses a database table to store cached data. diff --git a/src/guide/caching/overview.md b/src/guide/caching/overview.md index f29003ba..c8a9c260 100644 --- a/src/guide/caching/overview.md +++ b/src/guide/caching/overview.md @@ -13,6 +13,6 @@ the browser cache. Yii supports all these caching mechanisms: * [Data caching](data.md) -* [Fragment caching](fragment.md) -* [Page caching](page.md) -* [HTTP caching](http.md) +* Fragment caching +* Page caching +* HTTP caching diff --git a/src/guide/glossary.md b/src/guide/glossary.md index db8a8084..dea668f0 100644 --- a/src/guide/glossary.md +++ b/src/guide/glossary.md @@ -196,7 +196,7 @@ It holds a set of parameters for checking if a data set is valid. Service is a focused object that performs application work or provides infrastructure behavior and is usually stored in the DI container. -Read more in ["Service components"](structure/service.md). +Read more in ["Service components"](../cookbook/organizing-code/service.md). ## service provider diff --git a/src/guide/security/best-practices.md b/src/guide/security/best-practices.md index 46ea87c6..3711cdf0 100644 --- a/src/guide/security/best-practices.md +++ b/src/guide/security/best-practices.md @@ -112,7 +112,7 @@ If all you need is plain text, then escaping is as easy as the following: ``` -If it should be HTML, you could get some help from [HtmlPurifier](http://htmlpurifier.org/). +If it should be HTML, you could get some help from [HtmlPurifier](https://github.com/ezyang/htmlpurifier). Note that HtmlPurifier processing is quite heavy, so consider adding caching. Further reading on the topic: @@ -186,8 +186,8 @@ If you absolutely need it, check twice you restrict access to your IP only. Further reading on the topic: -- -- +- +- ## Using secure connection over TLS diff --git a/src/guide/start/hello.md b/src/guide/start/hello.md index 63a96813..163f435e 100644 --- a/src/guide/start/hello.md +++ b/src/guide/start/hello.md @@ -3,7 +3,7 @@ This section describes how to create a new "Hello" page in your application. It's a simple page that will echo back whatever you pass to it or, if nothing passed, will just say "Hello!". -To achieve this goal, you will define a route and create [a handler](../structure/handler.md) that does the job and +To achieve this goal, you will define a route and create [a handler](../structure/action.md) that does the job and forms the response. Then you will improve it to use [view](../views/view.md) for building the response. diff --git a/src/guide/structure/overview.md b/src/guide/structure/overview.md index 12f08b22..6a367f67 100644 --- a/src/guide/structure/overview.md +++ b/src/guide/structure/overview.md @@ -45,7 +45,7 @@ A context may include sub-contexts. If a class is shared by multiple contexts, i both contexts. A context may have [an entry point known as "action" or "controller"](action.md). Its job is to take [a request -instance](../runtime/request.md), pass it to [domain layer](domain.md) in a suitable format, and create +instance](../runtime/request.md), pass it to [domain layer](../../cookbook/organizing-code/domain.md) in a suitable format, and create [a response](../runtime/response.md) based on domain layer return. Besides, Yii applications also have the following: @@ -53,7 +53,7 @@ Besides, Yii applications also have the following: * [entry scripts](entry-script.md): they're PHP scripts that are directly accessible by end users. They're responsible for starting a request handling cycle. Typically, a single entry script is handling the whole application. -* [services](service.md): they're typically stateless objects registered within dependency container and +* [services](../../cookbook/organizing-code/service.md): they're typically stateless objects registered within dependency container and provide various action methods. * [middleware](middleware.md): they represent a code that needs to be invoked before and after the actual handling of each request by action handlers. diff --git a/src/id/cookbook/organizing-code/service.md b/src/id/cookbook/organizing-code/service.md index 0baee5d5..98a99d1d 100644 --- a/src/id/cookbook/organizing-code/service.md +++ b/src/id/cookbook/organizing-code/service.md @@ -115,5 +115,5 @@ into. Check: - Repository - Widget -- [Middleware](middleware.md) +- [Middleware](../../guide/structure/middleware.md) - Entity diff --git a/src/id/guide/caching/data.md b/src/id/guide/caching/data.md index 87208252..99315768 100644 --- a/src/id/guide/caching/data.md +++ b/src/id/guide/caching/data.md @@ -3,7 +3,7 @@ Caching data adalah tentang menyimpan beberapa variabel PHP ke dalam cache dan mengambilnya kembali dari cache. Ini juga menjadi fondasi untuk fitur caching yang lebih lanjut, seperti -[caching halaman](page.md). +caching halaman. Untuk menggunakan cache, pasang paket [yiisoft/cache](https://github.com/yiisoft/cache): @@ -61,7 +61,7 @@ Yii menyediakan handler berikut: - `ArrayCache` — menyediakan caching hanya untuk permintaan saat ini dengan menyimpan nilai dalam sebuah array. - [APCu](https://github.com/yiisoft/cache-apcu) — menggunakan ekstensi PHP - [APC](https://secure.php.net/manual/en/book.apc.php). + [APC](https://www.php.net/manual/en/book.apcu.php). Ini bisa dianggap sebagai opsi tercepat saat berurusan dengan cache untuk aplikasi terpusat (mis., satu server, tanpa load balancer khusus, dll.). diff --git a/src/id/guide/caching/overview.md b/src/id/guide/caching/overview.md index c688cfba..6bd83331 100644 --- a/src/id/guide/caching/overview.md +++ b/src/id/guide/caching/overview.md @@ -20,6 +20,6 @@ di cache browser. Yii mendukung semua mekanisme caching berikut: * [Data caching](data.md) -* [Fragment caching](fragment.md) -* [Page caching](page.md) -* [HTTP caching](http.md) +* Fragment caching +* Page caching +* HTTP caching diff --git a/src/id/guide/glossary.md b/src/id/guide/glossary.md index bbf357a0..da4a6971 100644 --- a/src/id/guide/glossary.md +++ b/src/id/guide/glossary.md @@ -213,7 +213,7 @@ does the actual processing. Service is a focused object that performs application work or provides infrastructure behavior and is usually stored in the DI container. Read -more in ["Service components"](structure/service.md). +more in ["Service components"](../cookbook/organizing-code/service.md). ## service provider diff --git a/src/id/guide/security/best-practices.md b/src/id/guide/security/best-practices.md index cf194718..7b469c44 100644 --- a/src/id/guide/security/best-practices.md +++ b/src/id/guide/security/best-practices.md @@ -121,8 +121,8 @@ If all you need is plain text, then escaping is as easy as the following: ``` If it should be HTML, you could get some help from -[HtmlPurifier](http://htmlpurifier.org/). Note that HtmlPurifier processing -is quite heavy, so consider adding caching. +[HtmlPurifier](https://github.com/ezyang/htmlpurifier). Note that +HtmlPurifier processing is quite heavy, so consider adding caching. Further reading on the topic: @@ -202,8 +202,8 @@ need it, check twice you restrict access to your IP only. Further reading on the topic: -- -- +- +- ## Using secure connection over TLS diff --git a/src/id/guide/start/hello.md b/src/id/guide/start/hello.md index d3e506e5..08eaf058 100644 --- a/src/id/guide/start/hello.md +++ b/src/id/guide/start/hello.md @@ -5,7 +5,7 @@ application. It's a simple page that will echo back whatever you pass to it or, if nothing passed, will just say "Hello!". To achieve this goal, you will define a route and create [a -handler](../structure/handler.md) that does the job and forms the response. +handler](../structure/action.md) that does the job and forms the response. Then you will improve it to use [view](../views/view.md) for building the response. diff --git a/src/id/guide/structure/overview.md b/src/id/guide/structure/overview.md index 3d8f5d9d..19195461 100644 --- a/src/id/guide/structure/overview.md +++ b/src/id/guide/structure/overview.md @@ -48,9 +48,9 @@ contexts, it's moved to the ancestor of both contexts. A context may have [an entry point known as "action" or "controller"](action.md). Its job is to take [a request -instance](../runtime/request.md), pass it to [domain layer](domain.md) in a -suitable format, and create [a response](../runtime/response.md) based on -domain layer return. +instance](../runtime/request.md), pass it to [domain +layer](../../cookbook/organizing-code/domain.md) in a suitable format, and +create [a response](../runtime/response.md) based on domain layer return. Besides, Yii applications also have the following: @@ -58,8 +58,9 @@ Besides, Yii applications also have the following: accessible by end users. They're responsible for starting a request handling cycle. Typically, a single entry script is handling the whole application. -* [services](service.md): they're typically stateless objects registered - within dependency container and provide various action methods. +* [services](../../cookbook/organizing-code/service.md): they're typically + stateless objects registered within dependency container and provide + various action methods. * [middleware](middleware.md): they represent a code that needs to be invoked before and after the actual handling of each request by action handlers. diff --git a/src/id/internals/014-docs.md b/src/id/internals/014-docs.md index 76c3ea24..88b83b32 100644 --- a/src/id/internals/014-docs.md +++ b/src/id/internals/014-docs.md @@ -21,7 +21,7 @@ keep documentation in the readme. ## Definitive guide The definitive guide, -[yiisoft/docs/guide](https://github.com/yiisoft/docs/tree/master/guide/en) +[yiisoft/docs/guide](https://github.com/yiisoft/docs/tree/master/src/guide) aims at covering usage of packages as a whole framework. Unlike package documentation, it isn't focused on a single package but is covering certain use-cases. diff --git a/src/internals/014-docs.md b/src/internals/014-docs.md index 67e25716..b81d8747 100644 --- a/src/internals/014-docs.md +++ b/src/internals/014-docs.md @@ -17,7 +17,7 @@ If the total length of readme is less than about 200 lines, it's fine to keep do ## Definitive guide -The definitive guide, [yiisoft/docs/guide](https://github.com/yiisoft/docs/tree/master/guide/en) +The definitive guide, [yiisoft/docs/guide](https://github.com/yiisoft/docs/tree/master/src/guide) aims at covering usage of packages as a whole framework. Unlike package documentation, it isn't focused on a single package but is covering certain use-cases. diff --git a/src/it/cookbook/organizing-code/service.md b/src/it/cookbook/organizing-code/service.md index 0baee5d5..98a99d1d 100644 --- a/src/it/cookbook/organizing-code/service.md +++ b/src/it/cookbook/organizing-code/service.md @@ -115,5 +115,5 @@ into. Check: - Repository - Widget -- [Middleware](middleware.md) +- [Middleware](../../guide/structure/middleware.md) - Entity diff --git a/src/it/guide/caching/data.md b/src/it/guide/caching/data.md index 0b7d1a62..86d7aee1 100644 --- a/src/it/guide/caching/data.md +++ b/src/it/guide/caching/data.md @@ -2,7 +2,7 @@ Data caching is about storing some PHP variables in a cache and retrieving them later from the cache. It's also the foundation for more advanced -caching features, such as [page caching](page.md). +caching features, such as page caching. To use cache, install [yiisoft/cache](https://github.com/yiisoft/cache) package: @@ -54,7 +54,7 @@ Yii provides the following handlers: - `ArrayCache` — provides caching for the current request only by storing the values in an array. - [APCu](https://github.com/yiisoft/cache-apcu) - uses a PHP - [APC](https://secure.php.net/manual/en/book.apc.php) extension. You can + [APC](https://www.php.net/manual/en/book.apcu.php) extension. You can consider this option as the fastest one when dealing with cache for a centralized thick application (e.g., one server, no dedicated load balancers, etc.). diff --git a/src/it/guide/caching/overview.md b/src/it/guide/caching/overview.md index 2e2d4845..bf15f442 100644 --- a/src/it/guide/caching/overview.md +++ b/src/it/guide/caching/overview.md @@ -16,6 +16,6 @@ content in the browser cache. Yii supports all these caching mechanisms: * [Data caching](data.md) -* [Fragment caching](fragment.md) -* [Page caching](page.md) -* [HTTP caching](http.md) +* Fragment caching +* Page caching +* HTTP caching diff --git a/src/it/guide/glossary.md b/src/it/guide/glossary.md index bbf357a0..da4a6971 100644 --- a/src/it/guide/glossary.md +++ b/src/it/guide/glossary.md @@ -213,7 +213,7 @@ does the actual processing. Service is a focused object that performs application work or provides infrastructure behavior and is usually stored in the DI container. Read -more in ["Service components"](structure/service.md). +more in ["Service components"](../cookbook/organizing-code/service.md). ## service provider diff --git a/src/it/guide/security/best-practices.md b/src/it/guide/security/best-practices.md index 32ae9410..7be3f38b 100644 --- a/src/it/guide/security/best-practices.md +++ b/src/it/guide/security/best-practices.md @@ -121,8 +121,8 @@ If all you need is plain text, then escaping is as easy as the following: ``` If it should be HTML, you could get some help from -[HtmlPurifier](http://htmlpurifier.org/). Note that HtmlPurifier processing -is quite heavy, so consider adding caching. +[HtmlPurifier](https://github.com/ezyang/htmlpurifier). Note that +HtmlPurifier processing is quite heavy, so consider adding caching. Further reading on the topic: @@ -202,8 +202,8 @@ need it, check twice you restrict access to your IP only. Further reading on the topic: -- -- +- +- ## Using secure connection over TLS diff --git a/src/it/guide/start/hello.md b/src/it/guide/start/hello.md index f4bba8d2..075434ef 100644 --- a/src/it/guide/start/hello.md +++ b/src/it/guide/start/hello.md @@ -5,7 +5,7 @@ applicazione. È una pagina semplice che restituirà tutto ciò che le passi o, se non viene passato nulla, dirà semplicemente "Hello!". Per raggiungere questo obiettivo, definirai una rotta e creerai [un gestore -di richieste](../structure/handler.md) che esegue il lavoro e forma la +di richieste](../structure/action.md) che esegue il lavoro e forma la risposta. Poi lo migliorerai per usare [una vista](../views/view.md) per costruire la risposta. diff --git a/src/it/guide/structure/overview.md b/src/it/guide/structure/overview.md index 3d8f5d9d..19195461 100644 --- a/src/it/guide/structure/overview.md +++ b/src/it/guide/structure/overview.md @@ -48,9 +48,9 @@ contexts, it's moved to the ancestor of both contexts. A context may have [an entry point known as "action" or "controller"](action.md). Its job is to take [a request -instance](../runtime/request.md), pass it to [domain layer](domain.md) in a -suitable format, and create [a response](../runtime/response.md) based on -domain layer return. +instance](../runtime/request.md), pass it to [domain +layer](../../cookbook/organizing-code/domain.md) in a suitable format, and +create [a response](../runtime/response.md) based on domain layer return. Besides, Yii applications also have the following: @@ -58,8 +58,9 @@ Besides, Yii applications also have the following: accessible by end users. They're responsible for starting a request handling cycle. Typically, a single entry script is handling the whole application. -* [services](service.md): they're typically stateless objects registered - within dependency container and provide various action methods. +* [services](../../cookbook/organizing-code/service.md): they're typically + stateless objects registered within dependency container and provide + various action methods. * [middleware](middleware.md): they represent a code that needs to be invoked before and after the actual handling of each request by action handlers. diff --git a/src/it/internals/014-docs.md b/src/it/internals/014-docs.md index 76c3ea24..88b83b32 100644 --- a/src/it/internals/014-docs.md +++ b/src/it/internals/014-docs.md @@ -21,7 +21,7 @@ keep documentation in the readme. ## Definitive guide The definitive guide, -[yiisoft/docs/guide](https://github.com/yiisoft/docs/tree/master/guide/en) +[yiisoft/docs/guide](https://github.com/yiisoft/docs/tree/master/src/guide) aims at covering usage of packages as a whole framework. Unlike package documentation, it isn't focused on a single package but is covering certain use-cases. diff --git a/src/pt-BR/cookbook/organizing-code/service.md b/src/pt-BR/cookbook/organizing-code/service.md index efd1506d..e2a1c994 100644 --- a/src/pt-BR/cookbook/organizing-code/service.md +++ b/src/pt-BR/cookbook/organizing-code/service.md @@ -117,5 +117,5 @@ código. Confira: - Repositório - Widget -- [Middleware](middleware.md) +- [Middleware](../../guide/structure/middleware.md) - Entidade diff --git a/src/pt-BR/guide/caching/data.md b/src/pt-BR/guide/caching/data.md index 1e69b953..6fd8e6c8 100644 --- a/src/pt-BR/guide/caching/data.md +++ b/src/pt-BR/guide/caching/data.md @@ -2,7 +2,7 @@ O cache de dados consiste em guardar algumas variáveis PHP no cache e recuperá-las dele mais tarde. Ele também é a base para recursos de cache -mais avançados, como o [cache de páginas](page.md). +mais avançados, como o cache de páginas. Para usar o cache, instale o pacote [yiisoft/cache](https://github.com/yiisoft/cache): @@ -54,7 +54,7 @@ O Yii fornece os seguintes drivers: - `ArrayCache` — faz cache apenas durante a requisição atual, guardando os valores em um array. - [APCu](https://github.com/yiisoft/cache-apcu) - usa a extensão - [APC](https://secure.php.net/manual/en/book.apc.php) do PHP. Você pode + [APC](https://www.php.net/manual/en/book.apcu.php) do PHP. Você pode considerar esta a opção mais rápida ao lidar com cache em uma aplicação centralizada e robusta (por exemplo, um servidor, sem load balancers dedicados etc.). diff --git a/src/pt-BR/guide/caching/overview.md b/src/pt-BR/guide/caching/overview.md index e2772151..67763a49 100644 --- a/src/pt-BR/guide/caching/overview.md +++ b/src/pt-BR/guide/caching/overview.md @@ -17,6 +17,6 @@ cache do navegador. O Yii suporta todos estes mecanismos de cache: * [Cache de dados](data.md) -* [Cache de fragmentos](fragment.md) -* [Cache de páginas](page.md) -* [Cache HTTP](http.md) +* Cache de fragmentos +* Cache de páginas +* Cache HTTP diff --git a/src/pt-BR/guide/glossary.md b/src/pt-BR/guide/glossary.md index 21f0518e..d726d331 100644 --- a/src/pt-BR/guide/glossary.md +++ b/src/pt-BR/guide/glossary.md @@ -226,7 +226,8 @@ conjunto de parâmetros para verificar se um conjunto de dados é válido. O Serviço é um objeto focado que realiza trabalho da aplicação ou fornece comportamento de infraestrutura e normalmente fica registrado no container -de DI. Leia mais em ["Componentes de serviço"](structure/service.md). +de DI. Leia mais em ["Componentes de +serviço"](../cookbook/organizing-code/service.md). ## service provider (provedor de serviços) diff --git a/src/pt-BR/guide/security/best-practices.md b/src/pt-BR/guide/security/best-practices.md index 78601e80..a4fb35fe 100644 --- a/src/pt-BR/guide/security/best-practices.md +++ b/src/pt-BR/guide/security/best-practices.md @@ -123,8 +123,8 @@ seguinte: ``` Se precisar ser HTML, você pode ter a ajuda do -[HtmlPurifier](http://htmlpurifier.org/). Note que o processamento do -HtmlPurifier é bem pesado, então considere usar cache. +[HtmlPurifier](https://github.com/ezyang/htmlpurifier). Note que o +processamento do HtmlPurifier é bem pesado, então considere usar cache. Leitura adicional sobre o assunto: @@ -206,8 +206,8 @@ ao seu IP. Leitura adicional sobre o assunto: -- -- +- +- ## Usando conexão segura via TLS diff --git a/src/pt-BR/guide/start/hello.md b/src/pt-BR/guide/start/hello.md index 741fcfc7..9d13038d 100644 --- a/src/pt-BR/guide/start/hello.md +++ b/src/pt-BR/guide/start/hello.md @@ -5,7 +5,7 @@ uma página simples que devolve o que você passar para ela ou, se nada for passado, apenas diz "Hello!". Para isso, você vai definir uma rota e criar [um -handler](../structure/handler.md) que faz o trabalho e monta a resposta. +handler](../structure/action.md) que faz o trabalho e monta a resposta. Depois, vai melhorá-lo para usar uma [view](../views/view.md) na construção da resposta. diff --git a/src/pt-BR/guide/structure/overview.md b/src/pt-BR/guide/structure/overview.md index 4f17ec2b..a746d45f 100644 --- a/src/pt-BR/guide/structure/overview.md +++ b/src/pt-BR/guide/structure/overview.md @@ -49,8 +49,9 @@ vários contextos, ela é movida para o ancestral comum desses contextos. Um contexto pode ter [um ponto de entrada conhecido como "action" ou "controller"](action.md). A função dele é receber [uma instância de requisição](../runtime/request.md), passá-la para a [camada de -domínio](domain.md) em um formato adequado e criar [uma -resposta](../runtime/response.md) com base no retorno da camada de domínio. +domínio](../../cookbook/organizing-code/domain.md) em um formato adequado e +criar [uma resposta](../runtime/response.md) com base no retorno da camada +de domínio. Além disso, aplicações Yii também têm o seguinte: @@ -58,8 +59,9 @@ Além disso, aplicações Yii também têm o seguinte: diretamente pelos usuários finais. Eles são responsáveis por iniciar um ciclo de tratamento de requisição. Normalmente, um único script de entrada atende a aplicação inteira. -* [serviços](service.md): normalmente são objetos sem estado registrados no - container de dependências que fornecem diversos métodos de ação. +* [serviços](../../cookbook/organizing-code/service.md): normalmente são + objetos sem estado registrados no container de dependências que fornecem + diversos métodos de ação. * [middleware](middleware.md): representam código que precisa ser executado antes e depois do tratamento efetivo de cada requisição pelos handlers de action. diff --git a/src/pt-BR/internals/014-docs.md b/src/pt-BR/internals/014-docs.md index 4c65146b..130eb6ec 100644 --- a/src/pt-BR/internals/014-docs.md +++ b/src/pt-BR/internals/014-docs.md @@ -21,7 +21,7 @@ problema em manter a documentação no readme. ## Guia definitivo O guia definitivo, -[yiisoft/docs/guide](https://github.com/yiisoft/docs/tree/master/guide/en) +[yiisoft/docs/guide](https://github.com/yiisoft/docs/tree/master/src/guide) tem como objetivo cobrir o uso dos pacotes como um framework completo. Diferente da documentação dos pacotes, ele não se concentra em um único pacote, e sim em determinados casos de uso. diff --git a/src/ru/cookbook/organizing-code/service.md b/src/ru/cookbook/organizing-code/service.md index f0a09a4d..1a1517c1 100644 --- a/src/ru/cookbook/organizing-code/service.md +++ b/src/ru/cookbook/organizing-code/service.md @@ -115,5 +115,5 @@ into. Check: - Репозиторий - Widget -- [Middleware](middleware.md) +- [Middleware](../../guide/structure/middleware.md) - Entity diff --git a/src/ru/guide/caching/data.md b/src/ru/guide/caching/data.md index 0b7d1a62..86d7aee1 100644 --- a/src/ru/guide/caching/data.md +++ b/src/ru/guide/caching/data.md @@ -2,7 +2,7 @@ Data caching is about storing some PHP variables in a cache and retrieving them later from the cache. It's also the foundation for more advanced -caching features, such as [page caching](page.md). +caching features, such as page caching. To use cache, install [yiisoft/cache](https://github.com/yiisoft/cache) package: @@ -54,7 +54,7 @@ Yii provides the following handlers: - `ArrayCache` — provides caching for the current request only by storing the values in an array. - [APCu](https://github.com/yiisoft/cache-apcu) - uses a PHP - [APC](https://secure.php.net/manual/en/book.apc.php) extension. You can + [APC](https://www.php.net/manual/en/book.apcu.php) extension. You can consider this option as the fastest one when dealing with cache for a centralized thick application (e.g., one server, no dedicated load balancers, etc.). diff --git a/src/ru/guide/caching/overview.md b/src/ru/guide/caching/overview.md index 2e2d4845..bf15f442 100644 --- a/src/ru/guide/caching/overview.md +++ b/src/ru/guide/caching/overview.md @@ -16,6 +16,6 @@ content in the browser cache. Yii supports all these caching mechanisms: * [Data caching](data.md) -* [Fragment caching](fragment.md) -* [Page caching](page.md) -* [HTTP caching](http.md) +* Fragment caching +* Page caching +* HTTP caching diff --git a/src/ru/guide/glossary.md b/src/ru/guide/glossary.md index bbf357a0..da4a6971 100644 --- a/src/ru/guide/glossary.md +++ b/src/ru/guide/glossary.md @@ -213,7 +213,7 @@ does the actual processing. Service is a focused object that performs application work or provides infrastructure behavior and is usually stored in the DI container. Read -more in ["Service components"](structure/service.md). +more in ["Service components"](../cookbook/organizing-code/service.md). ## service provider diff --git a/src/ru/guide/security/best-practices.md b/src/ru/guide/security/best-practices.md index 0507a75f..c03e3170 100644 --- a/src/ru/guide/security/best-practices.md +++ b/src/ru/guide/security/best-practices.md @@ -122,7 +122,7 @@ XSS или кросс-сайтинговый скриптинг становит ``` Если нужно вывести HTML, вам лучше воспользоваться -[HtmlPurifier](http://htmlpurifier.org/). +[HtmlPurifier](https://github.com/ezyang/htmlpurifier). Обратите внимание, что обработка с помощью HtmlPurifier довольно тяжела, поэтому рассмотрите возможность использования кеширования. @@ -211,8 +211,8 @@ token-in-form. Дополнительная информация по теме: -- -- +- +- ## Использование безопасного подключения через TLS diff --git a/src/ru/guide/start/hello.md b/src/ru/guide/start/hello.md index 26326214..16b28fa4 100644 --- a/src/ru/guide/start/hello.md +++ b/src/ru/guide/start/hello.md @@ -5,7 +5,7 @@ ничего не передано — просто говорит «Hello!». Чтобы этого добиться, вы определите маршрут и создадите -[обработчик](../structure/handler.md), который выполнит задачу и сформирует +[обработчик](../structure/action.md), который выполнит задачу и сформирует ответ. Затем вы улучшите решение, используя [представление](../views/view.md) для построения ответа. diff --git a/src/ru/guide/structure/overview.md b/src/ru/guide/structure/overview.md index 3d8f5d9d..19195461 100644 --- a/src/ru/guide/structure/overview.md +++ b/src/ru/guide/structure/overview.md @@ -48,9 +48,9 @@ contexts, it's moved to the ancestor of both contexts. A context may have [an entry point known as "action" or "controller"](action.md). Its job is to take [a request -instance](../runtime/request.md), pass it to [domain layer](domain.md) in a -suitable format, and create [a response](../runtime/response.md) based on -domain layer return. +instance](../runtime/request.md), pass it to [domain +layer](../../cookbook/organizing-code/domain.md) in a suitable format, and +create [a response](../runtime/response.md) based on domain layer return. Besides, Yii applications also have the following: @@ -58,8 +58,9 @@ Besides, Yii applications also have the following: accessible by end users. They're responsible for starting a request handling cycle. Typically, a single entry script is handling the whole application. -* [services](service.md): they're typically stateless objects registered - within dependency container and provide various action methods. +* [services](../../cookbook/organizing-code/service.md): they're typically + stateless objects registered within dependency container and provide + various action methods. * [middleware](middleware.md): they represent a code that needs to be invoked before and after the actual handling of each request by action handlers. diff --git a/src/ru/internals/014-docs.md b/src/ru/internals/014-docs.md index 76c3ea24..88b83b32 100644 --- a/src/ru/internals/014-docs.md +++ b/src/ru/internals/014-docs.md @@ -21,7 +21,7 @@ keep documentation in the readme. ## Definitive guide The definitive guide, -[yiisoft/docs/guide](https://github.com/yiisoft/docs/tree/master/guide/en) +[yiisoft/docs/guide](https://github.com/yiisoft/docs/tree/master/src/guide) aims at covering usage of packages as a whole framework. Unlike package documentation, it isn't focused on a single package but is covering certain use-cases. diff --git a/src/zh-CN/cookbook/organizing-code/service.md b/src/zh-CN/cookbook/organizing-code/service.md index 0b1a7efe..54b0c80a 100644 --- a/src/zh-CN/cookbook/organizing-code/service.md +++ b/src/zh-CN/cookbook/organizing-code/service.md @@ -115,5 +115,5 @@ into. Check: - 仓库 - Widget -- [Middleware](middleware.md) +- [Middleware](../../guide/structure/middleware.md) - Entity diff --git a/src/zh-CN/guide/caching/data.md b/src/zh-CN/guide/caching/data.md index ef1f0590..e2850591 100644 --- a/src/zh-CN/guide/caching/data.md +++ b/src/zh-CN/guide/caching/data.md @@ -1,6 +1,6 @@ # 数据缓存 -数据缓存是将一些 PHP 变量存储在缓存中,然后稍后从缓存中检索它们。它也是更高级缓存功能(如 [页面缓存](page.md))的基础。 +数据缓存是将一些 PHP 变量存储在缓存中,然后稍后从缓存中检索它们。它也是更高级缓存功能(如 页面缓存)的基础。 要使用缓存,请安装 [yiisoft/cache](https://github.com/yiisoft/cache) 包: @@ -40,7 +40,7 @@ Yii 提供以下处理器: 一个不进行实际缓存的缓存占位符。此处理器的目的是简化需要检查缓存可用性的代码。例如,在开发期间或服务器没有实际缓存支持时,您可以配置缓存服务使用此处理器。当您启用实际缓存支持时,可以切换到使用相应的缓存处理器。在这两种情况下,您都可以使用相同的代码而无需额外检查。 - `ArrayCache` — 通过将值存储在数组中,仅为当前请求提供缓存。 - [APCu](https://github.com/yiisoft/cache-apcu) - 使用 PHP - [APC](https://secure.php.net/manual/en/book.apc.php) + [APC](https://www.php.net/manual/en/book.apcu.php) 扩展。在处理集中式厚应用程序(例如,单服务器,无专用负载均衡器等)的缓存时,您可以将此选项视为最快的选项。 - [数据库](https://github.com/yiisoft/cache-db) — 使用数据库表存储缓存数据。 - [文件](https://github.com/yiisoft/cache-file) — diff --git a/src/zh-CN/guide/caching/overview.md b/src/zh-CN/guide/caching/overview.md index a4273809..2b6ac6ef 100644 --- a/src/zh-CN/guide/caching/overview.md +++ b/src/zh-CN/guide/caching/overview.md @@ -8,6 +8,6 @@ Web 页面的片段或整体,例如最新文章的渲染结果。在客户端 Yii 支持所有这些缓存机制: * [数据缓存](data.md) -* [片段缓存](fragment.md) -* [页面缓存](page.md) -* [HTTP 缓存](http.md) +* 片段缓存 +* 页面缓存 +* HTTP 缓存 diff --git a/src/zh-CN/guide/glossary.md b/src/zh-CN/guide/glossary.md index de20d887..b466663f 100644 --- a/src/zh-CN/guide/glossary.md +++ b/src/zh-CN/guide/glossary.md @@ -202,7 +202,7 @@ generation"](runtime/routing.md). Service is a focused object that performs application work or provides infrastructure behavior and is usually stored in the DI container. Read -more in ["Service components"](structure/service.md). +more in ["Service components"](../cookbook/organizing-code/service.md). ## service provider diff --git a/src/zh-CN/guide/security/best-practices.md b/src/zh-CN/guide/security/best-practices.md index fb0010d5..72cd11d6 100644 --- a/src/zh-CN/guide/security/best-practices.md +++ b/src/zh-CN/guide/security/best-practices.md @@ -105,7 +105,7 @@ XSS 或跨站脚本攻击发生在向浏览器输出 HTML 时输出未正确转 ``` -如果它应该是 HTML,您可以从 [HtmlPurifier](http://htmlpurifier.org/) +如果它应该是 HTML,您可以从 [HtmlPurifier](https://github.com/ezyang/htmlpurifier) 获得一些帮助。请注意,HtmlPurifier 处理相当繁重,因此请考虑添加缓存。 有关该主题的进一步阅读: @@ -175,8 +175,8 @@ token-in-form. 有关该主题的进一步阅读: -- -- +- +- ## 通过 TLS 使用安全连接 diff --git a/src/zh-CN/guide/start/hello.md b/src/zh-CN/guide/start/hello.md index b9c77ce9..a24d7127 100644 --- a/src/zh-CN/guide/start/hello.md +++ b/src/zh-CN/guide/start/hello.md @@ -2,7 +2,7 @@ 本节描述如何在应用程序中创建一个新的“Hello”页面。这是一个简单的页面,它会回显您传递给它的任何内容,或者如果没有传递任何内容,则显示“Hello!”。 -为实现这个目标,您将定义一个路由并创建一个 [处理器](../structure/handler.md) +为实现这个目标,您将定义一个路由并创建一个 [处理器](../structure/action.md) 来完成工作并形成响应。然后您将改进它,使用[视图](../views/view.md)来构建响应。 通过本教程,您将学习三件事: diff --git a/src/zh-CN/guide/structure/overview.md b/src/zh-CN/guide/structure/overview.md index 08893e15..e3f120d9 100644 --- a/src/zh-CN/guide/structure/overview.md +++ b/src/zh-CN/guide/structure/overview.md @@ -45,11 +45,12 @@ App/ 一个上下文可以有 [一个称为“动作”或“控制器”的入口点](action.md)。它的工作是获取[请求实例](../runtime/request.md),以适当的格式将其传递给 -[领域层](domain.md),并根据领域层的返回创建 [响应](../runtime/response.md)。 +[领域层](../../cookbook/organizing-code/domain.md),并根据领域层的返回创建 +[响应](../runtime/response.md)。 此外,Yii 应用程序还具有以下内容: * [入口脚本](entry-script.md):它们是最终用户可以直接访问的 PHP 脚本。它们负责启动请求处理周期。通常,单个入口脚本处理整个应用程序。 -* [服务](service.md):它们通常是在依赖容器中注册的无状态对象,并提供各种操作方法。 +* [服务](../../cookbook/organizing-code/service.md):它们通常是在依赖容器中注册的无状态对象,并提供各种操作方法。 * [中间件](middleware.md):它们表示需要在操作处理器实际处理每个请求之前和之后调用的代码。 diff --git a/src/zh-CN/internals/014-docs.md b/src/zh-CN/internals/014-docs.md index 96d7cd16..1f63bea8 100644 --- a/src/zh-CN/internals/014-docs.md +++ b/src/zh-CN/internals/014-docs.md @@ -17,7 +17,7 @@ ## 权威指南 权威指南 -[yiisoft/docs/guide](https://github.com/yiisoft/docs/tree/master/guide/en) +[yiisoft/docs/guide](https://github.com/yiisoft/docs/tree/master/src/guide) 旨在涵盖作为整个框架的包的使用。与包文档不同,它不专注于单个包,而是涵盖某些用例。 指南应遵循 [Microsoft From 666ae240b0c27f4a363176cacbad1144a30ce1dd Mon Sep 17 00:00:00 2001 From: Yuri Neves Date: Fri, 23 Oct 2026 15:33:47 -0300 Subject: [PATCH 11/11] Add explicit ids to pt-BR headings with accented anchors --- .../po/pt-BR/cookbook_custom-hydrator-type-casters.md.po | 4 ++-- _translations/po/pt-BR/guide_tutorial_i18n.md.po | 2 +- _translations/po/pt-BR/internals_001-yii-values.md.po | 6 +++--- src/pt-BR/cookbook/custom-hydrator-type-casters.md | 4 ++-- src/pt-BR/guide/tutorial/i18n.md | 2 +- src/pt-BR/internals/001-yii-values.md | 6 +++--- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/_translations/po/pt-BR/cookbook_custom-hydrator-type-casters.md.po b/_translations/po/pt-BR/cookbook_custom-hydrator-type-casters.md.po index bd045858..29c87b64 100644 --- a/_translations/po/pt-BR/cookbook_custom-hydrator-type-casters.md.po +++ b/_translations/po/pt-BR/cookbook_custom-hydrator-type-casters.md.po @@ -791,7 +791,7 @@ msgstr "" #: ../src/cookbook/custom-hydrator-type-casters.md #, no-wrap msgid "Request input" -msgstr "Entrada da requisição" +msgstr "Entrada da requisição " #. type: Plain text #: ../src/cookbook/custom-hydrator-type-casters.md @@ -995,7 +995,7 @@ msgstr "" #: ../src/cookbook/custom-hydrator-type-casters.md #, no-wrap msgid "Null and invalid values" -msgstr "Valores nulos e inválidos" +msgstr "Valores nulos e inválidos " #. type: Plain text #: ../src/cookbook/custom-hydrator-type-casters.md diff --git a/_translations/po/pt-BR/guide_tutorial_i18n.md.po b/_translations/po/pt-BR/guide_tutorial_i18n.md.po index 7e4039b0..eb19ba66 100644 --- a/_translations/po/pt-BR/guide_tutorial_i18n.md.po +++ b/_translations/po/pt-BR/guide_tutorial_i18n.md.po @@ -448,7 +448,7 @@ msgstr "Escape o texto traduzido antes de exibi-lo. Guarde HTML confiável separ #: ../src/guide/tutorial/i18n.md #, no-wrap msgid "Choosing locale per request" -msgstr "Escolhendo o idioma por requisição" +msgstr "Escolhendo o idioma por requisição " #. type: Plain text #: ../src/guide/tutorial/i18n.md diff --git a/_translations/po/pt-BR/internals_001-yii-values.md.po b/_translations/po/pt-BR/internals_001-yii-values.md.po index b804715f..edf50d94 100644 --- a/_translations/po/pt-BR/internals_001-yii-values.md.po +++ b/_translations/po/pt-BR/internals_001-yii-values.md.po @@ -100,7 +100,7 @@ msgstr "Desempenho é uma condição necessária para a praticidade. O software #: ../src/en/internals/001-yii-values.md #, no-wrap msgid "Sensible defaults and flexibility" -msgstr "Padrões sensatos e flexibilidade" +msgstr "Padrões sensatos e flexibilidade " #. type: Plain text #: ../src/en/internals/001-yii-values.md @@ -111,7 +111,7 @@ msgstr "Preferimos padrões e convenções sensatos que os usuários possam pers #: ../src/en/internals/001-yii-values.md #, no-wrap msgid "Be practice-oriented" -msgstr "Ser orientado à prática" +msgstr "Ser orientado à prática " #. type: Plain text #: ../src/en/internals/001-yii-values.md @@ -178,7 +178,7 @@ msgstr "Menos regras é melhor do que mais regras." #: ../src/en/internals/001-yii-values.md #, no-wrap msgid "Be Explicit" -msgstr "Ser explícito" +msgstr "Ser explícito " #. type: Plain text #: ../src/en/internals/001-yii-values.md diff --git a/src/pt-BR/cookbook/custom-hydrator-type-casters.md b/src/pt-BR/cookbook/custom-hydrator-type-casters.md index 1448c31a..8fcc274c 100644 --- a/src/pt-BR/cookbook/custom-hydrator-type-casters.md +++ b/src/pt-BR/cookbook/custom-hydrator-type-casters.md @@ -425,7 +425,7 @@ $filter = $hydrator->create(CommentFilter::class, [ // $filter->authorId->equals($filter->postId) retorna false. ``` -#### Entrada da requisição +#### Entrada da requisição O pacote [Yii Input HTTP](https://github.com/yiisoft/input-http) usa o hydrator para preencher objetos de entrada da requisição, então o mesmo type @@ -532,7 +532,7 @@ final readonly class Action } ``` -### Valores nulos e inválidos +### Valores nulos e inválidos Veja o que acontece com uma propriedade declarada como `?UserId` para diferentes valores de entrada: diff --git a/src/pt-BR/guide/tutorial/i18n.md b/src/pt-BR/guide/tutorial/i18n.md index 0539a2ab..3b5cc401 100644 --- a/src/pt-BR/guide/tutorial/i18n.md +++ b/src/pt-BR/guide/tutorial/i18n.md @@ -208,7 +208,7 @@ $this->setTitle($translator->translate('home.title')); Escape o texto traduzido antes de exibi-lo. Guarde HTML confiável separadamente ou renderize-o a partir de um template de view. -## Escolhendo o idioma por requisição +## Escolhendo o idioma por requisição Numa aplicação web, escolha o idioma cedo na pilha de middlewares e aplique-o tanto ao tradutor quanto à view. O exemplo abaixo usa o parâmetro diff --git a/src/pt-BR/internals/001-yii-values.md b/src/pt-BR/internals/001-yii-values.md index 8735807b..11de0ab6 100644 --- a/src/pt-BR/internals/001-yii-values.md +++ b/src/pt-BR/internals/001-yii-values.md @@ -26,13 +26,13 @@ objetivo. Procuramos Desempenho é uma condição necessária para a praticidade. O software não deve desperdiçar recursos de máquina nem recursos humanos. -### Padrões sensatos e flexibilidade +### Padrões sensatos e flexibilidade Preferimos padrões e convenções sensatos que os usuários possam personalizar. Buscamos um equilíbrio entre flexibilidade, disciplina e simplicidade que atenda às necessidades comuns. -### Ser orientado à prática +### Ser orientado à prática Preferimos a prática à teoria. Por exemplo: @@ -61,7 +61,7 @@ As soluções devem ser simples e expressivas: - Evitamos soluções feias, a menos que não haja alternativa. - Menos regras é melhor do que mais regras. -### Ser explícito +### Ser explícito Preferimos soluções e código explícitos e óbvios. As soluções devem expressar claramente o que fazem. Por exemplo: