diff --git a/.github/workflows/translation.yml b/.github/workflows/translation.yml index 728bc316..74b8c923 100644 --- a/.github/workflows/translation.yml +++ b/.github/workflows/translation.yml @@ -24,11 +24,11 @@ jobs: image: arduanovdanil/po4a-fork:v0.73 options: -v ${{ github.workspace }}:/src run: | - cd guide + cd _translations/guide po4a po4a.cfg - name: Commit changed files uses: stefanzweifel/git-auto-commit-action@v5 with: commit_message: Update translation - file_pattern: 'guide' + file_pattern: '_translations guide' diff --git a/014-docs.md b/014-docs.md index 9323af6e..765ab76b 100644 --- a/014-docs.md +++ b/014-docs.md @@ -31,11 +31,11 @@ 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 folder with the name of the file you want to translate in `/guide/po`. Note that if the source file - is in a subfolder, the subfolder name is appended to the folder and separated by an underscore, for example, - for translating `guide/en/concept/aliases.md` file find `guide/po/concept_aliases.md` folder. +- 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 `guide/po/intro_what-is-yii.md/ru/intro_what-is-yii.md.ru.po`. If there is no localization yet, + 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 diff --git a/_translations/guide/po/es/README.md.po b/_translations/guide/po/es/README.md.po new file mode 100644 index 00000000..eba7c9b7 --- /dev/null +++ b/_translations/guide/po/es/README.md.po @@ -0,0 +1,635 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" +"PO-Revision-Date: 2025-09-05 13:17+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 3.7\n" + +#. type: Title # +#: ../../guide/en/README.md +#, no-wrap +msgid "The definitive guide to Yii 3.0" +msgstr "La Guía Definitiva de Yii 3.0" + +#. type: Plain text +#: ../../guide/en/README.md +msgid "We release this guide under the [Terms of Yii Documentation](https://www.yiiframework.com/license#docs)." +msgstr "Esta guía se publica bajo los [Términos de documentación de Yii](https://www.yiiframework.com/license#docs))." + +#. type: Plain text +#: ../../guide/en/README.md +msgid "Introduction +" +msgstr "Introducción" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[About Yii](intro/what-is-yii.md) +" +msgstr "[Acerca de Yii](intro/what-is-yii.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Upgrading from version 2.0](intro/upgrade-from-v2.md) +" +msgstr "[Actualizar desde la Version 2.0](intro/upgrade-from-v2.md)" + +#. type: Plain text +#: ../../guide/en/README.md +msgid "Getting started -" +msgstr "Primeros Pasos" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[What do you need to know?](start/prerequisites.md) +" +msgstr "[Qué Necesitas Saber](start/prerequisites.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Creating a project](start/creating-project.md) +" +msgstr "" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Running applications](start/workflow.md) +" +msgstr "[Ejecutando Aplicaciones](start/workflow.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Saying hello](start/hello.md) +" +msgstr "[Hola Mundo](start/hello.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Working with forms](start/forms.md) +" +msgstr "[Trabajar con Formularios](start/forms.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Working with databases](start/databases.md) !" +msgstr "[Trabajar con Bases de Datos](start/databases.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Generating code with Gii](start/gii.md) -" +msgstr "[Generación de Código con Gii](start/gii.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Looking ahead](start/looking-ahead.md) +" +msgstr "[Adentrarse en Yii](start/looking-ahead.md)" + +#. type: Plain text +#: ../../guide/en/README.md +msgid "Application structure +" +msgstr "Estructura De Una Aplicación" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Application structure overview](structure/overview.md) +" +msgstr "[Información General de Estructura de Una Aplicación](structure/overview.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Entry scripts](structure/entry-script.md) +" +msgstr "[Scripts de Entrada](structure/entry-script.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Application](structure/application.md) +" +msgstr "[Applicación](structure/application.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Service components](structure/service.md) +" +msgstr "[Componentes de Servicios](structure/service.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Actions](structure/action.md) +" +msgstr "[Acciones](structure/action.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Domain](structure/domain.md) +" +msgstr "[Dominio](structure/domain.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Middleware](structure/middleware.md) +" +msgstr "[Lógica de Intercambio (middleware)](structure/middleware.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Packages](structure/package.md) +" +msgstr "[Paquetes](structure/package.md)" + +#. type: Plain text +#: ../../guide/en/README.md +msgid "Key concepts +" +msgstr "Conceptos Clave" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Class autoloading](concept/autoloading.md) +" +msgstr "[Autocarga de Clases (Autoloading)](concept/autoloading.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Dependency injection container](concept/di-container.md) +" +msgstr "[Contenedor de Inyección de Dependencia](concept/di-container.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Configuration](concept/configuration.md) +" +msgstr "[Configuración](concept/configuration.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Aliases](concept/aliases.md) +" +msgstr "[Alias](concept/aliases.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Events](concept/events.md) +" +msgstr "[Eventos](concept/events.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Immutability](concept/immutability.md) +" +msgstr "" + +#. type: Plain text +#: ../../guide/en/README.md +msgid "Handling requests +" +msgstr "Gestión de las Peticiones" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Routing and URL generation](runtime/routing.md) +" +msgstr "[Enrutamiento y Creación de las URL](runtime/routing.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Request](runtime/request.md) +" +msgstr "[Peticiones (Requests)](runtime/request.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Response](runtime/response.md) +" +msgstr "[Respuestas (Responses)](runtime/response.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Sessions](runtime/sessions.md) +" +msgstr "[Sesiones (Sessions)](runtime/sessions.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Cookies](runtime/cookies.md) +" +msgstr "[Cookies](runtime/cookies.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Handling errors](runtime/handling-errors.md) +" +msgstr "[Manejo de Errores](runtime/handling-errors.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Logging](runtime/logging.md) +" +msgstr "[Registros (logs)](runtime/logging.md)" + +#. type: Plain text +#: ../../guide/en/README.md +msgid "Views -" +msgstr "Vistas" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Views](views/view.md) -" +msgstr "[Vistas](views/view.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Template engines](views/template-engines.md) -" +msgstr "[Motores de Plantillas](views/template-engines.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[View injections](views/view-injections.md) +" +msgstr "" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Scripts, styles and metatags](views/script-style-meta.md)" +msgstr "" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Assets](views/asset.md) -" +msgstr "[Assets](views/asset.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Widgets](views/widget.md) -" +msgstr "[Widgets](views/widget.md)" + +#. type: Plain text +#: ../../guide/en/README.md +msgid "Working with databases +-" +msgstr "Trabajar con Bases de Datos" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Database access objects](db-dao.md): Connecting to a database, basic queries, transactions, and schema manipulation" +msgstr "[Objeto de Acceso a Datos](db-dao.md): Conexión a una base de datos, consultas básicas, transacciones y manipulación de esquemas" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Query builder](db-query-builder.md): Querying the database using a simple abstraction layer" +msgstr "[Constructor de Consultas](db-query-builder.md): Consulta de la base de datos utilizando una capa simple de abstracción" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Active record](db-active-record.md): The Active Record ORM, retrieving and manipulating records, and defining relations" +msgstr "[Active Record](db-active-record.md): ORM Active Record, recuperación y manipulación de registros y definición de relaciones" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Migrations](databases/db-migrations.md): +" +msgstr "[Migraciones](db-migrations.md)" + +#. type: Plain text +#: ../../guide/en/README.md +msgid "Getting data from users -" +msgstr "Obtener Datos de los Usuarios" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Creating forms](input/forms.md) -" +msgstr "[Crear Formularios](input/forms.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Validating input](https://github.com/yiisoft/validator/blob/master/docs/guide/en/README.md) +" +msgstr "[Validar Datos](https://github.com/yiisoft/validator/blob/master/docs/guide/en/README.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Uploading files](input/file-upload.md) -" +msgstr "[Carga de Archivos](input/file-upload.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Collecting tabular input](input/tabular-input.md) -" +msgstr "[Obtener Datos de Formularios Tabulados (Tabular Input)](input/tabular-input.md)" + +#. type: Plain text +#: ../../guide/en/README.md +msgid "Displaying data -" +msgstr "Visualizar Datos" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Data formatting](output/formatting.md) -" +msgstr "[Formato de Datos](output/formatting.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Pagination](output/pagination.md) -" +msgstr "[Paginación](output/pagination.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Sorting](output/sorting.md) -" +msgstr "[Ordenamiento](output/sorting.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Data providers](output/data-providers.md) -" +msgstr "[Proveedores de Datos](output/data-providers.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Data widgets](output/data-widgets.md) -" +msgstr "[Widgets de Datos](output/data-widgets.md)" + +#. type: Plain text +#: ../../guide/en/README.md +msgid "Security +-" +msgstr "Seguridad" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Security overview](security/overview.md) +" +msgstr "[Información General de Seguridad](security/overview.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Authentication](security/authentication.md) +" +msgstr "[Autenticación](security/authentication.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Authorization](security/authorization.md) +-" +msgstr "[Autorización](security/authorization.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Working with passwords](security/passwords.md) +" +msgstr "[Trabajar con Contraseñas](security/passwords.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Cryptography](security/cryptography.md) +" +msgstr "[Criptografía](security/cryptography.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Best practices](security/best-practices.md) +" +msgstr "[Buenas Prácticas](security/best-practices.md)" + +#. type: Plain text +#: ../../guide/en/README.md +msgid "Caching +-" +msgstr "Caché" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Caching overview](caching/overview.md) +" +msgstr "[Información General de Caché](caching/overview.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Data caching](caching/data.md) +" +msgstr "[Caché de Datos](caching/data.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Fragment caching](caching/fragment.md) -" +msgstr "[Caché de Fragmentos](caching/fragment.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Page caching](caching/page.md) -" +msgstr "[Caché de Páginas](caching/page.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[HTTP caching](caching/http.md) -" +msgstr "[Caché HTTP](caching/http.md)" + +#. type: Title - +#: ../../guide/en/README.md +#, fuzzy, no-wrap +msgid "REST APIs -" +msgstr "Servicios Web RESTful" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Quick start](rest/quick-start.md)" +msgstr "[Inicio Rápido](rest/quick-start.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Resources](rest/resources.md)" +msgstr "[Recursos](rest/resources.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Controllers](rest/controllers.md)" +msgstr "[Controladores](rest/controllers.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Routing](rest/routing.md)" +msgstr "[Enrutamiento](rest/routing.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Authentication](rest/authentication.md)" +msgstr "[Autentificación](rest/authentication.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Rate limiting](rest/rate-limiting.md)" +msgstr "[Límite de Solicitudes por Cliente (Rate Limiting)](rest/rate-limiting.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Versioning](rest/versioning.md)" +msgstr "[Gestión de Versiones](rest/versioning.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Error handling](rest/error-handling.md)" +msgstr "[Manejo de Errores](rest/error-handling.md)" + +#. type: Plain text +#: ../../guide/en/README.md +msgid "Development tools -" +msgstr "Herramientas de Desarrollo" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "Debug toolbar and debugger" +msgstr "Depurador y Barra de Herramientas de Depuración" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "Generating code using Gii" +msgstr "Generación de Código con Gii" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "Generating API documentation" +msgstr "Generación de Documentación de API" + +#. type: Plain text +#: ../../guide/en/README.md +msgid "Testing -" +msgstr "Pruebas (Testing)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Testing overview](testing/overview.md)" +msgstr "[Información General de Pruebas](testing/overview.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Testing environment setup](testing/environment-setup.md)" +msgstr "[Configuración del Entorno de Pruebas](testing/environment-setup.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Unit tests](testing/unit.md)" +msgstr "[Pruebas Unitarias](testing/unit.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Functional tests](testing/functional.md)" +msgstr "[Pruebas Funcionales](testing/functional.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Acceptance tests](testing/acceptance.md)" +msgstr "[Pruebas de Aceptación](testing/acceptance.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Fixtures](testing/fixtures.md)" +msgstr "[Datos de Prueba (Fixtures)](testing/fixtures.md)" + +#. type: Plain text +#: ../../guide/en/README.md +msgid "Special topics -" +msgstr "Temas Especiales" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Building application from scratch](tutorial/start-from-scratch.md) -" +msgstr "[Creación de una Aplicación Desde Cero](tutorial/start-from-scratch.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Console applications](tutorial/console-applications.md) +" +msgstr "[Comandos de Consola](tutorial/console-applications.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Docker](tutorial/docker.md) -" +msgstr "[Docker](tutorial/docker.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Internationalization](tutorial/i18n.md) -" +msgstr "[Internacionalización](tutorial/i18n.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Mailing](tutorial/mailing.md) +" +msgstr "[Envío de Correos Electrónicos](tutorial/mailing.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Performance tuning](tutorial/performance-tuning.md) +" +msgstr "[Ajustes de Rendimiento](tutorial/performance-tuning.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Using Yii with event loop](tutorial/using-with-event-loop.md) +" +msgstr "[Utilizar Yii con Bucle de Eventos](tutorial/using-with-event-loop.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Using Yii with RoadRunner](tutorial/using-yii-with-roadrunner.md) +" +msgstr "[Utilizar Yii con RoadRunner](tutorial/using-yii-with-roadrunner.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Using Yii with Swoole](tutorial/using-yii-with-swoole.md) +" +msgstr "" + +#. type: Plain text +#: ../../guide/en/README.md +msgid "Widgets -" +msgstr "Widgets" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[GridView](https://www.yiiframework.com/doc-2.0/yii-grid-gridview.html)" +msgstr "[GridView](https://www.yiiframework.com/doc-2.0/yii-grid-gridview.html)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[ListView](https://www.yiiframework.com/doc-2.0/yii-widgets-listview.html)" +msgstr "[ListView](https://www.yiiframework.com/doc-2.0/yii-widgets-listview.html)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[DetailView](https://www.yiiframework.com/doc-2.0/yii-widgets-detailview.html)" +msgstr "[DetailView](https://www.yiiframework.com/doc-2.0/yii-widgets-detailview.html)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[ActiveForm](https://www.yiiframework.com/doc-2.0/guide-input-forms.html#activerecord-based-forms-activeform)" +msgstr "[ActiveForm](https://www.yiiframework.com/doc-2.0/guide-input-forms.html#activerecord-based-forms-activeform)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Menu](https://www.yiiframework.com/doc-2.0/yii-widgets-menu.html)" +msgstr "[Menu](https://www.yiiframework.com/doc-2.0/yii-widgets-menu.html)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[LinkPager](https://www.yiiframework.com/doc-2.0/yii-widgets-linkpager.html)" +msgstr "[LinkPager](https://www.yiiframework.com/doc-2.0/yii-widgets-linkpager.html)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[LinkSorter](https://www.yiiframework.com/doc-2.0/yii-widgets-linksorter.html)" +msgstr "[LinkSorter](https://www.yiiframework.com/doc-2.0/yii-widgets-linksorter.html)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Bootstrap widgets](https://www.yiiframework.com/extension/yiisoft/yii2-bootstrap/doc/guide)" +msgstr "[Bootstrap widgets](https://www.yiiframework.com/extension/yiisoft/yii2-bootstrap/doc/guide)" + +#. type: Plain text +#: ../../guide/en/README.md +msgid "Helpers +" +msgstr "Clases Auxiliares" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Arrays](https://github.com/yiisoft/arrays/)" +msgstr "" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Files](https://github.com/yiisoft/files/)" +msgstr "" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Html](https://github.com/yiisoft/html/)" +msgstr "" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Json](https://github.com/yiisoft/json)" +msgstr "" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Network utilities](https://github.com/yiisoft/network-utilities/)" +msgstr "" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[VarDumper](https://github.com/yiisoft/var-dumper)" +msgstr "" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Strings](https://github.com/yiisoft/strings)" +msgstr "" + +#. type: Plain text +#: ../../guide/en/README.md +msgid "Extras +" +msgstr "" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Glossary](glossary.md)" +msgstr "" diff --git a/_translations/guide/po/es/caching_data.md.po b/_translations/guide/po/es/caching_data.md.po new file mode 100644 index 00000000..9ef94778 --- /dev/null +++ b/_translations/guide/po/es/caching_data.md.po @@ -0,0 +1,336 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" +"PO-Revision-Date: 2025-09-04 11:19+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\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/guide/po/es/caching_overview.md.po b/_translations/guide/po/es/caching_overview.md.po new file mode 100644 index 00000000..007b4e8d --- /dev/null +++ b/_translations/guide/po/es/caching_overview.md.po @@ -0,0 +1,58 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title # +#: en/caching/overview.md +#, no-wrap +msgid "Caching" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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 +#: en/caching/overview.md +msgid "Yii supports all these caching mechanisms:" +msgstr "" + +#. type: Bullet: '* ' +#: en/caching/overview.md +msgid "[Data caching](data.md)" +msgstr "" + +#. type: Bullet: '* ' +#: en/caching/overview.md +msgid "[Fragment caching](fragment.md)" +msgstr "" + +#. type: Bullet: '* ' +#: en/caching/overview.md +msgid "[Page caching](page.md)" +msgstr "" + +#. type: Bullet: '* ' +#: en/caching/overview.md +msgid "[HTTP caching](http.md)" +msgstr "" diff --git a/_translations/guide/po/es/concept_aliases.md.po b/_translations/guide/po/es/concept_aliases.md.po new file mode 100644 index 00000000..f5757036 --- /dev/null +++ b/_translations/guide/po/es/concept_aliases.md.po @@ -0,0 +1,330 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2025-09-03 17:50+0500\n" +"PO-Revision-Date: 2025-09-05 12:21+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 3.7\n" + +#. type: Title # +#: en/concept/aliases.md +#, no-wrap +msgid "Aliases" +msgstr "Alias" + +#. type: Plain text +#: en/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 "" +"Los alias son utilizados para representar rutas o URLs de manera que no tengas que escribir explícitamente rutas absolutas o URLs en tu\n" +"proyecto. Un alias debe comenzar con el signo `@` para ser diferenciado de una ruta normal de archivo y de URLs. Los alias definidos\n" +"sin el `@` del principio, serán prefijados con el signo `@`." + +#. type: Plain text +#: en/concept/aliases.md +#, fuzzy +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 "Yii incluye varios alias predefinidos en `config/params.php`. Por ejemplo, el alias `@src` representa la ruta de instalación de la aplicación en la carpeta `src`; `@web` representa la URL base para la aplicación Web ejecutándose." + +#. type: Title ## +#: en/concept/aliases.md +#, no-wrap +msgid "Defining aliases " +msgstr "Definir Alias " + +#. type: Plain text +#: en/concept/aliases.md +msgid "You can define an alias via application's `config/params.php`:" +msgstr "Puedes definir un alias mediante la aplicación en `config/params.php`:" + +#. type: Fenced code block (php) +#: en/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 "" +"return [\n" +" // ...\n" +"\n" +" 'aliases' => [\n" +" // un alias de una ruta de archivos\n" +" '@foo' => '/path/to/foo',\n" +"\n" +" // un alias de un URL\n" +" '@bar' => 'http://www.example.com',\n" +"\n" +" // un alias de un archivo en concreto que contiene la clase \\foo\\Bar\n" +" '@foo/Bar.php' => '/definitely/not/foo/Bar.php',\n" +" ]\n" +"];\n" + +#. type: Plain text +#: en/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 "" +"> [!Nota]\n" +"> Una ruta de archivo o URL en alias *no* se refiere necesariamente a un archivo o recurso existente.\n" + +#. type: Plain text +#: en/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 "" +"Dado un alias, puedes derivar un nuevo alias anexando una barra diagonal `/` seguida por uno o varios segmentos de la ruta.\n" +"Por ejemplo, `@foo` es un alias de raíz, mientras que `@foo/bar/file.php` es un alias derivado." + +#. type: Plain text +#: en/concept/aliases.md +msgid "You can define an alias using another alias (either root or derived):" +msgstr "Puedes definir un alias usando otro alias (ya sea un alias de raíz o derivado):" + +#. type: Fenced code block (php) +#: en/concept/aliases.md +#, no-wrap +msgid "'@foobar' => '@foo/bar', \n" +msgstr "'@foobar' => '@foo/bar',\n" + +#. type: Plain text +#: en/concept/aliases.md +msgid "The `yiisoft/aliases` parameter initializes `Aliases` service from [`yiisoft/aliases` package](https://github.com/yiisoft/aliases). You can set extra aliases in runtime by using the service:" +msgstr "" +"El parámetro `aliases` inicializa el servicio `Aliases` desde el [paquete `yiisoft/aliases`](https://github.com/yiisoft/aliases).\n" +"Puedes agregar alias adicionales en tiempo de ejecución usando el servicio:" + +#. type: Fenced code block (php) +#: en/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 "" +"use \\Yiisoft\\Aliases\\Aliases;\n" +"\n" +"public function actionIndex(Aliases $aliases)\n" +"{\n" +" $aliases->set('@uploads', '@root/uploads');\n" +"}\n" + +#. type: Title ## +#: en/concept/aliases.md +#, no-wrap +msgid "Using aliases in configuration " +msgstr "" + +#. type: Plain text +#: en/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) +#: en/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 ## +#: en/concept/aliases.md +#, no-wrap +msgid "Resolving aliases " +msgstr "Resolución de Alias " + +#. type: Plain text +#: en/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 "Puedes utilizar el servicio `Aliases` para resolver un alias o un alias derivado a la ruta de archivo o URL que representa:" + +#. type: Fenced code block (php) +#: en/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 "" +"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 +#: en/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 "La ruta de archivo/URL representado por un alias derivado está determinado por la sustitución de la parte de su alias raíz con su correspondiente ruta/Url en el alias derivado." + +#. type: Plain text +#: en/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 "" +"> [!NOTE]\n" +"> El método `get()` no comprueba si la ruta/URL resultante hacer referencia a un archivo o recurso existente.\n" + +#. type: Plain text +#: en/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 "" +"Un alias de raíz puede contener carácteres `/`.\n" +"El método `get()` es lo suficientemente inteligente para saber qué parte de un alias es un alias de raíz y por lo tanto determinar correctamente la correspondiente ruta de archivo o URL. Por ejemplo:" + +#. type: Fenced code block (php) +#: en/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 "" +"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 +#: en/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 "Si `@foo/bar` no está definido como un alias de raíz, la última declaración mostraría `/path/to/foo/bar/file.php`." + +#. type: Title ## +#: en/concept/aliases.md +#, no-wrap +msgid "Predefined aliases " +msgstr "Alias Predefinidos " + +#. type: Plain text +#: en/concept/aliases.md +#, fuzzy +msgid "[Yii application](https://github.com/yiisoft/app) predefines a set of aliases to reference commonly used file paths and URLs:" +msgstr "Yii predefine un conjunto de alias para aliviar la necesidad de hacer referencia a rutas de archivo o URLs que son utilizadas regularmente:" + +#. type: Bullet: '- ' +#: en/concept/aliases.md +msgid "`@root` - the base directory of the currently running application." +msgstr "`@root`, la ruta base de la aplicación que se está ejecutando actualmente." + +#. type: Bullet: '- ' +#: en/concept/aliases.md +msgid "`@assets` - application's public directory where it publishes assets." +msgstr "" + +#. type: Bullet: '- ' +#: en/concept/aliases.md +msgid "`@assetsUrl` - URL of base directory with published assets." +msgstr "" + +#. type: Bullet: '- ' +#: en/concept/aliases.md +msgid "`@baseUrl` - the base URL of the currently running Web application. Defaults to `/`." +msgstr "" + +#. type: Bullet: '- ' +#: en/concept/aliases.md +msgid "`@npm` - node packages directory." +msgstr "" + +#. type: Bullet: '- ' +#: en/concept/aliases.md +msgid "`@bower` - bower packages directory." +msgstr "" + +#. type: Bullet: '- ' +#: en/concept/aliases.md +msgid "`@vendor` - Composer's `vendor` directory." +msgstr "`@vendor`, la carpeta `vendor` de Composer." + +#. type: Bullet: '- ' +#: en/concept/aliases.md +#, fuzzy +msgid "`@public` - application's publicly accessible directory that with `index.php`." +msgstr "`@public`, el directorio raíz Web de la aplicación Web se está ejecutando actualmente." + +#. type: Bullet: '- ' +#: en/concept/aliases.md +msgid "`@runtime` - the runtime path of the currently running application. Defaults to `@root/runtime`." +msgstr "`@runtime`, la ruta de ejecución de la aplicación en ejecución. Por defecto`@root/runtime`." + +#. type: Bullet: '- ' +#: en/concept/aliases.md +msgid "`@layout` - the directory with layouts." +msgstr "" + +#. type: Bullet: '- ' +#: en/concept/aliases.md +msgid "`@resources` - directory with views, asset sources and other resources." +msgstr "" + +#. type: Bullet: '- ' +#: en/concept/aliases.md +msgid "`@views` - application view templates base directory." +msgstr "" diff --git a/_translations/guide/po/es/concept_autoloading.md.po b/_translations/guide/po/es/concept_autoloading.md.po new file mode 100644 index 00000000..67e92e68 --- /dev/null +++ b/_translations/guide/po/es/concept_autoloading.md.po @@ -0,0 +1,88 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2025-09-04 07:25+0500\n" +"PO-Revision-Date: 2025-09-05 12:25+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 3.7\n" + +#. type: Title # +#: en/concept/autoloading.md +#, no-wrap +msgid "Class autoloading" +msgstr "Autocarga de Clases (Autoloading)" + +#. type: Plain text +#: en/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 "" +"Dado que Yii utiliza [Composer](https://getcomposer.org) para administar paquetes, las clases de esos paquetes son automaticamente\n" +"cargados sin la necesidad de ser incluidos utilizando `require` para cada uno de ellos. Cuando los paquetes son instalados,\n" +"un [autocargador compatible con PSR-0](https://www.php-fig.org/psr/psr-4/) es generado. Para usarlo,\n" +"se debe invocar el autocargador `/vendor/autoload.php` con `require_once` en el script de entrada `index.php`." + +#. type: Plain text +#: en/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 "" +"El autocargador no se utiliza solamente para los paquetes que se instalan, tambien se utiliza para su aplicación que también es un paquete.\n" +"Para cargar clases desde cierto espacio de nombres (namespaces), lo siguiente debe ser añadido a `composer.json`:" + +#. type: Fenced code block (json) +#: en/concept/autoloading.md +#, no-wrap +msgid "" +"{\n" +" \"autoload\": {\n" +" \"psr-4\": {\n" +" \"App\\\\\": \"src/\"\n" +" }\n" +" }\n" +"}\n" +msgstr "" +"{\n" +" \"autoload\": {\n" +" \"psr-4\": {\n" +" \"App\\\\\": \"src/\"\n" +" }\n" +" }\n" +"}\n" + +#. type: Plain text +#: en/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 "" +"Donde `App\\\\` es el espacio de nombre raiz (namespace), y `src/` es la carpeta donde se ubican las clases. Se pueden añadir distintos namespaces y carpetas si es necesario.\n" +"Una vez listo, ejecuta `composer dump-autoload` y las clases de los espacios de nombres serán cargados automaticamente." + +#. type: Plain text +#: en/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: Title ## +#: en/concept/autoloading.md +#, no-wrap +msgid "References" +msgstr "Referencias" + +#. type: Bullet: '- ' +#: en/concept/autoloading.md +msgid "[PSR-4: Autoloader](https://www.php-fig.org/psr/psr-4/)." +msgstr "[PSR-4: Autoloader](https://www.php-fig.org/psr/psr-4/)." + +#. type: Bullet: '- ' +#: en/concept/autoloading.md +msgid "[Composer guide on autoloading](https://getcomposer.org/doc/01-basic-usage.md#autoloading)." +msgstr "[Guía de Composer sobre autocarga](https://getcomposer.org/doc/01-basic-usage.md#autoloading)." diff --git a/_translations/guide/po/es/concept_configuration.md.po b/_translations/guide/po/es/concept_configuration.md.po new file mode 100644 index 00000000..3bbd3aea --- /dev/null +++ b/_translations/guide/po/es/concept_configuration.md.po @@ -0,0 +1,507 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title ## +#: en/concept/configuration.md en/tutorial/using-yii-with-roadrunner.md +#: en/views/view-injections.md +#, no-wrap +msgid "Configuration" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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/`." +msgstr "" + +#. type: Title ## +#: en/concept/configuration.md +#, no-wrap +msgid "Config plugin" +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "In the application template [yiisoft/config](https://github.com/yiisoft/config) is used. Since writing all application configurations from scratch is a tedious process, many packages offer default configs, and the plugin helps with copying these into the application." +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "To offer default configs, `composer.json` of the package has to have `config-plugin` section. When installing or updating packages with Composer, the plugin reads `config-plugin` sections for each dependency, copies files themselves to application `config/packages/` if they don't yet exist and writes a merge plan to `config/packages/merge_plan.php`. The merge plan defines how to merge the configs into a single big array ready to be passed to [DI container](di-container.md)." +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "Take a look at what's in the \"yiisoft/app\" `composer.json` by default:" +msgstr "" + +#. type: Fenced code block (json) +#: en/concept/configuration.md +#, no-wrap +msgid "" +"\"config-plugin-options\": {\n" +" \"output-directory\": \"config/packages\"\n" +"},\n" +"\"config-plugin\": {\n" +" \"common\": \"config/common/*.php\",\n" +" \"params\": [\n" +" \"config/params.php\",\n" +" \"?config/params-local.php\"\n" +" ],\n" +" \"web\": [\n" +" \"$common\",\n" +" \"config/web/*.php\"\n" +" ],\n" +" \"console\": [\n" +" \"$common\",\n" +" \"config/console/*.php\"\n" +" ],\n" +" \"events\": \"config/events.php\",\n" +" \"events-web\": [\n" +" \"$events\",\n" +" \"config/events-web.php\"\n" +" ],\n" +" \"events-console\": [\n" +" \"$events\",\n" +" \"config/events-console.php\"\n" +" ],\n" +" \"providers\": \"config/providers.php\",\n" +" \"providers-web\": [\n" +" \"$providers\",\n" +" \"config/providers-web.php\"\n" +" ],\n" +" \"providers-console\": [\n" +" \"$providers\",\n" +" \"config/providers-console.php\"\n" +" ],\n" +" \"routes\": \"config/routes.php\"\n" +"},\n" +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "There are many named configs defined. For each name, there is a configuration." +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "A string means that the plugin takes config as is and merges it with same-named configs from packages you require. That happens if these packages have `config-plugin` in their `composer.json`." +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "The array means that the plugin will merge many files in the order they're specified." +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "`?` at the beginning of the file path indicated that the file may be absent. In this case, it's skipped." +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "`$` at the beginning of the name means a reference to another named config." +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "`params` is a bit special because it's reserved for application parameters. These are automatically available as `$params` in all other configuration files." +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "You can learn more about config plugin features [from its documentation](https://github.com/yiisoft/config/blob/master/README.md)." +msgstr "" + +#. type: Title ## +#: en/concept/configuration.md +#, no-wrap +msgid "Config files" +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "Now, as you know how the plugin assembles configs, look at `config` directory:" +msgstr "" + +#. type: Fenced code block +#: en/concept/configuration.md +#, no-wrap +msgid "" +"common/\n" +" application-parameters.php\n" +" i18n.php\n" +" router.php\n" +"console/\n" +"packages/\n" +" yiisoft/\n" +" dist.lock\n" +" merge_plan.php\n" +"web/\n" +" application.php\n" +" psr17.php\n" +"events.php\n" +"events-console.php\n" +"events-web.php\n" +"params.php\n" +"providers.php\n" +"providers-console.php\n" +"providers-web.php\n" +"routes.php\n" +msgstr "" + +#. type: Title ### +#: en/concept/configuration.md +#, no-wrap +msgid "Container configuration" +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "The application consists of a set of services registered in a [dependency container](di-container.md). The config files that responsible for direct dependency container configuration are under `common/`, `console/` and `web/` directories. We use `web/` for config specific to web application and `console/` for config specific to console commands. Both web and console are sharing configuration under `common/`." +msgstr "" + +#. type: Fenced code block (php) +#: en/concept/configuration.md +#, no-wrap +msgid "" +" [\n" +" 'class' => ApplicationParameters::class,\n" +" 'charset()' => [$params['app']['charset']],\n" +" 'name()' => [$params['app']['name']],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "Config plugin passes special `$params` variable to all config files. The code passes its values to the service." +msgstr "" + +#. type: Plain text +#: en/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 +#: en/concept/configuration.md +msgid "For convenience, there is a naming convention for custom string keys:" +msgstr "" + +#. type: Bullet: '1. ' +#: en/concept/configuration.md +msgid "Prefix package name such as `yiisoft/cache-file/custom-definition`." +msgstr "" + +#. type: Bullet: '2. ' +#: en/concept/configuration.md +msgid "In case configuration are for the application itself, skip package prefix, such as `custom-definition`." +msgstr "" + +#. type: Title ### +#: en/concept/configuration.md +#, no-wrap +msgid "Service providers" +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "As an alternative to registering dependencies directly, you can use service providers. Basically, these are classes that given parameters are configuring and registering services within the container. Similar to three dependency configuration files described, there are three configs for specifying service providers: `providers-console.php` for console commands, `providers-web.php` for web application and `providers.php` for both:" +msgstr "" + +#. type: Fenced code block (php) +#: en/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' => [\n" +" 'class' => CacheProvider::class,\n" +" '__construct()' => [\n" +" $params['yiisoft/cache-file']['file-cache']['path'],\n" +" ],\n" +" ],\n" +" // ...\n" +msgstr "" + +#. type: Plain text +#: en/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. These classes could be either created in the project itself or provided by a package." +msgstr "" + +#. type: Plain text +#: en/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 +#: en/concept/configuration.md +msgid "Provider should implement a single method, `public function register(Container $container): void`. In this method you need to add a service to container using `set()` method. Below is a provider for a cache service:" +msgstr "" + +#. type: Fenced code block (php) +#: en/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\\Container;\n" +"use Yiisoft\\Di\\Support\\ServiceProvider;\n" +"\n" +"final readonly class CacheProvider extends ServiceProvider\n" +"{\n" +" public function __construct(\n" +" private string $cachePath = '@runtime/cache'\n" +" )\n" +" {\n" +" $this->cachePath = $cachePath;\n" +" }\n" +"\n" +" public function register(Container $container): void\n" +" {\n" +" $container->set(CacheInterface::class, function (ContainerInterface $container) {\n" +" $aliases = $container->get(Aliases::class);\n" +"\n" +" return new FileCache($aliases->get($this->cachePath));\n" +" });\n" +"\n" +" $container->set(YiiCacheInterface::class, Cache::class);\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ### +#: en/concept/configuration.md +#, no-wrap +msgid "Routes" +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "You can configure how web application responds to certain URLs in `config/routes.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: en/concept/configuration.md +#, no-wrap +msgid "" +"use App\\Controller\\SiteController;\n" +"use Yiisoft\\Router\\Route;\n" +"\n" +"return [\n" +" Route::get('/')->action([SiteController::class, 'index'])->name('site/index')\n" +"];\n" +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "Read more about it in [\"Routes\"](../runtime/routing.md)." +msgstr "" + +#. type: Title # +#: en/concept/configuration.md en/concept/events.md +#, no-wrap +msgid "Events" +msgstr "Eventos" + +#. type: Plain text +#: en/concept/configuration.md +msgid "Many services emit certain events that you can attach to. You could do that via three config files: `events-web.php` for web application events, `events-console.php` for console events and `events.php` for both. The configuration is an array where keys are event names and values are an array of handlers:" +msgstr "" + +#. type: Fenced code block (php) +#: en/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 definition of an invokable class may be here while your `$container->has('the definition)` \n" +" 'di-alias'\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "Read more about it in [\"Events\"](events.md)." +msgstr "" + +#. type: Title ### +#: en/concept/configuration.md +#, no-wrap +msgid "Parameters" +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "Parameters, `config/params.php` store configuration values that are used in other config files to configuring services and service providers." +msgstr "" + +#. type: Plain text +#: en/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 +#: en/concept/configuration.md +msgid "Default application `params.php` looks like the following:" +msgstr "" + +#. type: Fenced code block (php) +#: en/concept/configuration.md +#, no-wrap +msgid "" +" [\n" +" 'charset' => 'UTF-8',\n" +" 'locale' => 'en',\n" +" 'name' => 'My Project',\n" +" ],\n" +"\n" +" 'yiisoft/aliases' => [\n" +" 'aliases' => [\n" +" '@root' => dirname(__DIR__),\n" +" '@assets' => '@root/public/assets',\n" +" '@assetsUrl' => '/assets',\n" +" '@baseUrl' => '/',\n" +" '@message' => '@root/resources/message',\n" +" '@npm' => '@root/node_modules',\n" +" '@public' => '@root/public',\n" +" '@resources' => '@root/resources',\n" +" '@runtime' => '@root/runtime',\n" +" '@vendor' => '@root/vendor',\n" +" '@layout' => '@resources/views/layout',\n" +" '@views' => '@resources/views',\n" +" ],\n" +" ],\n" +"\n" +" 'yiisoft/yii-view' => [\n" +" 'injections' => [\n" +" Reference::to(ContentViewInjection::class),\n" +" Reference::to(CsrfViewInjection::class),\n" +" Reference::to(LayoutViewInjection::class),\n" +" ],\n" +" ],\n" +"\n" +" 'yiisoft/yii-console' => [\n" +" 'commands' => [\n" +" 'hello' => Hello::class,\n" +" ],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "For convenience, there is a naming convention about parameters:" +msgstr "" + +#. type: Bullet: '1. ' +#: en/concept/configuration.md +msgid "Group parameters package name such as `yiisoft/cache-file`." +msgstr "" + +#. type: Bullet: '2. ' +#: en/concept/configuration.md +msgid "In case parameters are for the application itself, as in `app`, skip package prefix." +msgstr "" + +#. type: Bullet: '3. ' +#: en/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. ' +#: en/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 ### +#: en/concept/configuration.md +#, no-wrap +msgid "Package configs" +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "Config plugin described copy default package configurations to `packages/` directory. Once copied you own the configs, so you can adjust these as you like. `yiisoft/` in the default template stands for package vendor. Since only `yiisoft` packages are in template, there's a single directory. `merge_plan.php` is used in runtime to get the order on how configs are merged. Note that for config keys there should be a single source of truth. One config can't override values of another config." +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "`dist.lock` is used by the plugin to keep track of changes and display diff between current config and example one." +msgstr "" diff --git a/_translations/guide/po/es/concept_di-container.md.po b/_translations/guide/po/es/concept_di-container.md.po new file mode 100644 index 00000000..96270ce0 --- /dev/null +++ b/_translations/guide/po/es/concept_di-container.md.po @@ -0,0 +1,375 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" +"PO-Revision-Date: 2025-09-04 07:37+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title # +#: ../../guide/en/concept/di-container.md +#, no-wrap +msgid "Dependency injection and container" +msgstr "" + +#. type: Title ## +#: ../../guide/en/concept/di-container.md +#, no-wrap +msgid "Dependency injection " +msgstr "" + +#. type: Plain text +#: ../../guide/en/concept/di-container.md +msgid "There are two ways of re-using things in OOP: inheritance and composition." +msgstr "" + +#. type: Plain text +#: ../../guide/en/concept/di-container.md +msgid "Inheritance is simple:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/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 +#: ../../guide/en/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 +#: ../../guide/en/concept/di-container.md +msgid "Another way to handle this is composition:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/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 +#: ../../guide/en/concept/di-container.md +msgid "We've avoided unnecessary inheritance and used interface to reduce coupling. You can replace cache implementation without changing `CachedWidget` so it's becoming more stable." +msgstr "" + +#. type: Plain text +#: ../../guide/en/concept/di-container.md +msgid "The `CacheInterface` here is a dependency: an object another object depends on. The process of putting an instance of dependency into an object (`CachedWidget`) is called dependency injection. There are many ways to perform it:" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/concept/di-container.md +msgid "Constructor injection. Best for mandatory dependencies." +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/concept/di-container.md +msgid "Method injection. Best for optional dependencies." +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/concept/di-container.md +msgid "Property injection. Better to be avoided in PHP except maybe data transfer objects." +msgstr "" + +#. type: Title ### +#: ../../guide/en/concept/di-container.md +#, no-wrap +msgid "Why use private properties " +msgstr "" + +#. type: Plain text +#: ../../guide/en/concept/di-container.md +msgid "In the composition example above, note that the `$cache` property is declared as `private`." +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/concept/di-container.md +msgid "This design choice provides several benefits:" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/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: '- ' +#: ../../guide/en/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: '- ' +#: ../../guide/en/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: '- ' +#: ../../guide/en/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 ## +#: ../../guide/en/concept/di-container.md +#, no-wrap +msgid "DI container " +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/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 +#: ../../guide/en/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: '- ' +#: ../../guide/en/concept/di-container.md +msgid "Define how to instantiate such an API wrapper." +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/concept/di-container.md +msgid "Instantiate it when required and only once per request." +msgstr "" + +#. type: Plain text +#: ../../guide/en/concept/di-container.md +msgid "That's what dependency containers are for." +msgstr "" + +#. type: Plain text +#: ../../guide/en/concept/di-container.md +msgid "A dependency injection (DI) container is an object that knows how to instantiate and configure objects and all their dependent objects. [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." +msgstr "" + +#. type: Plain text +#: ../../guide/en/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: Title ### +#: ../../guide/en/concept/di-container.md +#, no-wrap +msgid "Configuring container " +msgstr "" + +#. type: Plain text +#: ../../guide/en/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) +#: ../../guide/en/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 +#: ../../guide/en/concept/di-container.md +msgid "configuration could be:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/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 +#: ../../guide/en/concept/di-container.md +msgid "That's equal to the following:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/concept/di-container.md +#, no-wrap +msgid "" +"$myService = new MyService(42);\n" +"$myService->setDiscount(10);\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/concept/di-container.md +msgid "There are extra methods of declaring dependencies:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/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" +" // array definition (same as above)\n" +" 'full_definition' => [\n" +" 'class' => EngineMarkOne::class,\n" +" '__construct()' => [42], \n" +" '$propertyName' => 'value',\n" +" 'setX()' => [42],\n" +" ],\n" +"\n" +" // closure\n" +" 'closure' => static function(ContainerInterface $container) {\n" +" return new MyClass($container->get('db'));\n" +" },\n" +"\n" +" // static call\n" +" 'static_call' => [MyFactory::class, 'create'],\n" +"\n" +" // instance of an object\n" +" 'object' => new MyClass(),\n" +"];\n" +msgstr "" + +#. type: Title ### +#: ../../guide/en/concept/di-container.md +#, no-wrap +msgid "Injecting dependencies " +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/concept/di-container.md +msgid "This is primarily done in constructor and handing method of action handlers:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/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 +#: ../../guide/en/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: Title ## +#: ../../guide/en/concept/di-container.md +#, no-wrap +msgid "References " +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/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/guide/po/es/concept_events.md.po b/_translations/guide/po/es/concept_events.md.po new file mode 100644 index 00000000..4c3e9172 --- /dev/null +++ b/_translations/guide/po/es/concept_events.md.po @@ -0,0 +1,334 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2025-09-04 11:19+0500\n" +"PO-Revision-Date: 2025-09-05 12:44+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 3.7\n" + +#. type: Title # +#: en/concept/configuration.md en/concept/events.md +#, no-wrap +msgid "Events" +msgstr "Eventos" + +#. type: Plain text +#: en/concept/events.md +msgid "Events allow you to make custom code executed at certain execution points without modifying existing code. You can attach a custom code called \"handler\" to an event so that when the event is triggered, the handler gets executed automatically." +msgstr "" +"Los eventos permiten ejecutar código personalizado en ciertos puntos de ejecución sin modificar el código existente.\n" +"A un evento se le puede acoplar un código especial llamado gestor (handler), de manera que una vez que el evento se dispare (triggered),\n" +"el código se ejecuta de manera automática." + +#. type: Plain text +#: en/concept/events.md +msgid "For example, when a user is signed up, you need to send a welcome email. You can do it right in the `SignupService` but then, when you additionally need to resize user's avatar image, you'll have to change `SignupService` code again. In other words, `SignupService` will be coupled to both code sending welcome email and code resizing avatar image." +msgstr "" +"Por ejemplo, cuando un usuario se registra debes enviarle un correo electrónico de bienvenida. Puedes realizar esto directamente en `RegistroService`,\n" +"pero luego adicionalmente debes redimensionar la imagen del avatar del usuario, y tendrás que modificar nuevamente `RegistroService`.\n" +"En otras palabras, a `RegistroService` se le acoplan el codigo de enviar un correo de bienvenida y redimensionar la imagen del avatar." + +#. type: Plain text +#: en/concept/events.md +#, no-wrap +msgid "" +"To avoid it, instead of telling what do after signup explicitly you can, instead, raise `UserSignedUp` event\n" +"and then finish a signup process. The code sending an email and the code resizing avatar image will attach to the event\n" +" and, therefore, will be executed. If you'll ever need to do more on signup, you'll be able to attach extra event\n" +"handlers without modifying `SignupService`. \n" +msgstr "" +"Para evitar todo eso, en vez de decir explicitamente qué hacer despues de un registro, podemos levantar el evento `UsuarioRegistrado`\n" +"y luego finalizar el proceso de registro. El código que envía el correo y el código que redimensiona la imagen de avatar se adjuntan al evento\n" +"y por lo tanto serán ejecutados cuando el evento se dispara. Si alguna vez se necesita hacer más cosas en el proceso de registro, puedes añadir distintos gestores de\n" +"eventos sin necesidad de modificar `RegistroService`.\n" + +#. type: Plain text +#: en/concept/events.md +msgid "For raising events and attaching handlers to these events, Yii has a special service called event dispatcher. It's available from [yiisoft/event-dispatcher package](https://github.com/yiisoft/event-dispatcher)." +msgstr "" +"Para levantar eventos y acoplar gestores a esos eventos, Yii tiene un servicio especial llamado despachador de eventos.\n" +"Se encuentra disponible en el [paquete yiisoft/event-dispatcher](https://github.com/yiisoft/event-dispatcher)." + +#. type: Title ## +#: en/concept/events.md +#, no-wrap +msgid "Event Handlers " +msgstr "Gestores de Eventos " + +#. type: Plain text +#: en/concept/events.md +#, fuzzy +msgid "An event handler is [PHP callable](https://www.php.net/manual/en/language.types.callable.php) that gets executed when the event it's attached to is triggered." +msgstr "" +"Un gestor de eventos es una [llamada de retorno PHP (PHP callback)](https://www.php.net/manual/en/language.types.callable.php) que se ejecuta cuando se\n" +"lanza el evento al que corresponde." + +#. type: Plain text +#: en/concept/events.md +msgid "The signature of an event handler is:" +msgstr "La firma de un gestor de eventos es:" + +#. type: Fenced code block (php) +#: en/concept/events.md +#, no-wrap +msgid "" +"function (EventClass $event) {\n" +" // handle it\n" +"}\n" +msgstr "" +"function (EventClass $event) {\n" +" // gestionar evento\n" +"}\n" + +#. type: Title ## +#: en/concept/events.md +#, no-wrap +msgid "Attaching event handlers " +msgstr "Acoplar Gestores de Eventos " + +#. type: Plain text +#: en/concept/events.md +msgid "You can attach a handler to an event like the following:" +msgstr "Puedes acoplar un gestor a un evento como se demuestra a continuación:" + +#. type: Fenced code block (php) +#: en/concept/events.md +#, no-wrap +msgid "" +"use Yiisoft\\EventDispatcher\\Provider\\Provider;\n" +"\n" +"final readonly class WelcomeEmailSender\n" +"{\n" +" public function __construct(Provider $provider)\n" +" {\n" +" $provider->attach([$this, 'handleUserSignup']);\n" +" }\n" +"\n" +" public function handleUserSignup(UserSignedUp $event)\n" +" {\n" +" // handle it \n" +" }\n" +"}\n" +msgstr "" +"use Yiisoft\\EventDispatcher\\Provider\\Provider;\n" +"\n" +"class WelcomeEmailSender\n" +"{\n" +" public function __construct(Provider $provider)\n" +" {\n" +" $provider->attach([$this, 'handleUserSignup']);\n" +" }\n" +"\n" +" public function handleUserSignup(UserSignedUp $event)\n" +" {\n" +" // gestionar evento\n" +" }\n" +"}\n" + +#. type: Plain text +#: en/concept/events.md +msgid "The `attach()` method is accepting a callback. Based on the type of this callback argument, the event type is determined." +msgstr "" +"El método `attach()` acepta funciones de retorno (callbacks). Dependiendo del argumento de la función de retorno\n" +"se determina el tipo de evento." + +#. type: Title ## +#: en/concept/events.md +#, no-wrap +msgid "Event handlers order" +msgstr "Orden de Gestores de Eventos" + +#. type: Plain text +#: en/concept/events.md +msgid "You may attach one or more handlers to a single event. When an event is triggered, the attached handlers will be called in the order that they were attached to the event. In case an event implements `Psr\\EventDispatcher\\StoppableEventInterface`, event handler can stop executing the rest of the handlers that follow it if `isPropagationStopped()` returns `true`." +msgstr "" +"Se puede acoplar uno o más gestores a un único evento. Cuando se lanza un evento, se ejecutarán los gestores adjuntos\n" +"en el orden que se hayan añadido al evento. En el caso que un evento implemente `Psr\\EventDispatcher\\StoppableEventInterface`,\n" +"el gestor de eventos puede detener la ejecución del resto de los gestores que le siguen si `isPropagationStopped()` devuelve `true`." + +#. type: Plain text +#: en/concept/events.md +msgid "In general, it's better not to rely on the order of event handlers." +msgstr "En general, lo mejor es no depender del orden de los gestores de eventos." + +#. type: Title ## +#: en/concept/events.md +#, no-wrap +msgid "Raising events " +msgstr "Lanzamiento de Eventos " + +#. type: Plain text +#: en/concept/events.md +msgid "Events are raised like the following:" +msgstr "Los eventos se lanzan de la siguiente forma:" + +#. type: Fenced code block (php) +#: en/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" +" }\n" +"\n" +" public function signup(SignupForm $form)\n" +" {\n" +" // handle signup\n" +"\n" +" $event = new UserSignedUp($form);\n" +" $this->eventDispatcher->dispatch($event);\n" +" }\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" +" }\n" +"\n" +" public function signup(SignupForm $form)\n" +" {\n" +" // handle signup\n" +"\n" +" $event = new UserSignedUp($form);\n" +" $this->eventDispatcher->dispatch($event);\n" +" }\n" +"}\n" + +#. type: Plain text +#: en/concept/events.md +msgid "First, you create an event supplying it with data that may be useful for handlers. Then you dispatch the event." +msgstr "Primero, estamos creando un evento entregandole datos que pueden ser útiles para los gestores. Luego, se lanza el evento." + +#. type: Plain text +#: en/concept/events.md +msgid "The event class itself may look like the following:" +msgstr "La clase del evento en sí se podría ver como esto:" + +#. type: Fenced code block (php) +#: en/concept/events.md +#, no-wrap +msgid "" +"final readonly class UserSignedUp\n" +"{\n" +" public function __construct(\n" +" public SignupForm $form\n" +" )\n" +" {\n" +" }\n" +"}\n" +msgstr "" +"final readonly class UserSignedUp\n" +"{\n" +" public function __construct(\n" +" public SignupForm $form\n" +" )\n" +" {\n" +" }\n" +"}\n" + +#. type: Title ## +#: en/concept/events.md +#, no-wrap +msgid "Events hierarchy" +msgstr "Jerarquía de Eventos" + +#. type: Plain text +#: en/concept/events.md +msgid "Events don't have any name or wildcard matching on purpose. Event class names and class/interface hierarchy and composition could be used to achieve great flexibility:" +msgstr "" +"Los eventos no tienen nombre o wildcard matching por una razón. Los nombres de clases de los eventos y la jerarquía de clases/interfaces\n" +"y composición se puede utilizar para obtener mayor flexibilidad:" + +#. type: Fenced code block (php) +#: en/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 "" +"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 +#: en/concept/events.md +msgid "With the interface, you can listen to all document-related events:" +msgstr "Para que la interface de arriba escuche todos los eventos relacionados con documentos, se puede realizar de la siguiente forma:" + +#. type: Fenced code block (php) +#: en/concept/events.md +#, no-wrap +msgid "" +"$provider->attach(function (DocumentEvent $event) {\n" +" // log events here\n" +"});\n" +msgstr "" +"$provider->attach(function (DocumentEvent $event) {\n" +" // log events here\n" +"});\n" + +#. type: Title ## +#: en/concept/events.md +#, no-wrap +msgid "Detaching event handlers " +msgstr "Desacoplar Gestores de Eventos " + +#. type: Plain text +#: en/concept/events.md +msgid "To detach a handler from an event you can call `detach()` method:" +msgstr "Para desacoplar un gestor de eventos puedes llamar al método `detach()`:" + +#. type: Fenced code block (php) +#: en/concept/events.md +#, no-wrap +msgid "$provider->detach(DocmentEvent::class);\n" +msgstr "$provider->detach(DocmentEvent::class);\n" + +#. type: Title ## +#: en/concept/events.md +#, no-wrap +msgid "Configuring application events" +msgstr "" + +#. type: Plain text +#: en/concept/events.md +msgid "You usually assign event handlers via application config. See [\"Configuration\"](configuration.md) for details." +msgstr "" diff --git a/_translations/guide/po/es/concept_immutability.md.po b/_translations/guide/po/es/concept_immutability.md.po new file mode 100644 index 00000000..90182929 --- /dev/null +++ b/_translations/guide/po/es/concept_immutability.md.po @@ -0,0 +1,224 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" +"PO-Revision-Date: 2025-09-04 11:19+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title # +#: ../../guide/en/concept/immutability.md +#, no-wrap +msgid "Immutability" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 ## +#: ../../guide/en/concept/immutability.md +#, no-wrap +msgid "Mutable pitfalls (what we avoid)" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/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 ## +#: ../../guide/en/concept/immutability.md +#, no-wrap +msgid "Creating an immutable object in PHP" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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) +#: ../../guide/en/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: '- ' +#: ../../guide/en/concept/immutability.md +msgid "We mark the class `final` to prevent subclass mutations; alternatively, design for extension carefully." +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/concept/immutability.md +msgid "Validate in the constructor and `with*` methods so every instance is always valid." +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 ## +#: ../../guide/en/concept/immutability.md +#, no-wrap +msgid "Using clone (and why it is inexpensive)" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/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) +#: ../../guide/en/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 ## +#: ../../guide/en/concept/immutability.md +#, no-wrap +msgid "Usage style" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/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: '- ' +#: ../../guide/en/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 +#: ../../guide/en/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/guide/po/es/databases_db-migrations.md.po b/_translations/guide/po/es/databases_db-migrations.md.po new file mode 100644 index 00000000..1d56a10e --- /dev/null +++ b/_translations/guide/po/es/databases_db-migrations.md.po @@ -0,0 +1,169 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" +"PO-Revision-Date: 2025-09-04 11:19+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title # +#: ../../guide/en/databases/db-migrations.md +#, no-wrap +msgid "Migrations" +msgstr "" + +#. type: Plain text +#: ../../guide/en/databases/db-migrations.md +msgid "To use migrations, install [yiisoft/db-migration](https://github.com/yiisoft/db-migration/) package:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../../guide/en/databases/db-migrations.md +#, no-wrap +msgid "composer require yiisoft/db-migration\n" +msgstr "" + +#. type: Title ### +#: ../../guide/en/databases/db-migrations.md +#, no-wrap +msgid "Example usage" +msgstr "" + +#. type: Plain text +#: ../../guide/en/databases/db-migrations.md +msgid "First, configure a DI container. Create `config/common/db.php` with the following content:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/databases/db-migrations.md +#, no-wrap +msgid "" +" [\n" +" 'class' => SqliteConnection::class,\n" +" '__construct()' => [\n" +" 'dsn' => 'sqlite:' . __DIR__ . '/Data/yiitest.sq3'\n" +" ]\n" +" ]\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/databases/db-migrations.md +msgid "Add the following to `config/params.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/databases/db-migrations.md +#, no-wrap +msgid "" +"...\n" +"'yiisoft/db-migration' => [\n" +" 'newMigrationNamespace' => 'App\\\\Migration',\n" +" 'sourceNamespaces' => ['App\\\\Migration'],\n" +"],\n" +"...\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/databases/db-migrations.md +msgid "Now test if it works:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../../guide/en/databases/db-migrations.md +#, no-wrap +msgid "./yii list migrate\n" +msgstr "" + +#. type: Title ### +#: ../../guide/en/databases/db-migrations.md +#, no-wrap +msgid "Creating a migration" +msgstr "" + +#. type: Plain text +#: ../../guide/en/databases/db-migrations.md +msgid "To work with migrations, you can use the provided [view](https://github.com/yiisoft/db-migration/tree/master/resources/views)." +msgstr "" + +#. type: Fenced code block (shell) +#: ../../guide/en/databases/db-migrations.md +#, no-wrap +msgid "./yii migrate:create my_first_table --command=table --fields=name,example --table-comment=my_first_table\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/databases/db-migrations.md +msgid "That would generate the following:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/databases/db-migrations.md +#, no-wrap +msgid "" +"createTable('my_first_table', [\n" +" 'id' => $b->primaryKey(),\n" +" 'name',\n" +" 'example',\n" +" ]);\n" +" \n" +" $b->addCommentOnTable('my_first_table', 'dest');\n" +" }\n" +"\n" +" public function down(MigrationBuilder $b): void\n" +" {\n" +" $b->dropTable('my_first_table');\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/databases/db-migrations.md +msgid "For more information [see](https://github.com/yiisoft/db-migration/tree/master/docs/guide/en)" +msgstr "" + +#. type: Title ### +#: ../../guide/en/databases/db-migrations.md +#, no-wrap +msgid "Upgrading from Yii2" +msgstr "" + +#. type: Plain text +#: ../../guide/en/databases/db-migrations.md +msgid "Migrations in Yii2 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." +msgstr "" diff --git a/_translations/guide/po/es/glossary.md.po b/_translations/guide/po/es/glossary.md.po new file mode 100644 index 00000000..8b848f49 --- /dev/null +++ b/_translations/guide/po/es/glossary.md.po @@ -0,0 +1,210 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "A" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, fuzzy, no-wrap +#| msgid "Aliases" +msgid "alias" +msgstr "Alias" + +#. type: Plain text +#: ../../guide/en/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 ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "asset" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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." +msgstr "" + +#. type: Title # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "C" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "configuration" +msgstr "" + +#. type: Plain text +#: ../../guide/en/glossary.md +msgid "The 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 # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "D" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "DI" +msgstr "" + +#. type: Plain text +#: ../../guide/en/glossary.md +msgid "Dependency Injection is a programming technique where an object injects a dependent object. [\"DI\"](concept/di-container.md)" +msgstr "" + +#. type: Title # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "I" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "installation" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "M" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "middleware" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "module" +msgstr "" + +#. type: Plain text +#: ../../guide/en/glossary.md +msgid "The module is a sub-application that groups some code based on a use-case. It's typically used within the main application and may contain URL handlers or console commands." +msgstr "" + +#. type: Title # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "N" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "namespace" +msgstr "" + +#. type: Plain text +#: ../../guide/en/glossary.md +msgid "Namespace refers to a [PHP language feature](https://www.php.net/manual/en/language.namespaces.php)." +msgstr "" + +#. type: Title # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "P" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "package" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 package manager." +msgstr "" + +#. type: Title # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "R" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "rule" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "Q" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "queue" +msgstr "" + +#. type: Plain text +#: ../../guide/en/glossary.md +msgid "A queue is similar to a stack. Queue follows First-In-First-Out methodology." +msgstr "" + +#. type: Title # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "V" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "vendor" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 "" diff --git a/_translations/guide/po/es/intro_upgrade-from-v2.md.po b/_translations/guide/po/es/intro_upgrade-from-v2.md.po new file mode 100644 index 00000000..2c702362 --- /dev/null +++ b/_translations/guide/po/es/intro_upgrade-from-v2.md.po @@ -0,0 +1,267 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title # +#: en/intro/upgrade-from-v2.md +#, no-wrap +msgid "Upgrading from Version 2.0" +msgstr "" + +#. type: Plain text +#: en/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"> If you haven't used Yii2, you can skip this section and get directly to \"[getting started](../start/installation.md)\"\n" +"> section.\n" +msgstr "" + +#. type: Plain text +#: en/intro/upgrade-from-v2.md +msgid "While sharing some common ideas and values, Yii 3 is conceptually different from Yii 2. There is no easy upgrade path, so first [check maintenance policy and end-of-life dates for Yii 2](https://www.yiiframework.com/release-cycle) and consider starting new projects on Yii 3 while keeping existing ones on Yii 2." +msgstr "" + +#. type: Title ## +#: en/intro/upgrade-from-v2.md +#, no-wrap +msgid "PHP requirements" +msgstr "" + +#. type: Plain text +#: en/intro/upgrade-from-v2.md +msgid "Yii3 requires PHP 8.2 or above. As a result, there are language features used that weren't used in Yii 2:" +msgstr "" + +#. type: Bullet: '- ' +#: en/intro/upgrade-from-v2.md +msgid "[Type declarations](https://www.php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration)" +msgstr "" + +#. type: Bullet: '- ' +#: en/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: '- ' +#: en/intro/upgrade-from-v2.md +msgid "[Class constant visibility](https://www.php.net/manual/en/language.oop5.constants.php)" +msgstr "" + +#. type: Bullet: '- ' +#: en/intro/upgrade-from-v2.md +msgid "[Named arguments](https://www.php.net/manual/en/functions.arguments.php#functions.named-arguments)" +msgstr "" + +#. type: Bullet: '- ' +#: en/intro/upgrade-from-v2.md +msgid "[Anonymous classes](https://www.php.net/manual/en/language.oop5.anonymous.php)" +msgstr "" + +#. type: Bullet: '- ' +#: en/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: '- ' +#: en/intro/upgrade-from-v2.md +msgid "[Generators](https://www.php.net/manual/en/language.generators.php)" +msgstr "" + +#. type: Bullet: '- ' +#: en/intro/upgrade-from-v2.md +msgid "[Variadic functions](https://www.php.net/manual/en/functions.arguments.php#functions.variable-arg-list)" +msgstr "" + +#. type: Bullet: '- ' +#: en/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: '- ' +#: en/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: '- ' +#: en/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: '- ' +#: en/intro/upgrade-from-v2.md +msgid "[Attributes](https://www.php.net/manual/en/language.attributes.php)" +msgstr "" + +#. type: Title ## +#: en/intro/upgrade-from-v2.md +#, no-wrap +msgid "Preliminary refactoring" +msgstr "" + +#. type: Plain text +#: en/intro/upgrade-from-v2.md +msgid "It's a good idea to refactor your Yii 2 project before porting it to Yii 3. That would both make porting easier and benefit the project in question while it's not moved to Yii 3 yet." +msgstr "" + +#. type: Title ### +#: en/intro/upgrade-from-v2.md +#, no-wrap +msgid "Use DI instead of the service locator" +msgstr "" + +#. type: Plain text +#: en/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"Since Yii 3 is forcing you to inject dependencies, it's a good idea to prepare and switch from using\n" +"service locator (`Yii::$app->`) to [DI container](https://www.yiiframework.com/doc/guide/2.0/en/concept-di-container).\n" +msgstr "" + +#. type: Plain text +#: en/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"If usage of DI container is problematic for whatever reason, consider moving all calls to `Yii::$app->` to controller\n" +"actions and widgets and passing dependencies manually from a controller to what needs them.\n" +msgstr "" + +#. type: Plain text +#: en/intro/upgrade-from-v2.md +msgid "See [Dependency injection and container](../concept/di-container.md) for an explanation of the idea." +msgstr "" + +#. type: Title ### +#: en/intro/upgrade-from-v2.md +#, no-wrap +msgid "Introduce repositories for getting data" +msgstr "" + +#. type: Plain text +#: en/intro/upgrade-from-v2.md +msgid "Since Active Record isn't the only way to work with a database in Yii 3, consider introducing repositories that would hide details of getting data and gather them in a single place. You can later redo it:" +msgstr "" + +#. type: Fenced code block (php) +#: en/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"final readonly class PostRepository\n" +"{\n" +" public function getArchive()\n" +" {\n" +" // ...\n" +" }\n" +" \n" +" public function getTop10ForFrontPage()\n" +" {\n" +" // ...\n" +" }\n" +"\n" +"}\n" +msgstr "" + +#. type: Title ### +#: en/intro/upgrade-from-v2.md +#, no-wrap +msgid "Separate domain layer from infrastructure" +msgstr "" + +#. type: Plain text +#: en/intro/upgrade-from-v2.md +msgid "In case you have a rich complicated domain, it's a good idea to separate it from infrastructure provided by a framework that's all the business logic has to go to framework-independent classes." +msgstr "" + +#. type: Title ### +#: en/intro/upgrade-from-v2.md +#, no-wrap +msgid "Move more into components" +msgstr "" + +#. type: Plain text +#: en/intro/upgrade-from-v2.md +msgid "Yii 3 services are conceptually similar to Yii 2 components, so it's a good idea to move reusable parts of your application into components." +msgstr "" + +#. type: Title ## +#: en/intro/upgrade-from-v2.md +#, no-wrap +msgid "Things to learn" +msgstr "" + +#. type: Title ## +#: en/intro/upgrade-from-v2.md en/start/prerequisites.md +#, no-wrap +msgid "Docker" +msgstr "" + +#. type: Plain text +#: en/intro/upgrade-from-v2.md +msgid "Default application templates are using [Docker](https://www.docker.com/get-started/) to run application. It's a good idea to learn how to use it and use it for your own projects since it provides a lot of benefits:" +msgstr "" + +#. type: Bullet: '1. ' +#: en/intro/upgrade-from-v2.md +msgid "Exactly the same environment as in production." +msgstr "" + +#. type: Bullet: '2. ' +#: en/intro/upgrade-from-v2.md +msgid "No need to install anything except Docker itself." +msgstr "" + +#. type: Bullet: '3. ' +#: en/intro/upgrade-from-v2.md +msgid "Environment is per application, not per server." +msgstr "" + +#. type: Title ### +#: en/intro/upgrade-from-v2.md +#, no-wrap +msgid "Environment variables" +msgstr "" + +#. type: Plain text +#: en/intro/upgrade-from-v2.md +msgid "Yii3 application templates are using [environment variables](https://en.wikipedia.org/wiki/Environment_variable) to configure pars of the application. The concept is [very handy for Dockerized applications](https://12factor.net/) but might be alien to users of Yii 1.1 and Yii 2." +msgstr "" + +#. type: Title ### +#: en/intro/upgrade-from-v2.md +#, no-wrap +msgid "Handlers" +msgstr "" + +#. type: Plain text +#: en/intro/upgrade-from-v2.md +msgid "Unlike Yii2, Yii3 doesn't have controllers per se. Instead, it uses [handlers](../structure/handler.md) which are similar to controllers but different." +msgstr "" + +#. type: Title ### +#: en/intro/upgrade-from-v2.md +#, no-wrap +msgid "Application structure" +msgstr "" + +#. type: Plain text +#: en/intro/upgrade-from-v2.md +msgid "Suggested Yii3 application structure is different from Yii 2. It's described in [application structure](../structure/overview.md)." +msgstr "" + +#. type: Plain text +#: en/intro/upgrade-from-v2.md +msgid "Despite that, Yii3 is flexible, so it's still possible to use a structure similar to Yii 2 with Yii 3." +msgstr "" diff --git a/_translations/guide/po/es/intro_what-is-yii.md.po b/_translations/guide/po/es/intro_what-is-yii.md.po new file mode 100644 index 00000000..0c5add48 --- /dev/null +++ b/_translations/guide/po/es/intro_what-is-yii.md.po @@ -0,0 +1,146 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" +"PO-Revision-Date: 2025-09-04 07:51+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title # +#: ../../guide/en/intro/what-is-yii.md +#, no-wrap +msgid "What is Yii" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 "" + +#. type: Title ## +#: ../../guide/en/intro/what-is-yii.md +#, no-wrap +msgid "What's Yii best for" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 "" + +#. type: Title ## +#: ../../guide/en/intro/what-is-yii.md +#, no-wrap +msgid "How does Yii compare with other frameworks?" +msgstr "" + +#. type: Plain text +#: ../../guide/en/intro/what-is-yii.md +msgid "If you're already familiar with another framework, you may appreciate knowing how Yii compares:" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/intro/what-is-yii.md +msgid "Yii takes the [philosophy of being practical and helpful](https://github.com/yiisoft/docs/blob/master/001-yii-values.md) achieving:" +msgstr "" + +#. type: Bullet: ' - ' +#: ../../guide/en/intro/what-is-yii.md +msgid "Performance in both development and execution." +msgstr "" + +#. type: Bullet: ' - ' +#: ../../guide/en/intro/what-is-yii.md +msgid "Convenient customizable defaults." +msgstr "" + +#. type: Bullet: ' - ' +#: ../../guide/en/intro/what-is-yii.md +msgid "Practice-orientation." +msgstr "" + +#. type: Bullet: ' - ' +#: ../../guide/en/intro/what-is-yii.md +msgid "Simplicity." +msgstr "" + +#. type: Bullet: ' - ' +#: ../../guide/en/intro/what-is-yii.md +msgid "Explicitness." +msgstr "" + +#. type: Bullet: ' - ' +#: ../../guide/en/intro/what-is-yii.md +msgid "Consistency." +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 "" + +#. type: Plain text +#: ../../guide/en/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 "" + +#. type: Title ## +#: ../../guide/en/intro/what-is-yii.md +#, no-wrap +msgid "Yii versions" +msgstr "" + +#. type: Plain text +#: ../../guide/en/intro/what-is-yii.md +msgid "Yii currently has three major versions available: 1.1, 2.0, and 3.0." +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/intro/what-is-yii.md +msgid "Version 1.1 is the old generation and is now in the feature freeze bugfix mode." +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/intro/what-is-yii.md +msgid "Version 2.0 is a current stable version in the feature freeze bugfix mode." +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/intro/what-is-yii.md +msgid "Version 3.0 is the current version in development. This guide is mainly about version 3." +msgstr "" + +#. type: Title ## +#: ../../guide/en/intro/what-is-yii.md +#, no-wrap +msgid "Requirements and prerequisites" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 "" + +#. type: Plain text +#: ../../guide/en/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 "" diff --git a/_translations/guide/po/es/runtime_cookies.md.po b/_translations/guide/po/es/runtime_cookies.md.po new file mode 100644 index 00000000..36ada364 --- /dev/null +++ b/_translations/guide/po/es/runtime_cookies.md.po @@ -0,0 +1,312 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\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/guide/po/es/runtime_handling-errors.md.po b/_translations/guide/po/es/runtime_handling-errors.md.po new file mode 100644 index 00000000..ea7b73e0 --- /dev/null +++ b/_translations/guide/po/es/runtime_handling-errors.md.po @@ -0,0 +1,441 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title # +#: en/runtime/handling-errors.md +#, no-wrap +msgid "Handling errors" +msgstr "" + +#. type: Plain text +#: en/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: '- ' +#: en/runtime/handling-errors.md +msgid "[PSR-15](https://www.php-fig.org/psr/psr-15/) middleware for catching unhandled errors." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/handling-errors.md +msgid "PSR-15 middleware for mapping certain exceptions to custom responses." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/handling-errors.md +msgid "Production and debug modes." +msgstr "" + +#. type: Bullet: '- ' +#: en/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: '- ' +#: en/runtime/handling-errors.md +msgid "Takes PHP settings into account." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/handling-errors.md +msgid "Handles out of memory errors, fatal errors, warnings, notices, and exceptions." +msgstr "" + +#. type: Bullet: '- ' +#: en/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: '- ' +#: en/runtime/handling-errors.md +msgid "Detects a response format based on a mime type of the request." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/handling-errors.md +msgid "Supports responding with HTML, plain text, JSON, XML, and headers out of the box." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/handling-errors.md +msgid "You can implement your own error rendering for extra types." +msgstr "" + +#. type: Plain text +#: en/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 ## +#: en/runtime/handling-errors.md +#, no-wrap +msgid "Using error handler" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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) +#: en/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 +#: en/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) +#: en/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 +#: en/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) +#: en/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" +" ErrorHandler::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 +#: en/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 ## +#: en/runtime/handling-errors.md +#, no-wrap +msgid "Rendering error data" +msgstr "" + +#. type: Plain text +#: en/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: '- ' +#: en/runtime/handling-errors.md +msgid "`Yiisoft\\ErrorHandler\\Renderer\\HeaderRenderer` - Renders error into HTTP headers. It's used for `HEAD` request." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/handling-errors.md +msgid "`Yiisoft\\ErrorHandler\\Renderer\\HtmlRenderer` - Renders error into HTML." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/handling-errors.md +msgid "`Yiisoft\\ErrorHandler\\Renderer\\JsonRenderer` - Renders error into JSON." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/handling-errors.md +msgid "`Yiisoft\\ErrorHandler\\Renderer\\PlainTextRenderer` - Renders error into plain text." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/handling-errors.md +msgid "`Yiisoft\\ErrorHandler\\Renderer\\XmlRenderer` - Renders error into XML." +msgstr "" + +#. type: Plain text +#: en/runtime/handling-errors.md +msgid "The renderer produces detailed error data depending on whether debug mode is enabled or disabled." +msgstr "" + +#. type: Plain text +#: en/runtime/handling-errors.md +msgid "An Example of header rendering with a debugging mode turned off:" +msgstr "" + +#. type: Fenced code block +#: en/runtime/handling-errors.md +#, no-wrap +msgid "" +"...\n" +"X-Error-Message: An internal server error occurred.\n" +"...\n" +msgstr "" + +#. type: Plain text +#: en/runtime/handling-errors.md +msgid "An Example of header rendering with a debugging mode turned on:" +msgstr "" + +#. type: Fenced code block +#: en/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 +#: en/runtime/handling-errors.md +msgid "Example of JSON rendering output with a debugging mode turned off:" +msgstr "" + +#. type: Fenced code block (json) +#: en/runtime/handling-errors.md +#, no-wrap +msgid "{\"message\":\"An internal server error occurred.\"}\n" +msgstr "" + +#. type: Plain text +#: en/runtime/handling-errors.md +msgid "An Example of JSON rendering output with debugging mode turned on:" +msgstr "" + +#. type: Fenced code block (json) +#: en/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 +#: en/runtime/handling-errors.md +msgid "Example of HTML rendering with debugging mode turned off:" +msgstr "" + +#. type: Plain text +#: en/runtime/handling-errors.md +msgid "![View production](img/view-production.png)" +msgstr "" + +#. type: Plain text +#: en/runtime/handling-errors.md +msgid "Example of HTML rendering with debugging mode on and a light theme:" +msgstr "" + +#. type: Plain text +#: en/runtime/handling-errors.md +msgid "![View development with light theme](img/view-development-light.png)" +msgstr "" + +#. type: Plain text +#: en/runtime/handling-errors.md +msgid "Example of HTML rendering with debugging mode on and a dark theme:" +msgstr "" + +#. type: Plain text +#: en/runtime/handling-errors.md +msgid "![View development with dark theme](img/view-development-dark.png)" +msgstr "" + +#. type: Plain text +#: en/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 that you register within the error catcher. By default, it supports JSON, XML, and plain text." +msgstr "" + +#. type: Title ### +#: en/runtime/handling-errors.md +#, no-wrap +msgid "Implementing your own renderer" +msgstr "" + +#. type: Plain text +#: en/runtime/handling-errors.md +msgid "You may customize the error response format by providing your own instance of `Yiisoft\\ErrorHandler\\ThrowableRendererInterface` when registering error catcher middleware." +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/handling-errors.md +#, no-wrap +msgid "" +"use Psr\\Http\\Message\\ServerRequestInterface;\n" +"use Yiisoft\\ErrorHandler\\ErrorData;\n" +"use Yiisoft\\ErrorHandler\\ThrowableRendererInterface;\n" +"\n" +"final readonly class MyRenderer implements ThrowableRendererInterface\n" +"{\n" +" public function render(Throwable $t, ServerRequestInterface $request = null): ErrorData\n" +" {\n" +" return new ErrorData($t->getMessage());\n" +" }\n" +"\n" +" public function renderVerbose(Throwable $t, ServerRequestInterface $request = null): ErrorData\n" +" {\n" +" return new ErrorData(\n" +" $t->getMessage(),\n" +" ['X-Custom-Header' => 'value-header'], // Headers to be added to the response.\n" +" );\n" +" }\n" +"};\n" +msgstr "" + +#. type: Plain text +#: en/runtime/handling-errors.md +msgid "You may configure it in the application configuration `config/web.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/handling-errors.md +#, no-wrap +msgid "" +"use Psr\\Container\\ContainerInterface;\n" +"use Psr\\Http\\Message\\ResponseFactoryInterface;\n" +"use Yiisoft\\ErrorHandler\\ErrorHandler;\n" +"use Yiisoft\\ErrorHandler\\Middleware\\ErrorCatcher;\n" +"\n" +"return [\n" +" // ...\n" +" ErrorCatcher::class => static function (ContainerInterface $container): ErrorCatcher {\n" +" $errorCatcher = new ErrorCatcher(\n" +" $container->get(ResponseFactoryInterface::class),\n" +" $container->get(ErrorHandler::class),\n" +" $container,\n" +" );\n" +" // Returns a new instance without renderers by the specified content types.\n" +" $errorCatcher = $errorCatcher->withoutRenderers('application/xml', 'text/xml');\n" +" // Returns a new instance with the specified content type and renderer class.\n" +" return $errorCatcher->withRenderer('my/format', new MyRenderer());\n" +" },\n" +" // ...\n" +"];\n" +msgstr "" + +#. type: Title ## +#: en/runtime/handling-errors.md +#, no-wrap +msgid "Friendly exceptions" +msgstr "" + +#. type: Plain text +#: en/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) +#: en/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 +#: en/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/guide/po/es/runtime_logging.md.po b/_translations/guide/po/es/runtime_logging.md.po new file mode 100644 index 00000000..a06a2197 --- /dev/null +++ b/_translations/guide/po/es/runtime_logging.md.po @@ -0,0 +1,642 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title # +#: en/runtime/logging.md +#, no-wrap +msgid "Logging" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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 +#: en/runtime/logging.md +msgid "Using the Yii logging framework involves the following steps:" +msgstr "" + +#. type: Bullet: '* ' +#: en/runtime/logging.md +msgid "Record [log messages](#log-messages) at various places in your code;" +msgstr "" + +#. type: Bullet: '* ' +#: en/runtime/logging.md +msgid "Configure [log targets](#log-targets) in the application configuration to filter and export log messages;" +msgstr "" + +#. type: Bullet: '* ' +#: en/runtime/logging.md +msgid "Examine the filtered logged messages exported by different targets (e.g. the [Yii debugger](../tool/debugger.md))." +msgstr "" + +#. type: Plain text +#: en/runtime/logging.md +msgid "In this section, the focus in on the first two steps." +msgstr "" + +#. type: Title ## +#: en/runtime/logging.md +#, no-wrap +msgid "Log Messages " +msgstr "" + +#. type: Plain text +#: en/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) +#: en/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 +#: en/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: '- ' +#: en/runtime/logging.md +msgid "`emergency` - System is unusable." +msgstr "" + +#. type: Bullet: '- ' +#: en/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: '- ' +#: en/runtime/logging.md +msgid "`critical` - Critical conditions. Example: Application component unavailable, unexpected exception." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/logging.md +msgid "`error` - Runtime errors that don't require immediate action but should typically be logged and monitored." +msgstr "" + +#. type: Bullet: '- ' +#: en/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: '- ' +#: en/runtime/logging.md +msgid "`notice` - Normal but significant events." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/logging.md +msgid "`info` - Interesting events. Example: User logs in, SQL logs." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/logging.md +msgid "`debug` - Detailed debug information." +msgstr "" + +#. type: Plain text +#: en/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) +#: en/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 +#: en/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 +#: en/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 +#: en/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 +#: en/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 ## +#: en/runtime/logging.md +#, no-wrap +msgid "Log targets " +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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) +#: en/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 +#: en/runtime/logging.md +msgid "In the above code, two log targets are registered:" +msgstr "" + +#. type: Bullet: '* ' +#: en/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 +#: en/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 +#: en/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: '* ' +#: en/runtime/logging.md +msgid "[[\\Yiisoft\\Log\\PsrTarget]]: passes log messages to another PSR-3 compatible logger." +msgstr "" + +#. type: Bullet: '* ' +#: en/runtime/logging.md +msgid "[[\\Yiisoft\\Log\\StreamTarget]]: writes log messages into a specified output stream." +msgstr "" + +#. type: Bullet: '* ' +#: en/runtime/logging.md +msgid "[[\\Yiisoft\\Log\\Target\\Db\\DbTarget]]: saves log messages in database." +msgstr "" + +#. type: Bullet: '* ' +#: en/runtime/logging.md +msgid "[[\\Yiisoft\\Log\\Target\\Email\\EmailTarget]]: sends log messages to pre-specified email addresses." +msgstr "" + +#. type: Bullet: '* ' +#: en/runtime/logging.md +msgid "[[\\Yiisoft\\Log\\Target\\File\\FileTarget]]: saves log messages in files." +msgstr "" + +#. type: Bullet: '* ' +#: en/runtime/logging.md +msgid "[[\\Yiisoft\\Log\\Target\\Syslog\\SyslogTarget]]: saves log messages to syslog by calling the PHP function `syslog()`." +msgstr "" + +#. type: Plain text +#: en/runtime/logging.md +msgid "In the following, we will describe the features common to all log targets." +msgstr "" + +#. type: Title ### +#: en/runtime/logging.md +#, no-wrap +msgid "Message Filtering " +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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 +#: en/runtime/logging.md +msgid "By default, the target will process messages of *any* severity level." +msgstr "" + +#. type: Plain text +#: en/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 +#: en/runtime/logging.md +msgid "By default, the target will process messages of *any* category." +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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) +#: en/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 ### +#: en/runtime/logging.md +#, no-wrap +msgid "Message Formatting " +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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 +#: en/runtime/logging.md +msgid "By default, log messages have the following format:" +msgstr "" + +#. type: Fenced code block +#: en/runtime/logging.md +#, no-wrap +msgid "Timestamp Prefix[Level][Category] Message Context\n" +msgstr "" + +#. type: Plain text +#: en/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) +#: en/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 +#: en/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) +#: en/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 +#: en/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) +#: en/runtime/logging.md +#, no-wrap +msgid "function (\\Yiisoft\\Log\\Message $message, array $commonContext): string;\n" +msgstr "" + +#. type: Plain text +#: en/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) +#: en/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 ### +#: en/runtime/logging.md +#, no-wrap +msgid "Message Trace Level " +msgstr "" + +#. type: Plain text +#: en/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) +#: en/runtime/logging.md +#, no-wrap +msgid "" +"$logger = new \\Yiisoft\\Log\\Logger($targets);\n" +"$logger->setTraceLevel(3);\n" +msgstr "" + +#. type: Plain text +#: en/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) +#: en/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 +#: en/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 ### +#: en/runtime/logging.md +#, no-wrap +msgid "Message flushing and exporting " +msgstr "" + +#. type: Plain text +#: en/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) +#: en/runtime/logging.md +#, no-wrap +msgid "" +"$logger = new \\Yiisoft\\Log\\Logger($targets);\n" +"$logger->setFlushInterval(100); // default is 1000\n" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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) +#: en/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 +#: en/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) +#: en/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 +#: en/runtime/logging.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> Frequent message flushing and exporting will degrade the performance of your application.\n" +msgstr "" + +#. type: Title ### +#: en/runtime/logging.md +#, no-wrap +msgid "Toggling log targets " +msgstr "" + +#. type: Plain text +#: en/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) +#: en/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 +#: en/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 ### +#: en/runtime/logging.md +#, no-wrap +msgid "Creating new targets " +msgstr "" + +#. type: Plain text +#: en/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 +#: en/runtime/logging.md +msgid "The following protected methods will also be available for child targets:" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/logging.md +msgid "`getMessages` - Get a list of log messages ([[\\Yii\\Log\\Message]] instances)." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/logging.md +msgid "`getFormattedMessages` - Get a list of log messages formatted as strings." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/logging.md +msgid "`formatMessages` - Get all log messages formatted as a string." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/logging.md +msgid "`getCommonContext` - Get an array with common context data in the `key => value` format." +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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) +#: en/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/guide/po/es/runtime_request.md.po b/_translations/guide/po/es/runtime_request.md.po new file mode 100644 index 00000000..984f9bbb --- /dev/null +++ b/_translations/guide/po/es/runtime_request.md.po @@ -0,0 +1,394 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title # +#: en/runtime/request.md +#, no-wrap +msgid "Request" +msgstr "" + +#. type: Plain text +#: en/runtime/request.md +msgid "HTTP request has a method, URI, a set of headers and a body:" +msgstr "" + +#. type: Fenced code block +#: en/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 +#: en/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 +#: en/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) +#: en/runtime/request.md +#, no-wrap +msgid "" +"public function view(ServerRequestInterface $request): ResponseInterface\n" +"{\n" +" // ...\n" +"}\n" +msgstr "" + +#. type: Title ## +#: en/runtime/request.md +#, no-wrap +msgid "Method" +msgstr "" + +#. type: Plain text +#: en/runtime/request.md +msgid "The method could be obtained from a request object:" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/request.md +#, no-wrap +msgid "$method = $request->getMethod();\n" +msgstr "" + +#. type: Plain text +#: en/runtime/request.md +msgid "Usually it's one of the:" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "GET" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "POST" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "PUT" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "DELETE" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "HEAD" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "PATCH" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "OPTIONS" +msgstr "" + +#. type: Plain text +#: en/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) +#: en/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 ## +#: en/runtime/request.md +#, no-wrap +msgid "URI" +msgstr "" + +#. type: Plain text +#: en/runtime/request.md +msgid "A URI has:" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "Scheme (`http`, `https`)" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "Host (`yiiframework.com`)" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "Port (`80`, `443`)" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "Path (`/posts/1`)" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "Query string (`page=1&sort=+id`)" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "Fragment (`#anchor`)" +msgstr "" + +#. type: Plain text +#: en/runtime/request.md +msgid "You can obtain `UriInterface` from request like the following:" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/request.md +#, no-wrap +msgid "$uri = $request->getUri();\n" +msgstr "" + +#. type: Plain text +#: en/runtime/request.md +msgid "Then you can get various details from its methods:" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "`getScheme()`" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "`getAuthority()`" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "`getUserInfo()`" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "`getHost()`" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "`getPort()`" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "`getPath()`" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "`getQuery()`" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "`getFragment()`" +msgstr "" + +#. type: Title ## +#: en/runtime/request.md en/runtime/response.md +#, no-wrap +msgid "Headers" +msgstr "" + +#. type: Plain text +#: en/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) +#: en/runtime/request.md +#, no-wrap +msgid "" +"$headers = $request->getHeaders();\n" +"foreach ($headers as $name => $values) {\n" +" // ...\n" +"}\n" +msgstr "" + +#. type: Plain text +#: en/runtime/request.md +msgid "To get a single header:" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/request.md +#, no-wrap +msgid "$values = $request->getHeader('Accept-Encoding');\n" +msgstr "" + +#. type: Plain text +#: en/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) +#: en/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 +#: en/runtime/request.md +msgid "To check if a header is present in the request:" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/request.md +#, no-wrap +msgid "" +"if ($request->hasHeader('Accept-Encoding')) {\n" +" // ...\n" +"}\n" +msgstr "" + +#. type: Title ## +#: en/runtime/request.md en/runtime/response.md +#, no-wrap +msgid "Body" +msgstr "" + +#. type: Plain text +#: en/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) +#: en/runtime/request.md +#, no-wrap +msgid "$body = $request->getBody();\n" +msgstr "" + +#. type: Plain text +#: en/runtime/request.md +msgid "The `$body` would be an instance of `Psr\\Http\\Message\\StreamInterface`." +msgstr "" + +#. type: Plain text +#: en/runtime/request.md +msgid "Also, you could get a parsed body:" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/request.md +#, no-wrap +msgid "$bodyParameters = $request->getParsedBody();\n" +msgstr "" + +#. type: Plain text +#: en/runtime/request.md +msgid "Parsing depends on PSR-7 implementation and may require middleware for custom body formats." +msgstr "" + +#. type: Fenced code block (php) +#: en/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 ## +#: en/runtime/request.md +#, no-wrap +msgid "File uploads" +msgstr "" + +#. type: Plain text +#: en/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) +#: en/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: Title ## +#: en/runtime/request.md +#, no-wrap +msgid "Attributes" +msgstr "" + +#. type: Plain text +#: en/runtime/request.md +msgid "Application middleware may set custom request attributes using `withAttribute()` method. You can get these attributes with `getAttribute()`." +msgstr "" diff --git a/_translations/guide/po/es/runtime_response.md.po b/_translations/guide/po/es/runtime_response.md.po new file mode 100644 index 00000000..f58451d8 --- /dev/null +++ b/_translations/guide/po/es/runtime_response.md.po @@ -0,0 +1,212 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title ## +#: en/runtime/request.md en/runtime/response.md +#, no-wrap +msgid "Headers" +msgstr "" + +#. type: Title ## +#: en/runtime/request.md en/runtime/response.md +#, no-wrap +msgid "Body" +msgstr "" + +#. type: Title # +#: en/runtime/response.md +#, no-wrap +msgid "Response" +msgstr "" + +#. type: Plain text +#: en/runtime/response.md +msgid "HTTP response has status code and message, a set of headers and a body:" +msgstr "" + +#. type: Fenced code block +#: en/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 +#: en/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 +#: en/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) +#: en/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 ## +#: en/runtime/response.md +#, no-wrap +msgid "Status code" +msgstr "" + +#. type: Plain text +#: en/runtime/response.md +msgid "You can set a status code like the following:" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/response.md +#, no-wrap +msgid "" +"use Yiisoft\\Http\\Status;\n" +"\n" +"$response = $response->withStatus(Status::NOT_FOUND);\n" +msgstr "" + +#. type: Plain text +#: en/runtime/response.md +msgid "Majority of status codes are available from `Status` class for convenience and readability." +msgstr "" + +#. type: Plain text +#: en/runtime/response.md +msgid "You can set headers like this:" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/response.md +#, no-wrap +msgid "$response = $response->withHeader('Content-type', 'application/json');\n" +msgstr "" + +#. type: Plain text +#: en/runtime/response.md +msgid "If there is a need to append a header value to the existing header:" +msgstr "" + +#. type: Fenced code block (php) +#: en/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 +#: en/runtime/response.md +msgid "And, if needed, headers could be removed:" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/response.md +#, no-wrap +msgid "$response = $response->withoutHeader('Set-Cookie');\n" +msgstr "" + +#. type: Plain text +#: en/runtime/response.md +msgid "Response body is an object implementing `Psr\\Http\\Message\\StreamInterface`." +msgstr "" + +#. type: Plain text +#: en/runtime/response.md +msgid "You can write to it via the interface itself:" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/response.md +#, no-wrap +msgid "" +"$body = $response->getBody();\n" +"$body->write('Hello');\n" +msgstr "" + +#. type: Title ## +#: en/runtime/response.md +#, no-wrap +msgid "Examples" +msgstr "" + +#. type: Title ### +#: en/runtime/response.md +#, no-wrap +msgid "Redirecting" +msgstr "" + +#. type: Fenced code block (php) +#: en/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: Title ### +#: en/runtime/response.md +#, no-wrap +msgid "Responding with JSON" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/response.md +#, no-wrap +msgid "" +"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(200)\n" +" ->withHeader('Content-Type', 'application/json');\n" +msgstr "" diff --git a/_translations/guide/po/es/runtime_routing.md.po b/_translations/guide/po/es/runtime_routing.md.po new file mode 100644 index 00000000..66a74661 --- /dev/null +++ b/_translations/guide/po/es/runtime_routing.md.po @@ -0,0 +1,515 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title # +#: en/runtime/routing.md +#, no-wrap +msgid "Routing and URL generation" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/runtime/routing.md +msgid "The reverse process of routing is *URL generation*, which creates a URL from a given named route and the associated query parameters. When you later request the created URL, the routing process can resolve it back into the original route and query parameters." +msgstr "" + +#. type: Plain text +#: en/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 ## +#: en/runtime/routing.md +#, no-wrap +msgid "Configuring routes" +msgstr "" + +#. type: Plain text +#: en/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) +#: en/runtime/routing.md +#, no-wrap +msgid "" +"action([SiteController::class, 'index'])\n" +" ->name('site/index')\n" +"];\n" +msgstr "" + +#. type: Plain text +#: en/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: '- ' +#: en/runtime/routing.md +msgid "get" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/routing.md +msgid "post" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/routing.md +msgid "put" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/routing.md +msgid "delete" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/routing.md +msgid "patch" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/routing.md +msgid "head" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/routing.md +msgid "options" +msgstr "" + +#. type: Plain text +#: en/runtime/routing.md +msgid "If you need many methods, you can use `methods()`:" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/routing.md +#, no-wrap +msgid "" +"action([SiteController::class, 'user'])\n" +" ->name('site/user')\n" +"];\n" +msgstr "" + +#. type: Plain text +#: en/runtime/routing.md +msgid "All these methods accept a route pattern and a handler. 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. You could specify a handler as:" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/routing.md +msgid "[Middleware](../structure/middleware.md) class name." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/routing.md +msgid "Handler action (an array of [HandlerClass, handlerMethod])." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/routing.md +msgid "A callable." +msgstr "" + +#. type: Plain text +#: en/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) +#: en/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 +#: en/runtime/routing.md +msgid "The callable is called as is:" +msgstr "" + +#. type: Fenced code block (php) +#: en/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 +#: en/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 +#: en/runtime/routing.md +msgid "Get current request and handler by type-hinting for `ServerRequestInterface` and `RequestHandlerInterface`. You could add extra handlers to wrap primary one with `middleware()` method:" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/routing.md +#, no-wrap +msgid "" +"action([DownloadController::class, 'download'])\n" +" ->name('download/id')\n" +" ->middleware(LimitDownloadRate::class)\n" +"];\n" +msgstr "" + +#. type: Plain text +#: en/runtime/routing.md +msgid "Check [\"the middleware\"](../structure/middleware.md) guide to learn more about how to implement middleware." +msgstr "" + +#. type: Plain text +#: en/runtime/routing.md +msgid "This is especially useful when grouping routes:" +msgstr "" + +#. type: Fenced code block (php) +#: en/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(FormatDataResponseAsJson::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(FormatDataResponseAsJson::class)\n" +" ->name('api/user/profile'),\n" +" )\n" +"];\n" +msgstr "" + +#. type: Plain text +#: en/runtime/routing.md +msgid "Router executes `ApiDataWrapper` before handling any URL starting with `/api`." +msgstr "" + +#. type: Plain text +#: en/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 +#: en/runtime/routing.md +msgid "You can set a default value for a route parameter. For example:" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/routing.md +#, no-wrap +msgid "" +"action([SiteController::class, 'user'])\n" +" ->name('site/user')\n" +" ->defaults(['id' => '42'])\n" +"];\n" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/runtime/routing.md +msgid "In cause URL should be valid for a single host, you can specify it with `host()`." +msgstr "" + +#. type: Title ## +#: en/runtime/routing.md +#, no-wrap +msgid "Routing " +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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 ## +#: en/runtime/routing.md +#, no-wrap +msgid "Generating URLs " +msgstr "" + +#. type: Plain text +#: en/runtime/routing.md +msgid "To generate URL based on a route, a route should have a name:" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/routing.md +#, no-wrap +msgid "" +"name('test/index'),\n" +" Route::post('/test/submit/{id}', [TestController::class, 'submit'])\n" +" ->name('test/submit')\n" +"];\n" +msgstr "" + +#. type: Plain text +#: en/runtime/routing.md +msgid "The generation looks like the following:" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/routing.md +#, no-wrap +msgid "" +"generate('test/submit', ['id' => '42']);\n" +" // ...\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/runtime/routing.md +msgid "Then we use `generate()` method to get actual URL. It accepts a route name and an array of named query parameters. The code will return \"/test/submit/42.\" If you need absolute URL, use `generateAbsolute()` instead." +msgstr "" + +#. type: Title ## +#: en/runtime/routing.md +#, no-wrap +msgid "Route patterns " +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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 ### +#: en/runtime/routing.md +#, no-wrap +msgid "Named Parameters " +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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 +#: en/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 +#: en/runtime/routing.md +msgid "On a route match router fills the associated request attributes 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 +#: en/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. ' +#: en/runtime/routing.md +msgid "`'posts/{year:\\d{4}}/{category}`" +msgstr "" + +#. type: Bullet: '2. ' +#: en/runtime/routing.md +msgid "`'posts'`" +msgstr "" + +#. type: Bullet: '3. ' +#: en/runtime/routing.md +msgid "`'post/{id:\\d+}'`" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/routing.md +msgid "`/posts` match the second pattern;" +msgstr "" + +#. type: Bullet: '- ' +#: en/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: '- ' +#: en/runtime/routing.md +msgid "`/post/100` match a third pattern. The `id` parameter value is 100;" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/routing.md +msgid "`/posts/php` doesn't match." +msgstr "" + +#. type: Plain text +#: en/runtime/routing.md +msgid "When generating URLs, you should use the following parameters:" +msgstr "" + +#. type: Fenced code block (php) +#: en/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 ### +#: en/runtime/routing.md +#, no-wrap +msgid "Optional parts " +msgstr "" + +#. type: Plain text +#: en/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) +#: en/runtime/routing.md +#, no-wrap +msgid "" +"use \\Yiisoft\\Router\\Route;\n" +"\n" +"Route::get('/posts[/{id}]')->defaults(['id' => '1']);\n" +msgstr "" + +#. type: Plain text +#: en/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/guide/po/es/runtime_sessions.md.po b/_translations/guide/po/es/runtime_sessions.md.po new file mode 100644 index 00000000..d601ed2e --- /dev/null +++ b/_translations/guide/po/es/runtime_sessions.md.po @@ -0,0 +1,251 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title # +#: en/runtime/sessions.md +#, no-wrap +msgid "Sessions" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/runtime/sessions.md +msgid "To add it to your application, use composer:" +msgstr "" + +#. type: Fenced code block (shell) +#: en/runtime/sessions.md +#, no-wrap +msgid "composer require yiisoft/session\n" +msgstr "" + +#. type: Title ## +#: en/runtime/sessions.md +#, no-wrap +msgid "Configuring middleware" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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) +#: en/runtime/sessions.md +#, no-wrap +msgid "" +"middleware(SessionMiddleware::class)\n" +" ->routes(\n" +" // ...\n" +" )\n" +"];\n" +msgstr "" + +#. type: Plain text +#: en/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) +#: en/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" +" CsrfMiddleware::class,\n" +" SessionMiddleware::class, // <-- add this\n" +" ErrorCatcher::class,\n" +" ]\n" +" );\n" +" }),\n" +" ],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Title ## +#: en/runtime/sessions.md +#, no-wrap +msgid "Opening and closing session" +msgstr "" + +#. type: Fenced code block (php) +#: en/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 +#: en/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 +#: en/runtime/sessions.md +msgid "There are two more ways to close a session:" +msgstr "" + +#. type: Fenced code block (php) +#: en/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 ## +#: en/runtime/sessions.md +#, no-wrap +msgid "Working with session data" +msgstr "" + +#. type: Plain text +#: en/runtime/sessions.md +msgid "Usually you will use the following methods to work with session data:" +msgstr "" + +#. type: Fenced code block (php) +#: en/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 ## +#: en/runtime/sessions.md +#, no-wrap +msgid "Flash messages" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/runtime/sessions.md +msgid "`FlashInteface` usage is the following:" +msgstr "" + +#. type: Fenced code block (php) +#: en/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 ## +#: en/runtime/sessions.md +#, no-wrap +msgid "Custom session storage" +msgstr "" + +#. type: Plain text +#: en/runtime/sessions.md +msgid "When using `Yiisoft\\Session\\Session`, you can use your own storage implementation:" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/sessions.md +#, no-wrap +msgid "" +"$handler = new MySessionHandler();\n" +"$session = new \\Yiisoft\\Session\\Session([], $handler);\n" +msgstr "" + +#. type: Plain text +#: en/runtime/sessions.md +msgid "Custom storage must implement `\\SessionHandlerInterface`." +msgstr "" diff --git a/_translations/guide/po/es/security_authentication.md.po b/_translations/guide/po/es/security_authentication.md.po new file mode 100644 index 00000000..cd14aa04 --- /dev/null +++ b/_translations/guide/po/es/security_authentication.md.po @@ -0,0 +1,312 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" +"PO-Revision-Date: 2025-09-04 11:19+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title # +#: ../../guide/en/security/authentication.md +#, no-wrap +msgid "Authentication" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/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: '* ' +#: ../../guide/en/security/authentication.md +msgid "Configure the `Yiisoft\\Yii\\Web\\User\\User` service;" +msgstr "" + +#. type: Bullet: '* ' +#: ../../guide/en/security/authentication.md +msgid "Create a class implementing the `\\Yiisoft\\Auth\\IdentityInterface` interface;" +msgstr "" + +#. type: Bullet: '* ' +#: ../../guide/en/security/authentication.md +msgid "Create a class implementing the `\\Yiisoft\\Auth\\IdentityRepositoryInterface` interface;" +msgstr "" + +#. type: Title ## +#: ../../guide/en/security/authentication.md +#, no-wrap +msgid "Configuring `Yiisoft\\Yii\\Web\\User\\User` " +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authentication.md +msgid "The `Yiisoft\\Yii\\Web\\User\\User` 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) +#: ../../guide/en/security/authentication.md +#, no-wrap +msgid "" +"use Yiisoft\\Session\\Session;\n" +"use Yiisoft\\Session\\SessionInterface;\n" +"use Yiisoft\\Auth\\IdentityRepositoryInterface;\n" +"use Psr\\Container\\ContainerInterface;\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" +" \n" +" \n" +" // User:\n" +" IdentityRepositoryInterface::class => static function (ContainerInterface $container) {\n" +" // instead of a Cycle-based repository, you can use any implementation\n" +" return $container->get(\\Cycle\\ORM\\ORMInterface::class)->getRepository(\\App\\Entity\\User::class);\n" +" },\n" +"];\n" +msgstr "" + +#. type: Title ## +#: ../../guide/en/security/authentication.md +#, no-wrap +msgid "Implementing`\\Yiisoft\\Auth\\IdentityInterface` " +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authentication.md +msgid "The identity class must implement the `\\Yiisoft\\Auth\\IdentityInterface` which has a single method:" +msgstr "" + +#. type: Bullet: '* ' +#: ../../guide/en/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 +#: ../../guide/en/security/authentication.md +msgid "In the following example, an identity class is implemented as a pure PHP object." +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/security/authentication.md +#, no-wrap +msgid "" +"id;\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../../guide/en/security/authentication.md +#, no-wrap +msgid "Implementing`\\Yiisoft\\Auth\\IdentityRepositoryInterface` " +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authentication.md +msgid "The identity repository class must implement the `\\Yiisoft\\Auth\\IdentityRepositoryInterface` which has the following methods:" +msgstr "" + +#. type: Bullet: '* ' +#: ../../guide/en/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: '* ' +#: ../../guide/en/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 +#: ../../guide/en/security/authentication.md +msgid "A dummy implementation may look like the following:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/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 ## +#: ../../guide/en/security/authentication.md +#, no-wrap +msgid "Using `\\Yiisoft\\User\\User` " +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authentication.md +msgid "You can use `\\Yiisoft\\User\\User` 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) +#: ../../guide/en/security/authentication.md +#, no-wrap +msgid "" +"use \\Psr\\Http\\Message\\ServerRequestInterface;\n" +"use \\Yiisoft\\User\\User;\n" +"\n" +"final readonly class SiteController\n" +"{\n" +" public function actionIndex(ServerRequestInterface $request, User $user)\n" +" { \n" +" if ($user->isGuest()) {\n" +" // user is guest\n" +" } else {\n" +" $identity = $user->getIdentity();\n" +" // do something based on identity\n" +" } \n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authentication.md +msgid "`isGuest()` determines if user is logged in or not. `getIdentity()` returns an instance of identity." +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authentication.md +msgid "To log in a user, you may use the following code:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/security/authentication.md +#, no-wrap +msgid "" +"$identity = $identityRepository->findByEmail($email);\n" +"\n" +"/* @var $user \\Yiisoft\\User\\User */\n" +"$user->login($identity);\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/security/authentication.md +msgid "To log out a user, call" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/security/authentication.md +#, no-wrap +msgid "" +"/* @var $user \\Yiisoft\\User\\User */\n" +"$user->logout();\n" +msgstr "" + +#. type: Title ## +#: ../../guide/en/security/authentication.md +#, no-wrap +msgid "Authentication Events " +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authentication.md +msgid "The user service raises a few events during the login and logout processes." +msgstr "" + +#. type: Bullet: '* ' +#: ../../guide/en/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: '* ' +#: ../../guide/en/security/authentication.md +msgid "`\\Yiisoft\\User\\Event\\AfterLogin`: raised after a successful login." +msgstr "" + +#. type: Bullet: '* ' +#: ../../guide/en/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: '* ' +#: ../../guide/en/security/authentication.md +msgid "`\\Yiisoft\\User\\Event\\AfterLogout`: raised after a successful logout." +msgstr "" + +#. type: Plain text +#: ../../guide/en/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/guide/po/es/security_authorization.md.po b/_translations/guide/po/es/security_authorization.md.po new file mode 100644 index 00000000..c94a0bc8 --- /dev/null +++ b/_translations/guide/po/es/security_authorization.md.po @@ -0,0 +1,679 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" +"PO-Revision-Date: 2025-09-04 11:19+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title # +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "Authorization" +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authorization.md +msgid "Authorization is the process of verifying that a user has enough permission to do something." +msgstr "" + +#. type: Title ## +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "Checking for permission " +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authorization.md +msgid "You can check if a user has certain permissions by using `\\Yiisoft\\User\\User` service:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "" +"namespace App\\Blog\\Post;\n" +"\n" +"use Yiisoft\\Router\\CurrentRoute;\n" +"use Yiisoft\\User\\User;\n" +"\n" +"final readonly class PostController\n" +"{\n" +" public function actionEdit(CurrentRoute $route, User $user, PostRepository $postRepository)\n" +" {\n" +" $postId = $route->getArgument('id');\n" +" if ($postId === null) {\n" +" // respond with 404 \n" +" }\n" +" \n" +" $post = $postRepository->findByPK($postId);\n" +" if ($post === null) {\n" +" // respond with 404 \n" +" }\n" +"\n" +" if (!$this->canEditPost($user, $post)) {\n" +" // respond with 403 \n" +" }\n" +" \n" +" // continue with editing a post\n" +" }\n" +" \n" +" private function canEditPost(User $user, Post $post): bool\n" +" {\n" +" return $post->getAuthorId() === $user->getId() || $user->can('updatePost'); \n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authorization.md +msgid "Behind the scenes, `Yiisoft\\Yii\\Web\\User\\User::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 ## +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "Role-based access control (RBAC) " +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/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 +#: ../../guide/en/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 +#: ../../guide/en/security/authorization.md +msgid "To ease description next, there are some basic RBAC concepts first." +msgstr "" + +#. type: Title ### +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "Basic concepts " +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/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 +#: ../../guide/en/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 ### +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "Configuring RBAC " +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authorization.md +msgid "RBAC is available via `yiisoft/rbac` package, so you need to require it:" +msgstr "" + +#. type: Fenced code block +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "composer require yiisoft/rbac\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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) +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "" +"use \\Psr\\Container\\ContainerInterface;\n" +"use Yiisoft\\Rbac\\Manager\\PhpManager;\n" +"use Yiisoft\\Rbac\\RuleFactory\\ClassNameRuleFactory;\n" +"\n" +"return [\n" +" \\Yiisoft\\Access\\AccessCheckerInterface::class => static function (ContainerInterface $container) {\n" +" $aliases = $container->get(\\Yiisoft\\Aliases\\Aliases::class);\n" +" return new PhpManager(new ClassNameRuleFactory(), $aliases->get('@rbac'));\n" +" }\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authorization.md +msgid "`\\Yiisoft\\Rbac\\Manager\\PhpManager` uses PHP script files to store authorization data. The files are under `@rbac` alias. 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 ### +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "Building authorization data " +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authorization.md +msgid "Building authorization data is all about the following tasks:" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/security/authorization.md +msgid "defining roles and permissions;" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/security/authorization.md +msgid "establishing relations between roles and permissions;" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/security/authorization.md +msgid "defining rules;" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/security/authorization.md +msgid "associating rules with roles and permissions;" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/security/authorization.md +msgid "assigning roles to users." +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/security/authorization.md +msgid "Either way, in the end, you'll get the following RBAC hierarchy:" +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authorization.md +msgid "![Simple RBAC hierarchy](img/rbac-hierarchy-1.svg \"Simple RBAC hierarchy\")" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 ### +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "Using console command" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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) +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "" +"manager;\n" +"\n" +" $auth->removeAll(); \n" +" \n" +" $createPost = (new Permission('createPost'))->withDescription('Create a post'); \n" +" $auth->add($createPost);\n" +"\n" +" $updatePost = (new Permission('updatePost'))->withDescription('Update post');\n" +" $auth->add($updatePost);\n" +"\n" +" // add the \"author\" role and give this role the \"createPost\" permission\n" +" $author = new Role('author');\n" +" $auth->add($author);\n" +" $auth->addChild($author, $createPost);\n" +"\n" +" // add the \"admin\" role and give this role the \"updatePost\" permission\n" +" // as well as the permissions of the \"author\" role\n" +" $admin = new Role('admin');\n" +" $auth->add($admin);\n" +" $auth->addChild($admin, $updatePost);\n" +" $auth->addChild($admin, $author);\n" +"\n" +" // Assign roles to users. 1 and 2 are IDs returned by IdentityInterface::getId()\n" +" // usually implemented in your User model.\n" +" $auth->assign($author, 2);\n" +" $auth->assign($admin, 1);\n" +" \n" +" return ExitCode::OK;\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authorization.md +msgid "You can execute the command above from the console the following way:" +msgstr "" + +#. type: Fenced code block +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "./yii rbac:init\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 #### +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "Using migrations" +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "**TODO**: finish it when migrations are implemented.\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/security/authorization.md +msgid "Create new migration using `./yii migrate:create init_rbac` then implement creating a hierarchy:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "" +"removeAll(); \n" +" \n" +" $createPost = (new Permission('createPost'))->withDescription('Create a post'); \n" +" $auth->add($createPost);\n" +"\n" +" $updatePost = (new Permission('updatePost'))->withDescription('Update post');\n" +" $auth->add($updatePost);\n" +"\n" +" // add the \"author\" role and give this role the \"createPost\" permission\n" +" $author = new Role('author');\n" +" $auth->add($author);\n" +" $auth->addChild($author, $createPost);\n" +"\n" +" // add the \"admin\" role and give this role the \"updatePost\" permission\n" +" // as well as the permissions of the \"author\" role\n" +" $admin = new Role('admin');\n" +" $auth->add($admin);\n" +" $auth->addChild($admin, $updatePost);\n" +" $auth->addChild($admin, $author);\n" +"\n" +" // Assign roles to users. 1 and 2 are IDs returned by IdentityInterface::getId()\n" +" // usually implemented in your User model.\n" +" $auth->assign($author, 2);\n" +" $auth->assign($admin, 1);\n" +" }\n" +" \n" +" public function down()\n" +" {\n" +" $auth = /* obtain auth */;\n" +"\n" +" $auth->removeAll();\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/security/authorization.md +msgid "You could apply migration by using `./yii migrate`." +msgstr "" + +#. type: Title ## +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "Assigning roles to users" +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "TODO: update when signup implemented in demo / template.\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/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) +#: ../../guide/en/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" +" $auth = \\Yii::$app->authManager;\n" +" $authorRole = $auth->getRole('author');\n" +" $auth->assign($authorRole, $user->getId());\n" +"\n" +" return $user;\n" +" }\n" +"\n" +" return null;\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 `authManager`." +msgstr "" + +#. type: Title ### +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "Using rules " +msgstr "" + +#. type: Plain text +#: ../../guide/en/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) +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "" +"namespace App\\User\\Rbac;\n" +"\n" +"use Yiisoft\\Rbac\\Item;\n" +"use \\Yiisoft\\Rbac\\Rule;\n" +"\n" +"/**\n" +" * Checks if the authorID matches user passed via params.\n" +" */\n" +"final readonly class AuthorRule extends Rule\n" +"{\n" +" private const NAME = 'isAuthor';\n" +"\n" +" public function __construct() {\n" +" parent::__construct(self::NAME);\n" +" }\n" +"\n" +" public function execute(string $userId, Item $item, array $parameters = []): bool\n" +" {\n" +" return isset($params['post']) ? $params['post']->getAuthorId() == $userId : false;\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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) +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "" +"/** @var \\Yiisoft\\Rbac\\ManagerInterface $auth */\n" +"\n" +"// add the rule\n" +"$rule = new AuthorRule();\n" +"$auth->add($rule);\n" +"\n" +"// add the \"updateOwnPost\" permission and associate the rule with it.\n" +"$updateOwnPost = (new \\Yiisoft\\Rbac\\Permission('updateOwnPost'))\n" +" ->withDescription('Update own post')\n" +" ->withRuleName($rule->getName());\n" +"$auth->add($updateOwnPost);\n" +"\n" +"// \"updateOwnPost\" will be used from \"updatePost\"\n" +"$auth->addChild($updateOwnPost, $updatePost);\n" +"\n" +"// allow \"author\" to update their own posts\n" +"$auth->addChild($author, $updateOwnPost);\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authorization.md +msgid "Now you've got the following hierarchy:" +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authorization.md +msgid "![RBAC hierarchy with a rule](img/rbac-hierarchy-2.svg \"RBAC hierarchy with a rule\")" +msgstr "" + +#. type: Title ### +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "Access check " +msgstr "" + +#. type: Plain text +#: ../../guide/en/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) +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "" +"namespace App\\Blog\\Post;\n" +"\n" +"use Psr\\Http\\Message\\ServerRequestInterface;\n" +"use Yiisoft\\User\\User;\n" +"\n" +"final readonly class PostController\n" +"{\n" +" public function actionEdit(ServerRequestInterface $request, User $user, PostRepository $postRepository)\n" +" {\n" +" $postId = $request->getAttribute('id');\n" +" if ($postId === null) {\n" +" // respond with 404 \n" +" }\n" +" \n" +" $post = $postRepository->findByPK($postId);\n" +" if ($post === null) {\n" +" // respond with 404 \n" +" }\n" +"\n" +" if (!$this->canEditPost($user, $post)) {\n" +" // respond with 403 \n" +" }\n" +" \n" +" // continue with editing a post\n" +" }\n" +" \n" +" private function canEditPost(User $user, Post $post): bool\n" +" {\n" +" return $user->can('updatePost', ['post' => $post]); \n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/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 +#: ../../guide/en/security/authorization.md +msgid "![Access check](img/rbac-access-check-1.svg \"Access check\")" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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) +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "" +"if ($user->can('updatePost', ['post' => $post])) {\n" +" // update post\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authorization.md +msgid "Here is what happens if the current user is John:" +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authorization.md +msgid "![Access check](img/rbac-access-check-2.svg \"Access check\")" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/security/authorization.md +msgid "In the case of Jane, it's a bit simpler since she is an admin:" +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authorization.md +msgid "![Access check](img/rbac-access-check-3.svg \"Access check\")" +msgstr "" + +#. type: Title ## +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "Implementing your own access checker" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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) +#: ../../guide/en/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/guide/po/es/security_best-practices.md.po b/_translations/guide/po/es/security_best-practices.md.po new file mode 100644 index 00000000..c79ca7de --- /dev/null +++ b/_translations/guide/po/es/security_best-practices.md.po @@ -0,0 +1,492 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-04 08:00+0500\n" +"PO-Revision-Date: 2025-09-04 08:00+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title ## +#: en/concept/autoloading.md en/security/best-practices.md +#, no-wrap +msgid "References" +msgstr "Referencias" + +#. type: Title # +#: en/security/best-practices.md +#, no-wrap +msgid "Security best practices" +msgstr "" + +#. type: Plain text +#: en/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 ## +#: en/security/best-practices.md +#, no-wrap +msgid "Basic principles" +msgstr "" + +#. type: Plain text +#: en/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. ' +#: en/security/best-practices.md +msgid "Filter input." +msgstr "" + +#. type: Bullet: '2. ' +#: en/security/best-practices.md +msgid "Escape output." +msgstr "" + +#. type: Title ### +#: en/security/best-practices.md +#, no-wrap +msgid "Filter input" +msgstr "" + +#. type: Plain text +#: en/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) +#: en/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 +#: en/security/best-practices.md +msgid "In Yii, most probably you'll use [form validation](../input/validation.md) to do similar checks." +msgstr "" + +#. type: Plain text +#: en/security/best-practices.md +msgid "Further reading on the topic:" +msgstr "" + +#. type: Bullet: '- ' +#: en/security/best-practices.md +msgid "" +msgstr "" + +#. type: Bullet: '- ' +#: en/security/best-practices.md +msgid "" +msgstr "" + +#. type: Title ### +#: en/security/best-practices.md +#, no-wrap +msgid "Escape output" +msgstr "" + +#. type: Plain text +#: en/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: '- ' +#: en/security/best-practices.md +msgid "" +msgstr "" + +#. type: Bullet: '- ' +#: en/security/best-practices.md +msgid "" +msgstr "" + +#. type: Bullet: '- ' +#: en/security/best-practices.md +msgid "" +msgstr "" + +#. type: Title ## +#: en/security/best-practices.md +#, no-wrap +msgid "Avoiding SQL injections" +msgstr "" + +#. type: Plain text +#: en/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) +#: en/security/best-practices.md +#, no-wrap +msgid "" +"$username = $_GET['username'];\n" +"$sql = \"SELECT * FROM user WHERE username = '$username'\";\n" +msgstr "" + +#. type: Plain text +#: en/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) +#: en/security/best-practices.md +#, no-wrap +msgid "SELECT * FROM user WHERE username = ''; DROP TABLE user; --'\n" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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 +#: en/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) +#: en/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: '- ' +#: en/security/best-practices.md +msgid "" +msgstr "" + +#. type: Title ## +#: en/security/best-practices.md +#, no-wrap +msgid "Avoiding XSS" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/security/best-practices.md +msgid "Avoiding XSS is quite easy in Yii. There are two cases:" +msgstr "" + +#. type: Bullet: '1. ' +#: en/security/best-practices.md +msgid "You want to output data as plain text." +msgstr "" + +#. type: Bullet: '2. ' +#: en/security/best-practices.md +msgid "You want to output data as HTML." +msgstr "" + +#. type: Plain text +#: en/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) +#: en/security/best-practices.md +#, no-wrap +msgid "\n" +msgstr "" + +#. type: Plain text +#: en/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 ## +#: en/security/best-practices.md +#, no-wrap +msgid "Avoiding CSRF" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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 +#: en/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 +#: en/security/best-practices.md +msgid "For this reason, Yii applies extra mechanisms to protect against CSRF attacks." +msgstr "" + +#. type: Plain text +#: en/security/best-practices.md +msgid "To avoid CSRF, you should always:" +msgstr "" + +#. type: Bullet: '1. ' +#: en/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. ' +#: en/security/best-practices.md +msgid "Keep Yii CSRF protection enabled." +msgstr "" + +#. type: Plain text +#: en/security/best-practices.md +msgid "Yii has CSRF protection as `Yiisoft\\Yii\\Web\\Middleware\\Csrf` middleware. Make sure it's in your application middleware stack." +msgstr "" + +#. type: Bullet: '- ' +#: en/security/best-practices.md +msgid "" +msgstr "" + +#. type: Bullet: '- ' +#: en/security/best-practices.md +msgid "" +msgstr "" + +#. type: Title ## +#: en/security/best-practices.md +#, no-wrap +msgid "Avoiding file exposure" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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 ## +#: en/security/best-practices.md +#, no-wrap +msgid "Avoiding debug info and tools in production" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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 +#: en/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: '- ' +#: en/security/best-practices.md +msgid "" +msgstr "" + +#. type: Bullet: '- ' +#: en/security/best-practices.md +msgid "" +msgstr "" + +#. type: Title ## +#: en/security/best-practices.md +#, no-wrap +msgid "Using secure connection over TLS" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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 ## +#: en/security/best-practices.md +#, no-wrap +msgid "Secure server configuration" +msgstr "" + +#. type: Plain text +#: en/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 ### +#: en/security/best-practices.md +#, no-wrap +msgid "Avoiding `Host`-header attacks" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/security/best-practices.md +msgid "For more information about the server configuration, please refer to the documentation of your webserver:" +msgstr "" + +#. type: Bullet: '- ' +#: en/security/best-practices.md +msgid "Apache 2: " +msgstr "" + +#. type: Bullet: '- ' +#: en/security/best-practices.md +msgid "Nginx: " +msgstr "" + +#. type: Title ### +#: en/security/best-practices.md +#, no-wrap +msgid "Configuring SSL peer validation" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/security/best-practices.md +#, no-wrap +msgid "cURL error 60: SSL certificate problem: unable to get local issuer certificate\n" +msgstr "" + +#. type: Plain text +#: en/security/best-practices.md +msgid "or" +msgstr "" + +#. type: Fenced code block +#: en/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 +#: en/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. ' +#: en/security/best-practices.md +msgid "Download [https://curl.haxx.se/ca/cacert.pem](https://curl.haxx.se/ca/cacert.pem)." +msgstr "" + +#. type: Bullet: '2. ' +#: en/security/best-practices.md +msgid "Add the following to your php.ini:" +msgstr "" + +#. type: Fenced code block +#: en/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 +#: en/security/best-practices.md +msgid "Note that you should keep the file up to date." +msgstr "" + +#. type: Bullet: '- ' +#: en/security/best-practices.md +msgid "[OWASP top 10](https://owasp.org/Top10/)" +msgstr "" + +#. type: Bullet: '- ' +#: en/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: '- ' +#: en/security/best-practices.md +msgid "[PHP manual: security](https://www.php.net/manual/en/security.php)" +msgstr "" + +#. type: Bullet: '- ' +#: en/security/best-practices.md +msgid "[Information security at STackExchange](https://security.stackexchange.com/)" +msgstr "" diff --git a/_translations/guide/po/es/security_cryptography.md.po b/_translations/guide/po/es/security_cryptography.md.po new file mode 100644 index 00000000..2d5eff67 --- /dev/null +++ b/_translations/guide/po/es/security_cryptography.md.po @@ -0,0 +1,233 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\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/guide/po/es/security_overview.md.po b/_translations/guide/po/es/security_overview.md.po new file mode 100644 index 00000000..f0c5eee1 --- /dev/null +++ b/_translations/guide/po/es/security_overview.md.po @@ -0,0 +1,68 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title # +#: en/security/overview.md +#, no-wrap +msgid "Security" +msgstr "" + +#. 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/guide/po/es/security_passwords.md.po b/_translations/guide/po/es/security_passwords.md.po new file mode 100644 index 00000000..40ba2fd9 --- /dev/null +++ b/_translations/guide/po/es/security_passwords.md.po @@ -0,0 +1,78 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\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/guide/po/es/security_trusted-request.md.po b/_translations/guide/po/es/security_trusted-request.md.po new file mode 100644 index 00000000..fb79cc48 --- /dev/null +++ b/_translations/guide/po/es/security_trusted-request.md.po @@ -0,0 +1,77 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\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/guide/po/es/start_creating-project.md.po b/_translations/guide/po/es/start_creating-project.md.po new file mode 100644 index 00000000..aa1fe6de --- /dev/null +++ b/_translations/guide/po/es/start_creating-project.md.po @@ -0,0 +1,128 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title # +#: en/start/creating-project.md +#, no-wrap +msgid "Creating a project" +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/start/creating-project.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> If you want to use another web server,\n" +"> see [\"Configuring web servers\"](../../../cookbook/en/configuring-webservers/general.md).\n" +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/start/creating-project.md +msgid "You can create a new project from a template using the [Composer](https://getcomposer.org) package manager:" +msgstr "" + +#. type: Fenced code block +#: en/start/creating-project.md +#, no-wrap +msgid "composer create-project yiisoft/app your_project\n" +msgstr "" + +#. type: Plain text +#: en/start/creating-project.md +msgid "Docker users can run the following command:" +msgstr "" + +#. type: Fenced code block (sh) +#: en/start/creating-project.md +#, no-wrap +msgid "docker run --rm -it -v \"$(pwd):/app\" composer/composer create-project yiisoft/app your_project\n" +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/start/creating-project.md +msgid "Go into the newly created directory and run:" +msgstr "" + +#. type: Fenced code block (sh) +#: en/start/creating-project.md +#, no-wrap +msgid "APP_ENV=dev ./yii serve --port=80\n" +msgstr "" + +#. type: Plain text +#: en/start/creating-project.md +msgid "For Docker users, run:" +msgstr "" + +#. type: Fenced code block +#: en/start/creating-project.md +#, no-wrap +msgid "make up\n" +msgstr "" + +#. type: Plain text +#: en/start/creating-project.md +msgid "Open your browser to the URL `http://localhost/`." +msgstr "" + +#. type: Plain text +#: en/start/creating-project.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> The HTTP server listens on port 80. If that port is already in use, specify the port via `--port` or, in case of Docker,\n" +"> `DEV_PORT` in the `docker/.env` file.\n" +msgstr "" + +#. type: Plain text +#: en/start/creating-project.md +msgid "![Successful Installation of Yii](img/app-installed.png)" +msgstr "" + +#. type: Plain text +#: en/start/creating-project.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> [← What do you need to know?](prerequisites.md) | \n" +"> [Running applications →](workflow.md)\n" +msgstr "" diff --git a/_translations/guide/po/es/start_databases.md.po b/_translations/guide/po/es/start_databases.md.po new file mode 100644 index 00000000..7093fc15 --- /dev/null +++ b/_translations/guide/po/es/start_databases.md.po @@ -0,0 +1,123 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title # +#: en/start/databases.md +#, no-wrap +msgid "Working with databases" +msgstr "" + +#. type: Plain text +#: en/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: '- ' +#: en/start/databases.md +msgid "[Yii DB](https://github.com/yiisoft/db)" +msgstr "" + +#. type: Bullet: '- ' +#: en/start/databases.md +msgid "[Yii Active Record](https://github.com/yiisoft/active-record)" +msgstr "" + +#. type: Bullet: '- ' +#: en/start/databases.md +msgid "[Cycle](https://github.com/cycle) via [Yii Cycle package](https://github.com/yiisoft/yii-cycle)" +msgstr "" + +#. type: Bullet: '- ' +#: en/start/databases.md +msgid "[Doctrine](https://www.doctrine-project.org/) via [Yii Doctrine package](https://github.com/stargazer-team/yii-doctrine)" +msgstr "" + +#. type: Bullet: '- ' +#: en/start/databases.md +msgid "[PDO](https://www.php.net/manual/en/book.pdo.php)" +msgstr "" + +#. type: Plain text +#: en/start/databases.md +msgid "For non-relational ones, there are usually official libraries available:" +msgstr "" + +#. type: Bullet: '- ' +#: en/start/databases.md +msgid "[ElasticSearch](https://github.com/elastic/elasticsearch-php)" +msgstr "" + +#. type: Bullet: '- ' +#: en/start/databases.md +msgid "[Redis](https://redis.io/docs/clients/#php)" +msgstr "" + +#. type: Bullet: '- ' +#: en/start/databases.md +msgid "..." +msgstr "" + +#. type: Plain text +#: en/start/databases.md +msgid "In this guide, we will focus on working with relational databases using Yii DB." +msgstr "" + +#. type: Title ## +#: en/start/databases.md +#, no-wrap +msgid "Configuring connection" +msgstr "" + +#. type: Title ## +#: en/start/databases.md +#, no-wrap +msgid "Creating and applying migration" +msgstr "" + +#. type: Title ## +#: en/start/databases.md +#, no-wrap +msgid "Inserting" +msgstr "" + +#. type: Title ## +#: en/start/databases.md +#, no-wrap +msgid "Selecting" +msgstr "" + +#. type: Title ## +#: en/start/databases.md +#, no-wrap +msgid "Using data package" +msgstr "" + +#. type: Title ### +#: en/start/databases.md +#, no-wrap +msgid "Pagination" +msgstr "" + +#. type: Plain text +#: en/start/databases.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> [← Working with forms](forms.md) |\n" +"> [Generating code with Gii →](gii.md)\n" +msgstr "" diff --git a/_translations/guide/po/es/start_forms.md.po b/_translations/guide/po/es/start_forms.md.po new file mode 100644 index 00000000..10550d50 --- /dev/null +++ b/_translations/guide/po/es/start_forms.md.po @@ -0,0 +1,345 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title # +#: en/start/forms.md +#, no-wrap +msgid "Working with forms" +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/start/forms.md +msgid "Through this tutorial, you will learn how to:" +msgstr "" + +#. type: Bullet: '* ' +#: en/start/forms.md +msgid "Create a form model to represent the data entered by a user through a form." +msgstr "" + +#. type: Bullet: '* ' +#: en/start/forms.md +msgid "Declare rules to validate the data entered." +msgstr "" + +#. type: Bullet: '* ' +#: en/start/forms.md +msgid "Build an HTML form in a view." +msgstr "" + +#. type: Title ## +#: en/start/forms.md +#, no-wrap +msgid "Installing form package" +msgstr "" + +#. type: Plain text +#: en/start/forms.md +msgid "To install form package, issue the following command in your application directory:" +msgstr "" + +#. type: Fenced code block +#: en/start/forms.md +#, no-wrap +msgid "composer require yiisoft/form-model\n" +msgstr "" + +#. type: Plain text +#: en/start/forms.md +msgid "For Docker that would be:" +msgstr "" + +#. type: Fenced code block +#: en/start/forms.md +#, no-wrap +msgid "make composer require yiisoft/form-model\n" +msgstr "" + +#. type: Title ## +#: en/start/forms.md +#, no-wrap +msgid "Creating a form " +msgstr "" + +#. type: Plain text +#: en/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/App/Controller/Echo/Form.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: en/start/forms.md +#, no-wrap +msgid "" +" " +msgstr "" + +#. type: Plain text +#: en/start/forms.md +msgid "Now that you have a form, use it in your action from \"[Saying Hello](hello.md)\"." +msgstr "" + +#. type: Plain text +#: en/start/forms.md +msgid "Here's what you end up with in `/src/Controller/Echo/Action.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: en/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 "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/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 "" + +#. type: Fenced code block (php) +#: en/start/forms.md +#, no-wrap +msgid "" +"routes(\n" +" Route::get('/')\n" +" ->action(\\App\\Controller\\HomePage\\Action::class)\n" +" ->name('home'),\n" +" Route::methods([Method::GET, Method::POST], '/say')\n" +" ->action(\\App\\Controller\\Echo\\Action::class)\n" +" ->name('echo/say'),\n" +" ),\n" +"];\n" +msgstr "" + +#. type: Title ## +#: en/start/forms.md +#, no-wrap +msgid "Adjusting view" +msgstr "" + +#. type: Plain text +#: en/start/forms.md +msgid "To render a form, you need to change your view, `src/Controller/Echo/template.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: en/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 "" + +#. type: Plain text +#: en/start/forms.md +msgid "If the form is valid, you display a message. The rest initializes and renders the form." +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Fenced code block (php) +#: en/start/forms.md +#, no-wrap +msgid "" +"'yiisoft/yii-view-renderer' => [\n" +" 'injections' => [\n" +" Reference::to(CsrfViewInjection::class),\n" +" ],\n" +"],\n" +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/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 "" + +#. type: Title ## +#: en/start/forms.md +#, no-wrap +msgid "Trying it Out " +msgstr "" + +#. type: Plain text +#: en/start/forms.md +msgid "To see how it works, use your browser to access the following URL:" +msgstr "" + +#. type: Fenced code block +#: en/start/forms.md +#, no-wrap +msgid "http://localhost:8080/say\n" +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/start/forms.md +msgid "![Form with a validation error](img/form-error.png)" +msgstr "" + +#. type: Plain text +#: en/start/forms.md +msgid "After you enter a valid message and click the \"submit\" button, the page echoes the data that you entered." +msgstr "" + +#. type: Plain text +#: en/start/forms.md +msgid "![Form with a success message](img/form-success.png)" +msgstr "" + +#. type: Title ## +#: en/start/forms.md en/start/hello.md +#, no-wrap +msgid "Summary " +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/start/forms.md +msgid "In the next section, you will learn how to work with databases, which are needed in nearly every application." +msgstr "" + +#. type: Plain text +#: en/start/forms.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> [← Saying hello](hello.md) |\n" +"> [Working with databases →](databases.md)\n" +msgstr "" diff --git a/_translations/guide/po/es/start_gii.md.po b/_translations/guide/po/es/start_gii.md.po new file mode 100644 index 00000000..68392a6a --- /dev/null +++ b/_translations/guide/po/es/start_gii.md.po @@ -0,0 +1,32 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title # +#: en/start/gii.md +#, no-wrap +msgid "Generating code with Gii" +msgstr "" + +#. type: Plain text +#: en/start/gii.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> [← Working with databases](databases.md) |\n" +"> [Looking ahead →](looking-ahead.md)\n" +msgstr "" diff --git a/_translations/guide/po/es/start_hello.md.po b/_translations/guide/po/es/start_hello.md.po new file mode 100644 index 00000000..e508bbab --- /dev/null +++ b/_translations/guide/po/es/start_hello.md.po @@ -0,0 +1,289 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title ## +#: en/start/forms.md en/start/hello.md +#, no-wrap +msgid "Summary " +msgstr "" + +#. type: Title # +#: en/start/hello.md +#, no-wrap +msgid "Saying hello" +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/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](../structure/views.md) for building the response." +msgstr "" + +#. type: Plain text +#: en/start/hello.md +msgid "Through this tutorial, you will learn three things:" +msgstr "" + +#. type: Bullet: '1. ' +#: en/start/hello.md +msgid "How to create a handler to respond to a request." +msgstr "" + +#. type: Bullet: '2. ' +#: en/start/hello.md +msgid "How to map URL to the handler." +msgstr "" + +#. type: Bullet: '3. ' +#: en/start/hello.md +msgid "How to create a [view](../structure/view.md) to compose the response's content." +msgstr "" + +#. type: Title ## +#: en/start/hello.md +#, no-wrap +msgid "Creating a handler " +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/start/hello.md +msgid "Create `src/Controller/Echo/Action.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: en/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 "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/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 "" + +#. type: Title ## +#: en/start/hello.md +#, no-wrap +msgid "Configuring router" +msgstr "" + +#. type: Plain text +#: en/start/hello.md +msgid "Now, to map your handler to URL, you need to add a route in `config/common/routes.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: en/start/hello.md +#, no-wrap +msgid "" +"routes(\n" +" Route::get('/')\n" +" ->action(\\App\\Controller\\HomePage\\Action::class)\n" +" ->name('home'),\n" +" Route::get('/say[/{message}]')\n" +" ->action(\\App\\Controller\\Echo\\Action::class)\n" +" ->name('echo/say'),\n" +" ),\n" +"];\n" +msgstr "" + +#. type: Plain text +#: en/start/hello.md +msgid "In the above, you map the `/say[/{message}]` pattern to `\\App\\Controller\\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` request attribute. `[]` marks this part of the pattern as optional." +msgstr "" + +#. type: Plain text +#: en/start/hello.md +msgid "You also give a `echo/say` name to this route to be able to generate URLs pointing to it." +msgstr "" + +#. type: Title ## +#: en/start/hello.md +#, no-wrap +msgid "Trying it out " +msgstr "" + +#. type: Plain text +#: en/start/hello.md +msgid "After creating the action and the view open `http://localhost/say/Hello+World` in your browser." +msgstr "" + +#. type: Plain text +#: en/start/hello.md +msgid "This URL displays a page with \"The message is: Hello World\"." +msgstr "" + +#. type: Plain text +#: en/start/hello.md +msgid "If you omit the `message` parameter in the URL, the page displays \"The message is: Hello!\"." +msgstr "" + +#. type: Title ## +#: en/start/hello.md +#, no-wrap +msgid "Creating a View Template " +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/start/hello.md +msgid "For the \"Hello\" task, create a `src/Controller/Echo/template.php` template that prints the `message` parameter received from the action method:" +msgstr "" + +#. type: Fenced code block (php) +#: en/start/hello.md +#, no-wrap +msgid "" +"\n" +"\n" +"

The message is:

\n" +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/start/hello.md +msgid "To use the view, you need to change `src/Controller/Echo/Action.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: en/start/hello.md +#, no-wrap +msgid "" +"viewRenderer->render(__DIR__ . '/template', [\n" +" 'message' => $message,\n" +" ]);\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: en/start/hello.md +msgid "Now open your browser and check it again. You should see the similar text but with a layout applied." +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/start/hello.md +msgid "You've also learned about routing in Yii, which acts as the bridge between user requests and handlers." +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/start/hello.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> [← Running applications](workflow.md) |\n" +"> [Working with forms →](forms.md)\n" +msgstr "" diff --git a/_translations/guide/po/es/start_looking-ahead.md.po b/_translations/guide/po/es/start_looking-ahead.md.po new file mode 100644 index 00000000..da8dc73d --- /dev/null +++ b/_translations/guide/po/es/start_looking-ahead.md.po @@ -0,0 +1,36 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title # +#: en/start/looking-ahead.md +#, no-wrap +msgid "Looking ahead" +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/start/looking-ahead.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> [← Generating code with Gii](gii.md)\n" +msgstr "" diff --git a/_translations/guide/po/es/start_prerequisites.md.po b/_translations/guide/po/es/start_prerequisites.md.po new file mode 100644 index 00000000..c5885145 --- /dev/null +++ b/_translations/guide/po/es/start_prerequisites.md.po @@ -0,0 +1,106 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title ## +#: en/intro/upgrade-from-v2.md en/start/prerequisites.md +#, no-wrap +msgid "Docker" +msgstr "" + +#. type: Title # +#: en/start/prerequisites.md +#, no-wrap +msgid "What do you need to know?" +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Title ## +#: en/start/prerequisites.md +#, no-wrap +msgid "PHP" +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Title ## +#: en/start/prerequisites.md +#, no-wrap +msgid "Object-oriented programming" +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/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 "" + +#. type: Title ## +#: en/start/prerequisites.md +#, no-wrap +msgid "Command line and Composer" +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Title ## +#: en/start/prerequisites.md +#, no-wrap +msgid "HTTP" +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/start/prerequisites.md +msgid "Also, you will benefit from familiarizing yourself with [twelve-factor app](https://12factor.net/) principles." +msgstr "" + +#. type: Plain text +#: en/start/prerequisites.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> [Creating a project →](creating-project.md)\n" +msgstr "" diff --git a/_translations/guide/po/es/start_workflow.md.po b/_translations/guide/po/es/start_workflow.md.po new file mode 100644 index 00000000..af2480c8 --- /dev/null +++ b/_translations/guide/po/es/start_workflow.md.po @@ -0,0 +1,222 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title # +#: en/start/workflow.md +#, no-wrap +msgid "Running applications" +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/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 "" + +#. type: Title ## +#: en/start/workflow.md +#, no-wrap +msgid "Functionality " +msgstr "" + +#. type: Plain text +#: en/start/workflow.md +msgid "The installed application has only the homepage, which displays when you access the URL `http://localhost/`. It shares a common layout that you can reuse on further pages." +msgstr "" + +#. type: Plain text +#: en/start/workflow.md +#, no-wrap +msgid "" +"\n" +msgstr "" + +#. type: Plain text +#: en/start/workflow.md +msgid "In addition to the web application, you can access a console script via `APP_ENV=dev ./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 "" + +#. type: Title ## +#: en/start/workflow.md +#, no-wrap +msgid "Application structure " +msgstr "" + +#. type: Plain text +#: en/start/workflow.md +msgid "The most important directories and files in your application are (assuming the application's root directory is `app`):" +msgstr "" + +#. type: Fenced code block +#: en/start/workflow.md +#, no-wrap +msgid "" +"assets/ Application assets to be published.\n" +"config/ Configuration.\n" +" common/ Configs applied to both console and web.\n" +" di/ DI container configuration.\n" +" aliasess.php Aliases.\n" +" application.php Application configuration.\n" +" bootstrap.php Bootstrap configuration.\n" +" params.php Various parameters used in DI configs.\n" +" routes.php Application routes.\n" +" console/ Configs applied to console.\n" +" commands.php Registered console commands.\n" +" params.php Various parameters used in DI configs.\n" +" web/ Configs applied to web.\n" +" di/ DI container configuration.\n" +" params.php Various parameters used in DI configs.\n" +" environments/ Environment-based configs.\n" +" dev/ Configs applied in dev environment.\n" +" params.php Various parameters used in DI configs.\n" +" prod/ Configs applied in prod environment.\n" +" params.php Various parameters used in DI configs.\n" +" test/ Configs applied in test environment.\n" +" params.php Various parameters used in DI configs. \n" +" configuration.php Defines how to read application configs.\n" +" .merge-plan.php Merge plan to assemble configs according to. Build using `configuration.php`.\n" +"docker/ Docker configuration.\n" +" dev/ Dev environment.\n" +" .env Environment variables.\n" +" compose.yml Services for dev environment.\n" +" prod/ Prod environment.\n" +" .env Environment variables.\n" +" compose.yml Services for prod environment.\n" +" test/ Test environment.\n" +" .env Environment variables.\n" +" compose.yml Services for test environment.\n" +" .env Common environment variables.\n" +" compose.yml Common services.\n" +" Dockerfile Images to use.\n" +"public/ Files publically accessible from the Internet.\n" +" assets/ Published assets.\n" +" index.php Entry script for web.\n" +"runtime/ Files generated during runtime.\n" +"src/ Application source code.\n" +" Command/ Console commands.\n" +" Controller/ Controllers.\n" +" Handler/ Custom handler for 404.\n" +" Layout/ Layouts.\n" +" autoload.php Autoloader.\n" +" Environment.php Environment helper.\n" +"tests/ A set of Codeception tests for the application. \n" +"vendor/ Installed Composer packages.\n" +".gitignore Files and directories to be ignored by Git.\n" +".php-cs-fixer.php PHP Coding Standards Fixer configuration.\n" +"c3.php Codeception code coverage script.\n" +"condeception.yml Codeception configuration.\n" +"composer.json Composer configuration.\n" +"composer.lock Composer lock file.\n" +"Makefile Makefile with shortcut commands.\n" +"psalm.xml Psalm configuration.\n" +"rector.php Rector configuration.\n" +"yii Console application entry point.\n" +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/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 "" + +#. type: Title ## +#: en/start/workflow.md +#, no-wrap +msgid "Request Lifecycle " +msgstr "" + +#. type: Plain text +#: en/start/workflow.md +msgid "The following diagram shows how an application handles a request." +msgstr "" + +#. type: Plain text +#: en/start/workflow.md +msgid "![Request Lifecycle](img/request-lifecycle.svg)" +msgstr "" + +#. type: Bullet: '1. ' +#: en/start/workflow.md +msgid "A user makes a request to the [entry script](../structure/entry-script.md) `public/index.php`." +msgstr "" + +#. type: Bullet: '2. ' +#: en/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 "" + +#. type: Bullet: '3. ' +#: en/start/workflow.md +msgid "Request factory creates a request object based on a raw request that came from a user." +msgstr "" + +#. type: Bullet: '4. ' +#: en/start/workflow.md +msgid "Application passes a request object through a middleware array configured. One of these is typically a router." +msgstr "" + +#. type: Bullet: '5. ' +#: en/start/workflow.md +msgid "The Router finds out what handler to execute based on request and configuration." +msgstr "" + +#. type: Bullet: '6. ' +#: en/start/workflow.md +msgid "The handler may load some data, possibly from a database." +msgstr "" + +#. type: Bullet: '7. ' +#: en/start/workflow.md +msgid "The handler forms a response by using data. Either directly or with the help of the view package." +msgstr "" + +#. type: Bullet: '8. ' +#: en/start/workflow.md +msgid "Emitter receives the response and takes care of sending the response to the user's browser." +msgstr "" + +#. type: Plain text +#: en/start/workflow.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> [← Creating a project](creating-project.md) |\n" +"> [Saying hello →](hello.md)\n" +msgstr "" diff --git a/_translations/guide/po/es/structure_action.md.po b/_translations/guide/po/es/structure_action.md.po new file mode 100644 index 00000000..097485db --- /dev/null +++ b/_translations/guide/po/es/structure_action.md.po @@ -0,0 +1,179 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title # +#: en/structure/action.md +#, no-wrap +msgid "Actions" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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) +#: en/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 +#: en/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) +#: en/structure/action.md +#, no-wrap +msgid "" +"use Yiisoft\\Router\\Route;\n" +"\n" +"Route::get('/')->action([FrontPageAction::class, 'run']),\n" +msgstr "" + +#. type: Plain text +#: en/structure/action.md +msgid "The class itself would be like:" +msgstr "" + +#. type: Fenced code block (php) +#: en/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 run(ServerRequestInterface $request): ResponseInterface\n" +" {\n" +" // build response for a front page \n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: en/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) +#: en/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 +#: en/structure/action.md +msgid "The class itself would look like the following:" +msgstr "" + +#. type: Fenced code block (php) +#: en/structure/action.md +#, no-wrap +msgid "" +"use \\Psr\\Http\\Message\\ServerRequestInterface;\n" +"use \\Psr\\Http\\Message\\ResponseInterface;\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(ServerRequestInterface $request): ResponseInterface\n" +" {\n" +" // render a single post \n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: en/structure/action.md +msgid "We usually call such a class \"controller.\"" +msgstr "" + +#. type: Title ## +#: en/structure/action.md +#, no-wrap +msgid "Autowiring" +msgstr "" + +#. type: Plain text +#: en/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) +#: en/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 +#: en/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/guide/po/es/structure_application.md.po b/_translations/guide/po/es/structure_application.md.po new file mode 100644 index 00000000..1b23eb6e --- /dev/null +++ b/_translations/guide/po/es/structure_application.md.po @@ -0,0 +1,48 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title # +#: en/structure/application.md +#, no-wrap +msgid "Application" +msgstr "" + +#. type: Plain text +#: en/structure/application.md +msgid "The primary purpose of the web application and its runner in Yii 3 is to process requests to get responses." +msgstr "" + +#. type: Plain text +#: en/structure/application.md +msgid "Typically, the runtime consists of:" +msgstr "" + +#. type: Bullet: '1. ' +#: en/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. ' +#: en/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. ' +#: en/structure/application.md +msgid "Shutdown. Fire `ApplicationShutdown` event." +msgstr "" diff --git a/_translations/guide/po/es/structure_domain.md.po b/_translations/guide/po/es/structure_domain.md.po new file mode 100644 index 00000000..e89bde8f --- /dev/null +++ b/_translations/guide/po/es/structure_domain.md.po @@ -0,0 +1,186 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title ## +#: en/concept/autoloading.md en/security/best-practices.md +#: en/structure/domain.md en/tutorial/console-applications.md +#, no-wrap +msgid "References" +msgstr "Referencias" + +#. type: Title # +#: en/structure/domain.md +#, no-wrap +msgid "Domain" +msgstr "" + +#. type: Plain text +#: en/structure/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 +#: en/structure/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 ## +#: en/structure/domain.md +#, no-wrap +msgid "Bounded context" +msgstr "" + +#. type: Plain text +#: en/structure/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 ## +#: en/structure/domain.md +#, no-wrap +msgid "Building blocks" +msgstr "" + +#. type: Plain text +#: en/structure/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: '- ' +#: en/structure/domain.md en/structure/service.md +#, no-wrap +msgid "Entity" +msgstr "" + +#. type: Plain text +#: en/structure/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 ### +#: en/structure/domain.md +#, no-wrap +msgid "Value object" +msgstr "" + +#. type: Plain text +#: en/structure/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 ### +#: en/structure/domain.md +#, no-wrap +msgid "Aggregate" +msgstr "" + +#. type: Plain text +#: en/structure/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 +#: en/structure/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 ### +#: en/structure/domain.md +#, no-wrap +msgid "Domain event" +msgstr "" + +#. type: Plain text +#: en/structure/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 ### +#: en/structure/domain.md +#, no-wrap +msgid "Data transfer object" +msgstr "" + +#. type: Plain text +#: en/structure/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 ### +#: en/structure/domain.md +#, no-wrap +msgid "Service" +msgstr "" + +#. type: Plain text +#: en/structure/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: Bullet: '- ' +#: en/structure/domain.md en/structure/service.md +#, no-wrap +msgid "Repository" +msgstr "" + +#. type: Plain text +#: en/structure/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 +#: en/structure/domain.md +msgid "Repository is usually implemented as a service." +msgstr "" + +#. type: Title ### +#: en/structure/domain.md +#, no-wrap +msgid "Instantiating building blocks" +msgstr "" + +#. type: Plain text +#: en/structure/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: Bullet: '- ' +#: en/structure/domain.md +msgid "[BoundedContext by Martin Fowler](https://martinfowler.com/bliki/BoundedContext.html)" +msgstr "" + +#. type: Bullet: '- ' +#: en/structure/domain.md +msgid "[ValueObject by Martin Fowler](https://martinfowler.com/bliki/ValueObject.html)" +msgstr "" + +#. type: Bullet: '- ' +#: en/structure/domain.md +msgid "[Aggregate by Marting Fowler](https://martinfowler.com/bliki/DDD_Aggregate.html)" +msgstr "" diff --git a/_translations/guide/po/es/structure_entry-script.md.po b/_translations/guide/po/es/structure_entry-script.md.po new file mode 100644 index 00000000..48447f4a --- /dev/null +++ b/_translations/guide/po/es/structure_entry-script.md.po @@ -0,0 +1,193 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title # +#: en/structure/entry-script.md +#, no-wrap +msgid "Entry scripts" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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 +#: en/structure/entry-script.md +msgid "Entry script for console application is `./yii`." +msgstr "" + +#. type: Plain text +#: en/structure/entry-script.md +msgid "Entry scripts mainly perform the following work with the help of `ApplicationRunner`:" +msgstr "" + +#. type: Bullet: '* ' +#: en/structure/entry-script.md +msgid "Register [Composer autoloader](https://getcomposer.org/doc/01-basic-usage.md#autoloading);" +msgstr "" + +#. type: Bullet: '* ' +#: en/structure/entry-script.md +msgid "Obtain configuration;" +msgstr "" + +#. type: Bullet: '* ' +#: en/structure/entry-script.md +msgid "Use configuration to initialize a dependency injection container;" +msgstr "" + +#. type: Bullet: '* ' +#: en/structure/entry-script.md +msgid "Get an instance of the request." +msgstr "" + +#. type: Bullet: '* ' +#: en/structure/entry-script.md +msgid "Pass it to `Application` to handle and get a response from it." +msgstr "" + +#. type: Bullet: '* ' +#: en/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 ## +#: en/structure/entry-script.md +#, no-wrap +msgid "Web Applications " +msgstr "" + +#. type: Plain text +#: en/structure/entry-script.md +msgid "The following is the code in the entry script for the application template:" +msgstr "" + +#. type: Fenced code block (php) +#: en/structure/entry-script.md +#, no-wrap +msgid "" +"debug();\n" +"// Run application:\n" +"$runner->run();\n" +msgstr "" + +#. type: Title ## +#: en/structure/entry-script.md +#, no-wrap +msgid "Console Applications " +msgstr "" + +#. type: Plain text +#: en/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) +#: en/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 ## +#: en/structure/entry-script.md +#, no-wrap +msgid "Alternative runtimes" +msgstr "" + +#. type: Plain text +#: en/structure/entry-script.md +msgid "For alternative runtimes such as RoadRunner or Swoole, special entry scripts should be used. See:" +msgstr "" + +#. type: Bullet: '- ' +#: en/structure/entry-script.md +msgid "[Using Yii with RoadRunner](../tutorial/using-yii-with-roadrunner.md)" +msgstr "" + +#. type: Bullet: '- ' +#: en/structure/entry-script.md +msgid "[Using Yii with Swoole](../tutorial/using-yii-with-swoole.md)" +msgstr "" diff --git a/_translations/guide/po/es/structure_handler.md.po b/_translations/guide/po/es/structure_handler.md.po new file mode 100644 index 00000000..bda05c2a --- /dev/null +++ b/_translations/guide/po/es/structure_handler.md.po @@ -0,0 +1,23 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title # +#: en/structure/handler.md +#, no-wrap +msgid "Request handlers" +msgstr "" diff --git a/_translations/guide/po/es/structure_middleware.md.po b/_translations/guide/po/es/structure_middleware.md.po new file mode 100644 index 00000000..51876f24 --- /dev/null +++ b/_translations/guide/po/es/structure_middleware.md.po @@ -0,0 +1,313 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" +"PO-Revision-Date: 2025-09-04 11:19+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title # +#: ../../guide/en/structure/middleware.md +#, no-wrap +msgid "Middleware" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/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: '- ' +#: ../../guide/en/structure/middleware.md +msgid "Pass the request to the next middleware performing some work before / after it." +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/structure/middleware.md +msgid "Form the response and return it." +msgstr "" + +#. type: Plain text +#: ../../guide/en/structure/middleware.md +msgid "Depending on middleware used, application behavior may vary significantly." +msgstr "" + +#. type: Plain text +#: ../../guide/en/structure/middleware.md +msgid "![Middleware](img/middleware.svg)" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/structure/middleware.md +msgid "![Middleware](img/middleware_alternative.svg)" +msgstr "" + +#. type: Title ## +#: ../../guide/en/structure/middleware.md +#, no-wrap +msgid "Using middleware" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/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 +#: ../../guide/en/structure/middleware.md +msgid "Now register the middleware in DI container configuration `config/web.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/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 +#: ../../guide/en/structure/middleware.md +msgid "In the `config/routes.php`, add new route:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/structure/middleware.md +#, no-wrap +msgid "" +"([SiteController::class, 'auth'])\n" +" ->name('site/auth')\n" +" ->addMiddleware(BasicAuthentication::class)\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/structure/middleware.md +#, fuzzy +#| msgid "The event class itself may look like the following:" +msgid "The action itself could be the following:" +msgstr "La clase del evento en sí se podría ver como esto:" + +#. type: Fenced code block (php) +#: ../../guide/en/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 +#: ../../guide/en/structure/middleware.md +msgid "Basic authentication middleware wrote to request `username` attribute, so you can access the data if needed." +msgstr "" + +#. type: Plain text +#: ../../guide/en/structure/middleware.md +msgid "To apply middleware to application overall regardless of URL, adjust `config/application.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/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" +" CsrfMiddleware::class,\n" +" Router::class,\n" +" ]\n" +" );\n" +" }),\n" +" 'fallbackHandler' => Reference::to(NotFoundHandler::class),\n" +" ],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Title ## +#: ../../guide/en/structure/middleware.md +#, no-wrap +msgid "Creating your own middleware" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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) +#: ../../guide/en/structure/middleware.md +#, no-wrap +msgid "public function process(ServerRequestInterface $request, RequestHandlerInterface $next): ResponseInterface;\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 ### +#: ../../guide/en/structure/middleware.md +#, no-wrap +msgid "Forming a response directly" +msgstr "" + +#. type: Plain text +#: ../../guide/en/structure/middleware.md +msgid "To respond directly, one needs a response factory passed via constructor:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/structure/middleware.md +#, no-wrap +msgid "" +"responseFactory->createResponse();\n" +" $response->getBody()->write('Hello!');\n" +" return $response;\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ### +#: ../../guide/en/structure/middleware.md +#, no-wrap +msgid "Delegating handling to the next middleware" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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) +#: ../../guide/en/structure/middleware.md +#, no-wrap +msgid "return $next->handle($request);\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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) +#: ../../guide/en/structure/middleware.md +#, no-wrap +msgid "" +"$request = $request->withAttribute('answer', 42);\n" +"return $next->handle();\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/structure/middleware.md +msgid "To get it in the next middleware:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/structure/middleware.md +#, no-wrap +msgid "$answer = $request->getAttribute('answer');\n" +msgstr "" + +#. type: Title ### +#: ../../guide/en/structure/middleware.md +#, no-wrap +msgid "Capturing response to manipulate it" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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) +#: ../../guide/en/structure/middleware.md +#, no-wrap +msgid "" +"$response = $next->handle($request);\n" +"// extra handing\n" +"return $response;\n" +msgstr "" diff --git a/_translations/guide/po/es/structure_overview.md.po b/_translations/guide/po/es/structure_overview.md.po new file mode 100644 index 00000000..9af2cdd4 --- /dev/null +++ b/_translations/guide/po/es/structure_overview.md.po @@ -0,0 +1,160 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title # +#: en/structure/overview.md +#, no-wrap +msgid "Overview" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/structure/overview.md +msgid "For example, if the application is an online store, the context could be:" +msgstr "" + +#. type: Bullet: '- ' +#: en/structure/overview.md +msgid "Customer" +msgstr "" + +#. type: Bullet: ' - ' +#: en/structure/overview.md +msgid "Profile" +msgstr "" + +#. type: Bullet: ' - ' +#: en/structure/overview.md +msgid "Products list" +msgstr "" + +#. type: Bullet: ' - ' +#: en/structure/overview.md +msgid "Checkout" +msgstr "" + +#. type: Bullet: '- ' +#: en/structure/overview.md +msgid "Logistics" +msgstr "" + +#. type: Bullet: '- ' +#: en/structure/overview.md +msgid "Delivery" +msgstr "" + +#. type: Bullet: ' - ' +#: en/structure/overview.md +msgid "Addresses" +msgstr "" + +#. type: Bullet: '- ' +#: en/structure/overview.md +msgid "Helpdesk" +msgstr "" + +#. type: Bullet: ' - ' +#: en/structure/overview.md +msgid "Support" +msgstr "" + +#. type: Bullet: ' - ' +#: en/structure/overview.md +msgid "Claims" +msgstr "" + +#. type: Bullet: ' - ' +#: en/structure/overview.md +msgid "Returns" +msgstr "" + +#. type: Bullet: '- ' +#: en/structure/overview.md +msgid "Accounting" +msgstr "" + +#. type: Bullet: ' - ' +#: en/structure/overview.md +msgid "Transactions" +msgstr "" + +#. type: Bullet: ' - ' +#: en/structure/overview.md +msgid "Taxes" +msgstr "" + +#. type: Plain text +#: en/structure/overview.md +msgid "For a \"Customer\" context, residing under `App\\Customer` namespace, structure would be:" +msgstr "" + +#. type: Fenced code block +#: en/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 +#: en/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 +#: en/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 +#: en/structure/overview.md +msgid "Besides, Yii applications also have the following:" +msgstr "" + +#. type: Bullet: '* ' +#: en/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: '* ' +#: en/structure/overview.md +msgid "[services](service.md): they're typically stateless objects registered within dependency container and provide various action methods." +msgstr "" + +#. type: Bullet: '* ' +#: en/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/guide/po/es/structure_package.md.po b/_translations/guide/po/es/structure_package.md.po new file mode 100644 index 00000000..5e71e6d5 --- /dev/null +++ b/_translations/guide/po/es/structure_package.md.po @@ -0,0 +1,342 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title # +#: en/structure/package.md +#, no-wrap +msgid "Packages" +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "Reusable code could be released as [a Composer package](https://getcomposer.org/doc/05-repositories.md#package). It could be an infrastructure library, a module representing one of the application contexts or, basically, any reusable code." +msgstr "" + +#. type: Title ## +#: en/structure/package.md +#, no-wrap +msgid "Using packages " +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "By default, Composer installs packages registered on [Packagist](https://packagist.org/) — the biggest repository for open source PHP packages. You can look for packages on Packagist. You may also [create your own repository](https://getcomposer.org/doc/05-repositories.md#repository) and configure Composer to use it. This is useful if you're developing private packages that you want to share within your projects only." +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "Packages installed by Composer are stored in the `vendor` directory of your project. Because the Composer is a dependency manager, when it installs a package, it will also install all its dependent packages." +msgstr "" + +#. type: Plain text +#: en/structure/package.md +#, no-wrap +msgid "" +"> [!WARNING]\n" +"> `vendor` directory of your application should never be modified.\n" +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "A package could be installed with the following command:" +msgstr "" + +#. type: Fenced code block +#: en/structure/package.md +#, no-wrap +msgid "composer install vendor-name/package-name\n" +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "After it's done, Composer modifies `composer.json` and `composer.lock`. The former defines what packages to install, and their version constraints the latter stores a snapshot of exact versions actually installed." +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "Classes from the package will be available immediately via [autoloading](../concept/autoloading.md)." +msgstr "" + +#. type: Title ## +#: en/structure/package.md +#, no-wrap +msgid "Creating packages " +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "You may consider creating a package when you feel the need to share with other people your great code. A package can contain any code you like, such as a helper class, a widget, a service, middleware, the whole module, etc." +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "Below are the basic steps you may follow." +msgstr "" + +#. type: Bullet: '1. ' +#: en/structure/package.md +msgid "Create a project for your package and host it on a VCS repository, such as [GitHub.com](https://github.com). The development and maintenance work for the package should be done on this repository." +msgstr "" + +#. type: Bullet: '2. ' +#: en/structure/package.md +msgid "Under the root directory of the project, create a file named `composer.json` as required by Composer. Please refer to the next subsection for more details." +msgstr "" + +#. type: Bullet: '3. ' +#: en/structure/package.md +msgid "Register your package with a Composer repository, such as [Packagist](https://packagist.org/), so that other users can find and install your package using Composer." +msgstr "" + +#. type: Title ### +#: en/structure/package.md +#, no-wrap +msgid "`composer.json` " +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "Each Composer package must have a `composer.json` file in its root directory. The file contains the metadata about the package. You may find the complete specification about this file in the [Composer Manual](https://getcomposer.org/doc/01-basic-usage.md#composer-json-project-setup). The following example shows the `composer.json` file for the `yiisoft/yii-widgets` package:" +msgstr "" + +#. type: Fenced code block (json) +#: en/structure/package.md +#, no-wrap +msgid "" +"{\n" +" \"name\": \"yiisoft/yii-widgets\",\n" +" \"type\": \"library\",\n" +" \"description\": \"Yii widgets collection\",\n" +" \"keywords\": [\n" +" \"yii\",\n" +" \"widgets\"\n" +" ],\n" +" \"homepage\": \"https://www.yiiframework.com/\",\n" +" \"license\": \"BSD-3-Clause\",\n" +" \"support\": {\n" +" \"issues\": \"https://github.com/yiisoft/yii-widgets/issues?state=open\",\n" +" \"forum\": \"https://www.yiiframework.com/forum/\",\n" +" \"wiki\": \"https://www.yiiframework.com/wiki/\",\n" +" \"irc\": \"ircs://irc.libera.chat:6697/yii\",\n" +" \"chat\": \"https://t.me/yii3en\",\n" +" \"source\": \"https://github.com/yiisoft/yii-widgets\"\n" +" },\n" +" \"funding\": [\n" +" {\n" +" \"type\": \"opencollective\",\n" +" \"url\": \"https://opencollective.com/yiisoft\"\n" +" },\n" +" {\n" +" \"type\": \"github\",\n" +" \"url\": \"https://github.com/sponsors/yiisoft\"\n" +" }\n" +" ],\n" +" \"require\": {\n" +" \"php\": \"^7.4|^8.0\",\n" +" \"yiisoft/aliases\": \"^1.1|^2.0\",\n" +" \"yiisoft/cache\": \"^1.0\",\n" +" \"yiisoft/html\": \"^2.0\",\n" +" \"yiisoft/view\": \"^4.0\",\n" +" \"yiisoft/widget\": \"^1.0\"\n" +" },\n" +" \"require-dev\": {\n" +" \"phpunit/phpunit\": \"^9.5\",\n" +" \"roave/infection-static-analysis-plugin\": \"^1.16\",\n" +" \"spatie/phpunit-watcher\": \"^1.23\",\n" +" \"vimeo/psalm\": \"^4.18\",\n" +" \"yiisoft/psr-dummy-provider\": \"^1.0\",\n" +" \"yiisoft/test-support\": \"^1.3\"\n" +" },\n" +" \"autoload\": {\n" +" \"psr-4\": {\n" +" \"Yiisoft\\\\Yii\\\\Widgets\\\\\": \"src\"\n" +" }\n" +" },\n" +" \"autoload-dev\": {\n" +" \"psr-4\": {\n" +" \"Yiisoft\\\\Yii\\\\Widgets\\\\Tests\\\\\": \"tests\"\n" +" }\n" +" },\n" +" \"extra\": {\n" +" \"branch-alias\": {\n" +" \"dev-master\": \"3.0.x-dev\"\n" +" }\n" +" },\n" +" \"scripts\": {\n" +" \"test\": \"phpunit --testdox --no-interaction\",\n" +" \"test-watch\": \"phpunit-watcher watch\"\n" +" },\n" +" \"config\": {\n" +" \"sort-packages\": true,\n" +" \"allow-plugins\": {\n" +" \"infection/extension-installer\": true,\n" +" \"composer/package-versions-deprecated\": true\n" +" }\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title #### +#: en/structure/package.md +#, no-wrap +msgid "Package Name " +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "Each Composer package should have a package name which uniquely identifies the package among all others. The format of package names is `vendorName/projectName`. For example, in the package name `yiisoft/queue`, the vendor name, and the project name are `yiisoft` and `queue`, respectively." +msgstr "" + +#. type: Plain text +#: en/structure/package.md +#, no-wrap +msgid "" +"> [!WARNING]\n" +"> Don't use `yiisoft` as your vendor name as it's reserved for use by the Yii itself.\n" +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "We recommend you prefix `yii-` to the project name for packages that aren't able to work as general PHP packages and require Yii application. This will allow users to more easily tell whether a package is Yii specific." +msgstr "" + +#. type: Title #### +#: en/structure/package.md +#, no-wrap +msgid "Dependencies " +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "If your extension depends on other packages, you should list them in `require` section of `composer.json`. Make sure you also list appropriate version constraints (e.g. `^1.0`, `@stable`) for each dependent package. Use stable dependencies when your extension is released in a stable version." +msgstr "" + +#. type: Title #### +#: en/structure/package.md +#, no-wrap +msgid "Class Autoloading " +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "In order for your classes to be autoloaded, you should specify the `autoload` entry in the `composer.json` file, like shown below:" +msgstr "" + +#. type: Fenced code block (json) +#: en/structure/package.md +#, no-wrap +msgid "" +"{\n" +" // ....\n" +"\n" +" \"autoload\": {\n" +" \"psr-4\": {\n" +" \"MyVendorName\\\\MyPackageName\\\\\": \"src\"\n" +" }\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "You may list one or multiple root namespaces and their corresponding file paths." +msgstr "" + +#. type: Title ### +#: en/structure/package.md +#, no-wrap +msgid "Recommended Practices " +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "Because packages are meant to be used by other people, you often need to make an extra effort during development. Below, we introduce some common and recommended practices in creating high-quality extensions." +msgstr "" + +#. type: Title #### +#: en/structure/package.md +#, no-wrap +msgid "Testing " +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "You want your package to run flawlessly without bringing problems to other people. To reach this goal, you should test your extension before releasing it to the public." +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "It's recommended that you create various test cases to cover your extension code rather than relying on manual tests. Each time before you release a new version of your package, you may run these test cases to make sure everything is in good shape. For more details, please refer to the [Testing](../testing/overview.md) section." +msgstr "" + +#. type: Title #### +#: en/structure/package.md +#, no-wrap +msgid "Versioning " +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "You should give each release of your extension a version number (e.g. `1.0.1`). We recommend you follow the [semantic versioning](https://semver.org) practice when determining what version numbers should be used." +msgstr "" + +#. type: Title #### +#: en/structure/package.md +#, no-wrap +msgid "Releasing " +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "To let other people know about your package, you need to release it to the public." +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "If it's the first time you're releasing a package, you should register it in a Composer repository, such as [Packagist](https://packagist.org/). After that, all you need to do is create a release tag (for example, `v1.0.1`) on the VCS repository of your extension and notify the Composer repository about the new release. People will then be able to find the new release and install or update the package through the Composer repository." +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "In the release of your package, in addition to code files, you should also consider including the following to help other people learn about and use your extension:" +msgstr "" + +#. type: Bullet: '* ' +#: en/structure/package.md +msgid "A readme file in the package root directory: it describes what your extension does and how to install and use it. We recommend you write it in [Markdown](https://daringfireball.net/projects/markdown/) format and name the file as `README.md`." +msgstr "" + +#. type: Bullet: '* ' +#: en/structure/package.md +msgid "A changelog file in the package root directory: it lists what changes are made in each release. The file may be written in Markdown format and named as `CHANGELOG.md`." +msgstr "" + +#. type: Bullet: '* ' +#: en/structure/package.md +msgid "An upgrade file in the package root directory: it gives the instructions on how to upgrade from older releases of the extension. The file may be written in Markdown format and named as `UPGRADE.md`." +msgstr "" + +#. type: Bullet: '* ' +#: en/structure/package.md +msgid "Tutorials, demos, screenshots, etc.: these are needed if your extension provides many features that can't be fully covered in the readme file." +msgstr "" + +#. type: Bullet: '* ' +#: en/structure/package.md +msgid "API documentation: your code should be well-documented to allow other people to more easily read and understand it." +msgstr "" diff --git a/_translations/guide/po/es/structure_service.md.po b/_translations/guide/po/es/structure_service.md.po new file mode 100644 index 00000000..fd3b204c --- /dev/null +++ b/_translations/guide/po/es/structure_service.md.po @@ -0,0 +1,195 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Bullet: '- ' +#: en/structure/domain.md en/structure/service.md +#, no-wrap +msgid "Entity" +msgstr "" + +#. type: Bullet: '- ' +#: en/structure/domain.md en/structure/service.md +#, no-wrap +msgid "Repository" +msgstr "" + +#. type: Title # +#: en/structure/service.md +#, no-wrap +msgid "Service components" +msgstr "" + +#. type: Plain text +#: en/structure/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) +#: en/structure/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 +#: en/structure/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) +#: en/structure/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 +#: en/structure/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 ## +#: en/structure/service.md +#, no-wrap +msgid "Service dependencies and configuration" +msgstr "" + +#. type: Plain text +#: en/structure/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: '- ' +#: en/structure/service.md +msgid "After the service is created, it shouldn't be re-configured in runtime." +msgstr "" + +#. type: Bullet: '- ' +#: en/structure/service.md +msgid "DI container instance usually **shouldn't** be injected as a dependency. Prefer concrete interfaces." +msgstr "" + +#. type: Bullet: '- ' +#: en/structure/service.md +msgid "In case of complicated or \"heavy\" initialization, try to postpone it until the service method is called." +msgstr "" + +#. type: Plain text +#: en/structure/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) +#: en/structure/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 ## +#: en/structure/service.md +#, no-wrap +msgid "Service methods" +msgstr "" + +#. type: Plain text +#: en/structure/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) +#: en/structure/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 +#: en/structure/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 ## +#: en/structure/service.md +#, no-wrap +msgid "Is everything a service?" +msgstr "" + +#. type: Plain text +#: en/structure/service.md +msgid "Often it makes sense to choose another class type to place your code into. Check:" +msgstr "" + +#. type: Bullet: '- ' +#: en/structure/service.md +msgid "Widget" +msgstr "" + +#. type: Bullet: '- ' +#: en/structure/service.md +msgid "[Middleware](middleware.md)" +msgstr "" diff --git a/_translations/guide/po/es/tutorial_console-applications.md.po b/_translations/guide/po/es/tutorial_console-applications.md.po new file mode 100644 index 00000000..c133277b --- /dev/null +++ b/_translations/guide/po/es/tutorial_console-applications.md.po @@ -0,0 +1,141 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title ## +#: en/concept/autoloading.md en/security/best-practices.md +#: en/structure/domain.md en/tutorial/console-applications.md +#, no-wrap +msgid "References" +msgstr "Referencias" + +#. type: Title # +#: en/tutorial/console-applications.md +#, no-wrap +msgid "Console applications" +msgstr "" + +#. type: Plain text +#: en/tutorial/console-applications.md +msgid "Console applications are mainly used to create utility, background processing and maintenance tasks." +msgstr "" + +#. type: Plain text +#: en/tutorial/console-applications.md +msgid "To get support for console application in your project, get `yiisoft/yii-console` via composer:" +msgstr "" + +#. type: Fenced code block +#: en/tutorial/console-applications.md +#, no-wrap +msgid "composer require yiisoft/yii-console\n" +msgstr "" + +#. type: Plain text +#: en/tutorial/console-applications.md +msgid "After it's installed, you can access the entry point as" +msgstr "" + +#. type: Fenced code block +#: en/tutorial/console-applications.md +#, no-wrap +msgid "./yii\n" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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) +#: en/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 +#: en/tutorial/console-applications.md +msgid "Now register the command in `config/params.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: en/tutorial/console-applications.md +#, no-wrap +msgid "" +"return [\n" +" 'console' => [\n" +" 'commands' => [\n" +" 'demo/hello' => App\\Demo\\HelloCommand::class,\n" +" ],\n" +" ], \n" +"];\n" +msgstr "" + +#. type: Plain text +#: en/tutorial/console-applications.md +msgid "After it's done, the command could be executed as" +msgstr "" + +#. type: Fenced code block +#: en/tutorial/console-applications.md +#, no-wrap +msgid "./yii demo:hello Alice\n" +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/console-applications.md +msgid "[Symfony Console component guide](https://symfony.com/doc/current/components/console.html)" +msgstr "" diff --git a/_translations/guide/po/es/tutorial_mailing.md.po b/_translations/guide/po/es/tutorial_mailing.md.po new file mode 100644 index 00000000..3361614a --- /dev/null +++ b/_translations/guide/po/es/tutorial_mailing.md.po @@ -0,0 +1,607 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\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/guide/po/es/tutorial_performance-tuning.md.po b/_translations/guide/po/es/tutorial_performance-tuning.md.po new file mode 100644 index 00000000..cca9c141 --- /dev/null +++ b/_translations/guide/po/es/tutorial_performance-tuning.md.po @@ -0,0 +1,345 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" +"PO-Revision-Date: 2025-09-04 11:19+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title # +#: ../../guide/en/tutorial/performance-tuning.md +#, no-wrap +msgid "Performance tuning" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 ## +#: ../../guide/en/tutorial/performance-tuning.md +#, no-wrap +msgid "Optimizing your PHP Environment " +msgstr "" + +#. type: Plain text +#: ../../guide/en/tutorial/performance-tuning.md +msgid "A well-configured PHP environment is important. To get maximum performance:" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/tutorial/performance-tuning.md +msgid "Use the latest stable PHP version. Major releases of PHP may bring significant performance improvements." +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/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: '- ' +#: ../../guide/en/tutorial/performance-tuning.md +msgid "[Tune `realpath()` cache](https://github.com/samdark/realpath_cache_tuner)." +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/tutorial/performance-tuning.md +msgid "Make sure [XDebug](https://xdebug.org/) isn't installed in the production environment." +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/tutorial/performance-tuning.md +msgid "Try [PHP 7 preloading](https://wiki.php.net/rfc/preload)." +msgstr "" + +#. type: Title ## +#: ../../guide/en/tutorial/performance-tuning.md +#, fuzzy, no-wrap +#| msgid "Raising events " +msgid "Optimizing your code " +msgstr "Lanzamiento de Eventos " + +#. type: Plain text +#: ../../guide/en/tutorial/performance-tuning.md +msgid "Beyond environment configuration, there are code-level optimizations that can improve your application's performance:" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/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: '- ' +#: ../../guide/en/tutorial/performance-tuning.md +msgid "[Speeding up array_merge()](https://www.exakat.io/speeding-up-array_merge/)" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/tutorial/performance-tuning.md +msgid "[Move that foreach() inside the method](https://www.exakat.io/move-that-foreach-inside-the-method/)" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/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: '- ' +#: ../../guide/en/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 +#: ../../guide/en/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 ## +#: ../../guide/en/tutorial/performance-tuning.md +#, no-wrap +msgid "Using caching techniques " +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 ## +#: ../../guide/en/tutorial/performance-tuning.md +#, no-wrap +msgid "Optimizing session storage " +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/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) +#: ../../guide/en/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 ## +#: ../../guide/en/tutorial/performance-tuning.md +#, no-wrap +msgid "Optimizing databases " +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/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 +#: ../../guide/en/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 +#: ../../guide/en/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 ## +#: ../../guide/en/tutorial/performance-tuning.md +#, no-wrap +msgid "Optimizing composer autoloader " +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/tutorial/performance-tuning.md +#, no-wrap +msgid "composer dumpautoload -o\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 ## +#: ../../guide/en/tutorial/performance-tuning.md +#, no-wrap +msgid "Processing data offline " +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/tutorial/performance-tuning.md +msgid "There are two methods to process data offline: pull and push." +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/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 ## +#: ../../guide/en/tutorial/performance-tuning.md +#, no-wrap +msgid "Using preloading" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/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 +#: ../../guide/en/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 ### +#: ../../guide/en/tutorial/performance-tuning.md +#, no-wrap +msgid "Preloading benchmarks" +msgstr "" + +#. type: Plain text +#: ../../guide/en/tutorial/performance-tuning.md +msgid "The application template benchmark includes configuring classes to injected dependencies in the bootstrap script." +msgstr "" + +#. type: Plain text +#: ../../guide/en/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) +#: ../../guide/en/tutorial/performance-tuning.md +#, no-wrap +msgid "ab -n 1000 -c 10 -t 10\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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) +#: ../../guide/en/tutorial/performance-tuning.md +#, no-wrap +msgid "composer install --optimize-autoloader --no-dev\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/tutorial/performance-tuning.md +msgid "With preloading enabled, the entire composer class map (825 files) was used:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/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 #### +#: ../../guide/en/tutorial/performance-tuning.md +#, no-wrap +msgid "Test results" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/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 ## +#: ../../guide/en/tutorial/performance-tuning.md +#, no-wrap +msgid "Performance profiling " +msgstr "" + +#. type: Plain text +#: ../../guide/en/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: Bullet: '- ' +#: ../../guide/en/tutorial/performance-tuning.md +msgid "[Yii debug toolbar and debugger](https://github.com/yiisoft/yii2-debug/blob/master/docs/guide/README.md)" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/tutorial/performance-tuning.md +msgid "[Blackfire](https://blackfire.io/)" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/tutorial/performance-tuning.md +msgid "[XHProf](https://secure.php.net/manual/en/book.xhprof.php)" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/tutorial/performance-tuning.md +msgid "[XDebug profiler](https://xdebug.org/docs/profiler)" +msgstr "" diff --git a/_translations/guide/po/es/tutorial_using-with-event-loop.md.po b/_translations/guide/po/es/tutorial_using-with-event-loop.md.po new file mode 100644 index 00000000..896c6e76 --- /dev/null +++ b/_translations/guide/po/es/tutorial_using-with-event-loop.md.po @@ -0,0 +1,132 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" +"PO-Revision-Date: 2025-09-04 11:19+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title # +#: ../../guide/en/tutorial/using-with-event-loop.md +#, no-wrap +msgid "Using Yii with event loop" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/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 +#: ../../guide/en/tutorial/using-with-event-loop.md +msgid "There are multiple tools that could be used to achieve it. Notably, [FrankenPHP](https://frankenphp.dev/), [RoadRunner](https://roadrunner.dev/) and [Swoole](https://www.swoole.co.uk/)." +msgstr "" + +#. type: Title ## +#: ../../guide/en/tutorial/using-with-event-loop.md +#, no-wrap +msgid "Event loop implications" +msgstr "" + +#. type: Plain text +#: ../../guide/en/tutorial/using-with-event-loop.md +msgid "Event loop worker basically looks like the following:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/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 +#: ../../guide/en/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 +#: ../../guide/en/tutorial/using-with-event-loop.md +msgid "That means that there's more to consider when developing applications." +msgstr "" + +#. type: Title ### +#: ../../guide/en/tutorial/using-with-event-loop.md +#, no-wrap +msgid "Processing is blocking" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 ### +#: ../../guide/en/tutorial/using-with-event-loop.md +#, no-wrap +msgid "Services and state" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/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) +#: ../../guide/en/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 ## +#: ../../guide/en/tutorial/using-with-event-loop.md +#, no-wrap +msgid "Integrations" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/tutorial/using-with-event-loop.md +msgid "[RoadRunner](using-yii-with-roadrunner.md)" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/tutorial/using-with-event-loop.md +msgid "[Swoole](using-yii-with-swoole.md)" +msgstr "" diff --git a/_translations/guide/po/es/tutorial_using-yii-with-roadrunner.md.po b/_translations/guide/po/es/tutorial_using-yii-with-roadrunner.md.po new file mode 100644 index 00000000..7ece32c3 --- /dev/null +++ b/_translations/guide/po/es/tutorial_using-yii-with-roadrunner.md.po @@ -0,0 +1,183 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title ## +#: en/concept/configuration.md en/tutorial/using-yii-with-roadrunner.md +#: en/views/view-injections.md +#, no-wrap +msgid "Configuration" +msgstr "" + +#. type: Title # +#: en/tutorial/using-yii-with-roadrunner.md +#, no-wrap +msgid "Using Yii with RoadRunner" +msgstr "" + +#. type: Plain text +#: en/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: Title ## +#: en/tutorial/using-yii-with-roadrunner.md +#: en/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "Installation" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/tutorial/using-yii-with-roadrunner.md +#, no-wrap +msgid "composer require yiisoft/yii-runner-roadrunner\n" +msgstr "" + +#. type: Plain text +#: en/tutorial/using-yii-with-roadrunner.md +msgid "After installation is done, run" +msgstr "" + +#. type: Fenced code block +#: en/tutorial/using-yii-with-roadrunner.md +#, no-wrap +msgid "./vendor/bin/rr get\n" +msgstr "" + +#. type: Plain text +#: en/tutorial/using-yii-with-roadrunner.md +msgid "That would download ready to use RoadRunner server `rr` binary." +msgstr "" + +#. type: Plain text +#: en/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) +#: en/tutorial/using-yii-with-roadrunner.md +#, no-wrap +msgid "" +"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" +" num_workers: 4\n" +" max_jobs: 64\n" +" middleware: [\"static\", \"headers\"]\n" +" static:\n" +" dir: \"public\"\n" +" forbid: [\".php\", \".htaccess\"]\n" +" headers:\n" +" response:\n" +" \"Cache-Control\": \"no-cache\"\n" +"\n" +"reload:\n" +" interval: 1s\n" +" patterns: [ \".php\" ]\n" +" services:\n" +" http:\n" +" recursive: true\n" +" dirs: [ \".\" ]\n" +"\n" +"logs:\n" +" mode: production\n" +" level: warn\n" +msgstr "" + +#. type: Plain text +#: en/tutorial/using-yii-with-roadrunner.md +msgid "We're specifying that entry script is `worker.php`, there should be three workers on port 8080, `public` directory files are static ones except `.php` and `.htaccess`. Also, we're sending an additional header." +msgstr "" + +#. type: Plain text +#: en/tutorial/using-yii-with-roadrunner.md +msgid "Create `/worker.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: en/tutorial/using-yii-with-roadrunner.md +#, no-wrap +msgid "" +"run();\n" +msgstr "" + +#. type: Title ## +#: en/tutorial/using-yii-with-roadrunner.md +#: en/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "Starting a server" +msgstr "" + +#. type: Plain text +#: en/tutorial/using-yii-with-roadrunner.md +#: en/tutorial/using-yii-with-swoole.md +msgid "To start a server, execute the following command:" +msgstr "" + +#. type: Fenced code block +#: en/tutorial/using-yii-with-roadrunner.md +#, no-wrap +msgid "./rr serve -d\n" +msgstr "" + +#. type: Title ## +#: en/tutorial/using-yii-with-roadrunner.md +#, no-wrap +msgid "On worker scope" +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/using-yii-with-roadrunner.md +msgid "Each worker's scope is isolated from other workers. Memory isn't shared." +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/using-yii-with-roadrunner.md +msgid "A single worker serves multiple requests where the scope is shared." +msgstr "" + +#. type: Bullet: '- ' +#: en/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/guide/po/es/tutorial_using-yii-with-swoole.md.po b/_translations/guide/po/es/tutorial_using-yii-with-swoole.md.po new file mode 100644 index 00000000..43a0103a --- /dev/null +++ b/_translations/guide/po/es/tutorial_using-yii-with-swoole.md.po @@ -0,0 +1,197 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" +"PO-Revision-Date: 2025-09-04 11:19+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title ## +#: ../../guide/en/tutorial/using-yii-with-roadrunner.md +#: ../../guide/en/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "Installation" +msgstr "" + +#. type: Title ## +#: ../../guide/en/tutorial/using-yii-with-roadrunner.md +#: ../../guide/en/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "Starting a server" +msgstr "" + +#. type: Plain text +#: ../../guide/en/tutorial/using-yii-with-roadrunner.md +#: ../../guide/en/tutorial/using-yii-with-swoole.md +msgid "To start a server, execute the following command:" +msgstr "" + +#. type: Title # +#: ../../guide/en/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "Using Yii with Swoole" +msgstr "" + +#. type: Plain text +#: ../../guide/en/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "" +"[Swoole](https://www.swoole.co.uk/) is a PHP network framework distributed as a PECL extension. It allows you built-in async,\n" +"multiple threads I/O modules. Developers can use sync or async, coroutine API to write the applications.\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/tutorial/using-yii-with-swoole.md +msgid "In the context of Yii, it allows running request handlers 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 +#: ../../guide/en/tutorial/using-yii-with-swoole.md +msgid "Swoole works on Linux and macOS and can be installed via pecl:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../../guide/en/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "pecl install swoole\n" +msgstr "" + +#. type: Title ## +#: ../../guide/en/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "Putting up a server" +msgstr "" + +#. type: Plain text +#: ../../guide/en/tutorial/using-yii-with-swoole.md +msgid "Since Swoole doesn't have built-in PSR-7 support, you need a package fixing so:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "composer require ilexn/swoole-convent-psr7\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/tutorial/using-yii-with-swoole.md +msgid "Create an entry script, `server.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "" +"withDefinitions($config->get('web'))\n" +" ->withProviders($config->get('providers-web'));\n" +"$container = new Container($containerConfig);\n" +"\n" +"$bootstrapList = $config->get('bootstrap-web');\n" +"foreach ($bootstrapList as $callback) {\n" +" if (!(is_callable($callback))) {\n" +" $type = is_object($callback) ? get_class($callback) : gettype($callback);\n" +"\n" +" throw new \\RuntimeException(\"Bootstrap callback must be callable, $type given.\");\n" +" }\n" +" $callback($container);\n" +"}\n" +"\n" +"$application = $container->get(Application::class);\n" +"\n" +"$serverRequestFactory = new \\Ilex\\SwoolePsr7\\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 Swoole\\HTTP\\Server('0.0.0.0', 9501);\n" +"\n" +"$server->on('start', static function (Swoole\\Http\\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 (Swoole\\Http\\Request $request, Swoole\\Http\\Response $response) use ($serverRequestFactory, $application, $container) {\n" +" $psr7Response = null;\n" +" try {\n" +" $requestContainer = clone $container;\n" +" $psr7Request = $serverRequestFactory->createFromSwoole($request);\n" +" $psr7Response = $application->handle($psr7Request);\n" +" \n" +" $converter = new \\Ilex\\SwoolePsr7\\SwooleResponseConverter($response);\n" +" $converter->send($psr7Response);\n" +" } catch (\\Throwable $t) {\n" +" // TODO: render it properly\n" +" $response->end($t->getMessage());\n" +" } finally {\n" +" $application->afterEmit($psr7Response ?? null);\n" +" $container->get(\\Yiisoft\\Di\\StateResetter::class)->reset();\n" +" $container = $requestContainer; \n" +" }\n" +"});\n" +"\n" +"$server->on('shutdown', static function (Swoole\\Http\\Server $server) use ($application) {\n" +" $application->shutdown();\n" +"});\n" +"\n" +"$server->start();\n" +msgstr "" + +#. type: Fenced code block +#: ../../guide/en/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "php server.php\n" +msgstr "" + +#. type: Title ## +#: ../../guide/en/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "On scope" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 "" diff --git a/_translations/guide/po/es/views_view-injections.md.po b/_translations/guide/po/es/views_view-injections.md.po new file mode 100644 index 00000000..14be90eb --- /dev/null +++ b/_translations/guide/po/es/views_view-injections.md.po @@ -0,0 +1,189 @@ +# Spanish translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" +"PO-Revision-Date: 2025-09-04 11:19+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: Title ## +#: ../../guide/en/concept/configuration.md +#: ../../guide/en/tutorial/using-yii-with-roadrunner.md +#: ../../guide/en/views/view-injections.md +#, no-wrap +msgid "Configuration" +msgstr "" + +#. type: Title # +#: ../../guide/en/views/view-injections.md +#, no-wrap +msgid "View injections" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/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) +#: ../../guide/en/views/view-injections.md +#, no-wrap +msgid "composer require yiisoft/yii-view-renderer\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/views/view-injections.md +msgid "In config `params.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/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 ## +#: ../../guide/en/views/view-injections.md +#, no-wrap +msgid "New injections" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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) +#: ../../guide/en/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 +#: ../../guide/en/views/view-injections.md +msgid "Add your new Injection to `params.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/views/view-injections.md +#, no-wrap +msgid "" +"'yiisoft/yii-view' => [\n" +" 'injections' => [\n" +" ...,\n" +" Reference::to(MyCustomParametersInjection::class),\n" +" ],\n" +" ],\n" +msgstr "" + +#. type: Title ## +#: ../../guide/en/views/view-injections.md +#, no-wrap +msgid "Using Separate Injections for Different Layouts" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/views/view-injections.md +msgid "Create your custom ViewInjection for a specific layout:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/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 +#: ../../guide/en/views/view-injections.md +msgid "Add your new injection to `params.php` under specific layout name. In the following example, it is `@layout/cart`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/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 "" + +#. type: Plain text +#: ../../guide/en/views/view-injections.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> [← Template engines](template-engines.md) |\n" +"> [Scripts, styles and metatags →](script-style-meta.md)\n" +msgstr "" diff --git a/_translations/guide/po/id/README.md.po b/_translations/guide/po/id/README.md.po new file mode 100644 index 00000000..7a6602c0 --- /dev/null +++ b/_translations/guide/po/id/README.md.po @@ -0,0 +1,634 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" +"PO-Revision-Date: 2025-09-05 11:19+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.7\n" + +#. type: Title # +#: ../../guide/en/README.md +#, no-wrap +msgid "The definitive guide to Yii 3.0" +msgstr "Panduan Definitif untuk Yii 3.0" + +#. type: Plain text +#: ../../guide/en/README.md +msgid "We release this guide under the [Terms of Yii Documentation](https://www.yiiframework.com/license#docs)." +msgstr "Panduan ini dirilis di bawah [Ketentuan Dokumentasi Yii](https://www.yiiframework.com/license#docs)." + +#. type: Plain text +#: ../../guide/en/README.md +msgid "Introduction +" +msgstr "Pengenalan +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[About Yii](intro/what-is-yii.md) +" +msgstr "[Tentang Yii](intro/what-is-yii.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Upgrading from version 2.0](intro/upgrade-from-v2.md) +" +msgstr "[Memutakhirkan dari versi 2.0](intro/upgrade-from-v2.md) +" + +#. type: Plain text +#: ../../guide/en/README.md +msgid "Getting started -" +msgstr "Mulai -" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[What do you need to know?](start/prerequisites.md) +" +msgstr "[Apa yang perlu kamu ketahui](start/prerequisites.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Creating a project](start/creating-project.md) +" +msgstr "[Membuat proyek](start/creating-project.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Running applications](start/workflow.md) +" +msgstr "[Menjalankan Aplikasi](start/workflow.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Saying hello](start/hello.md) +" +msgstr "[Mengucapkan halo](start/hello.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Working with forms](start/forms.md) +" +msgstr "[Bekerja Dengan Formulir](start/forms.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Working with databases](start/databases.md) !" +msgstr "[Bekerja Dengan Basis Data](start/databases.md) !" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Generating code with Gii](start/gii.md) -" +msgstr "[Menghasilkan Kode dengan Gii](start/gii.md) -" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Looking ahead](start/looking-ahead.md) +" +msgstr "[Melihat ke depan](start/looking-ahead.md) +" + +#. type: Plain text +#: ../../guide/en/README.md +msgid "Application structure +" +msgstr "Struktur Aplikasi +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Application structure overview](structure/overview.md) +" +msgstr "[Application Structure Overview](structure/overview.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Entry scripts](structure/entry-script.md) +" +msgstr "[Entry Scripts](structure/entry-script.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Application](structure/application.md) +" +msgstr "[Application](structure/application.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Service components](structure/service.md) +" +msgstr "[Service components](structure/service.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Actions](structure/action.md) +" +msgstr "[Actions](structure/action.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Domain](structure/domain.md) +" +msgstr "[Domain](structure/domain.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Middleware](structure/middleware.md) +" +msgstr "[Middleware](structure/middleware.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Packages](structure/package.md) +" +msgstr "[Packages](structure/package.md) +" + +#. type: Plain text +#: ../../guide/en/README.md +msgid "Key concepts +" +msgstr "Konsep Dasar -" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Class autoloading](concept/autoloading.md) +" +msgstr "[Class autoloading](concept/autoloading.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Dependency injection container](concept/di-container.md) +" +msgstr "[Dependency Injection Container](concept/di-container.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Configuration](concept/configuration.md) +" +msgstr "[Configuration](concept/configuration.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Aliases](concept/aliases.md) +" +msgstr "[Aliases](concept/aliases.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Events](concept/events.md) +" +msgstr "[Events](concept/events.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Immutability](concept/immutability.md) +" +msgstr "" + +#. type: Plain text +#: ../../guide/en/README.md +msgid "Handling requests +" +msgstr "Menangani Permintaan -" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Routing and URL generation](runtime/routing.md) +" +msgstr "[Routing and URL generation](runtime/routing.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Request](runtime/request.md) +" +msgstr "[Request](runtime/request.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Response](runtime/response.md) +" +msgstr "[Response](runtime/response.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Sessions](runtime/sessions.md) +" +msgstr "[Sessions](runtime/sessions.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Cookies](runtime/cookies.md) +" +msgstr "[Cookies](runtime/cookies.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Handling errors](runtime/handling-errors.md) +" +msgstr "[Handling errors](runtime/handling-errors.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Logging](runtime/logging.md) +" +msgstr "[Logging](runtime/logging.md) +" + +#. type: Plain text +#: ../../guide/en/README.md +msgid "Views -" +msgstr "Tampilan -" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Views](views/view.md) -" +msgstr "[Views](views/view.md) -" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Template engines](views/template-engines.md) -" +msgstr "[Template Engines](views/template-engines.md) -" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[View injections](views/view-injections.md) +" +msgstr "" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Scripts, styles and metatags](views/script-style-meta.md)" +msgstr "" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Assets](views/asset.md) -" +msgstr "[Assets](views/asset.md) -" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Widgets](views/widget.md) -" +msgstr "[Widgets](views/widget.md) -" + +#. type: Plain text +#: ../../guide/en/README.md +msgid "Working with databases +-" +msgstr "Bekerja Dengan Basis Data +-" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Database access objects](db-dao.md): Connecting to a database, basic queries, transactions, and schema manipulation" +msgstr "[Database Access Objects](db-dao.md): Menghubungkan ke basis data, permintaan dasar,transaksi, dan manipulasi skema" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Query builder](db-query-builder.md): Querying the database using a simple abstraction layer" +msgstr "[Query Builder](db-query-builder.md): Meminta basis data menggunakan lapisan abstraksi sederhana" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Active record](db-active-record.md): The Active Record ORM, retrieving and manipulating records, and defining relations" +msgstr "[Active Record](db-active-record.md): Active Record ORM, mengambil dan memanipulasi catatan, dan mendefinisikan hubungan" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Migrations](databases/db-migrations.md): +" +msgstr "[Migrations](db-migrations.md): +" + +#. type: Plain text +#: ../../guide/en/README.md +msgid "Getting data from users -" +msgstr "Mendapatkan Data dari Pengguna -" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Creating forms](input/forms.md) -" +msgstr "[Membuat Formulir](input/forms.md) -" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Validating input](https://github.com/yiisoft/validator/blob/master/docs/guide/en/README.md) +" +msgstr "[Memvalidasi Input](https://github.com/yiisoft/validator/blob/master/docs/guide/en/README.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Uploading files](input/file-upload.md) -" +msgstr "[Mengunggah File](input/file-upload.md) -" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Collecting tabular input](input/tabular-input.md) -" +msgstr "[Mengumpulkan Input Tabular](input/tabular-input.md) -" + +#. type: Plain text +#: ../../guide/en/README.md +msgid "Displaying data -" +msgstr "Menampilkan Data -" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Data formatting](output/formatting.md) -" +msgstr "[Data Formatting](output/formatting.md) -" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Pagination](output/pagination.md) -" +msgstr "[Pagination](output/pagination.md) -" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Sorting](output/sorting.md) -" +msgstr "[Sorting](output/sorting.md) -" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Data providers](output/data-providers.md) -" +msgstr "[Data Providers](output/data-providers.md) -" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Data widgets](output/data-widgets.md) -" +msgstr "[Data Widgets](output/data-widgets.md) -" + +#. type: Plain text +#: ../../guide/en/README.md +msgid "Security +-" +msgstr "Keamanan +-" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Security overview](security/overview.md) +" +msgstr "[Ikhtisar Overview](security/overview.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Authentication](security/authentication.md) +" +msgstr "[Autentikasi](security/authentication.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Authorization](security/authorization.md) +-" +msgstr "[Otorisasi](security/authorization.md) +-" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Working with passwords](security/passwords.md) +" +msgstr "[Bekerja dengan Kata Sandi](security/passwords.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Cryptography](security/cryptography.md) +" +msgstr "[Kriptografi](security/cryptography.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Best practices](security/best-practices.md) +" +msgstr "[Praktik terbaik](security/best-practices.md) +" + +#. type: Plain text +#: ../../guide/en/README.md +msgid "Caching +-" +msgstr "Caching +-" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Caching overview](caching/overview.md) +" +msgstr "[Ikhtisar Caching](caching/overview.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Data caching](caching/data.md) +" +msgstr "[Data Caching](caching/data.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Fragment caching](caching/fragment.md) -" +msgstr "[Fragment Caching](caching/fragment.md) -" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Page caching](caching/page.md) -" +msgstr "[Page Caching](caching/page.md) -" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[HTTP caching](caching/http.md) -" +msgstr "[HTTP caching](caching/http.md) -" + +#. type: Title - +#: ../../guide/en/README.md +#, no-wrap +msgid "REST APIs -" +msgstr "RESTful Web Services -" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Quick start](rest/quick-start.md)" +msgstr "[Mulai cepat](rest/quick-start.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Resources](rest/resources.md)" +msgstr "[Resources](rest/resources.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Controllers](rest/controllers.md)" +msgstr "[Controllers](rest/controllers.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Routing](rest/routing.md)" +msgstr "[Routing](rest/routing.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Authentication](rest/authentication.md)" +msgstr "[Authentication](rest/authentication.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Rate limiting](rest/rate-limiting.md)" +msgstr "[Rate Limiting](rest/rate-limiting.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Versioning](rest/versioning.md)" +msgstr "[Versioning](rest/versioning.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Error handling](rest/error-handling.md)" +msgstr "[Error Handling](rest/error-handling.md)" + +#. type: Plain text +#: ../../guide/en/README.md +msgid "Development tools -" +msgstr "Alat Pengembangan -" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "Debug toolbar and debugger" +msgstr "Debug Toolbar and Debugger" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "Generating code using Gii" +msgstr "Membuat Kode menggunakan Gii" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "Generating API documentation" +msgstr "Membuat Dokumentasi API" + +#. type: Plain text +#: ../../guide/en/README.md +msgid "Testing -" +msgstr "Pengujian -" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Testing overview](testing/overview.md)" +msgstr "[Ikhtisar Pengujian](testing/overview.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Testing environment setup](testing/environment-setup.md)" +msgstr "[Pengaturan lingkungan pengujian](testing/environment-setup.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Unit tests](testing/unit.md)" +msgstr "[Unit Tests](testing/unit.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Functional tests](testing/functional.md)" +msgstr "[Functional Tests](testing/functional.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Acceptance tests](testing/acceptance.md)" +msgstr "[Acceptance Tests](testing/acceptance.md)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Fixtures](testing/fixtures.md)" +msgstr "[Fixtures](testing/fixtures.md)" + +#. type: Plain text +#: ../../guide/en/README.md +msgid "Special topics -" +msgstr "Topik Khusus -" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Building application from scratch](tutorial/start-from-scratch.md) -" +msgstr "[Membangun Aplikasi dari Awal](tutorial/start-from-scratch.md) -" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Console applications](tutorial/console-applications.md) +" +msgstr "[Aplikasi Konsol](tutorial/console-applications.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Docker](tutorial/docker.md) -" +msgstr "[Docker](tutorial/docker.md) -" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Internationalization](tutorial/i18n.md) -" +msgstr "[Penginternasionalan](tutorial/i18n.md) -" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Mailing](tutorial/mailing.md) +" +msgstr "[Mailing](tutorial/mailing.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Performance tuning](tutorial/performance-tuning.md) +" +msgstr "[Penyesuaian Kinerja](tutorial/performance-tuning.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Using Yii with event loop](tutorial/using-with-event-loop.md) +" +msgstr "[Menggunakan Yii dengan event loop](tutorial/using-with-event-loop.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Using Yii with RoadRunner](tutorial/using-yii-with-roadrunner.md) +" +msgstr "[Menggunakan Yii dengan RoadRunner](tutorial/using-yii-with-roadrunner.md) +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Using Yii with Swoole](tutorial/using-yii-with-swoole.md) +" +msgstr "[Menggunakan Yii dengan Swoole](using-yii-with-swoole.md) +" + +#. type: Plain text +#: ../../guide/en/README.md +msgid "Widgets -" +msgstr "Widgets -" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[GridView](https://www.yiiframework.com/doc-2.0/yii-grid-gridview.html)" +msgstr "[GridView](https://www.yiiframework.com/doc-2.0/yii-grid-gridview.html)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[ListView](https://www.yiiframework.com/doc-2.0/yii-widgets-listview.html)" +msgstr "[ListView](https://www.yiiframework.com/doc-2.0/yii-widgets-listview.html)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[DetailView](https://www.yiiframework.com/doc-2.0/yii-widgets-detailview.html)" +msgstr "[DetailView](https://www.yiiframework.com/doc-2.0/yii-widgets-detailview.html)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[ActiveForm](https://www.yiiframework.com/doc-2.0/guide-input-forms.html#activerecord-based-forms-activeform)" +msgstr "[ActiveForm](https://www.yiiframework.com/doc-2.0/guide-input-forms.html#activerecord-based-forms-activeform)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Menu](https://www.yiiframework.com/doc-2.0/yii-widgets-menu.html)" +msgstr "[Menu](https://www.yiiframework.com/doc-2.0/yii-widgets-menu.html)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[LinkPager](https://www.yiiframework.com/doc-2.0/yii-widgets-linkpager.html)" +msgstr "[LinkPager](https://www.yiiframework.com/doc-2.0/yii-widgets-linkpager.html)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[LinkSorter](https://www.yiiframework.com/doc-2.0/yii-widgets-linksorter.html)" +msgstr "[LinkSorter](https://www.yiiframework.com/doc-2.0/yii-widgets-linksorter.html)" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Bootstrap widgets](https://www.yiiframework.com/extension/yiisoft/yii2-bootstrap/doc/guide)" +msgstr "[Bootstrap Widgets](https://www.yiiframework.com/extension/yiisoft/yii2-bootstrap/doc/guide)" + +#. type: Plain text +#: ../../guide/en/README.md +msgid "Helpers +" +msgstr "Helpers +" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Arrays](https://github.com/yiisoft/arrays/)" +msgstr "" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Files](https://github.com/yiisoft/files/)" +msgstr "" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Html](https://github.com/yiisoft/html/)" +msgstr "" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Json](https://github.com/yiisoft/json)" +msgstr "" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Network utilities](https://github.com/yiisoft/network-utilities/)" +msgstr "" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[VarDumper](https://github.com/yiisoft/var-dumper)" +msgstr "" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Strings](https://github.com/yiisoft/strings)" +msgstr "" + +#. type: Plain text +#: ../../guide/en/README.md +msgid "Extras +" +msgstr "Lainnya+" + +#. type: Bullet: '* ' +#: ../../guide/en/README.md +msgid "[Glossary](glossary.md)" +msgstr "[Glosarium](glossary.md)" diff --git a/_translations/guide/po/id/caching_data.md.po b/_translations/guide/po/id/caching_data.md.po new file mode 100644 index 00000000..5951b68a --- /dev/null +++ b/_translations/guide/po/id/caching_data.md.po @@ -0,0 +1,460 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" +"PO-Revision-Date: 2025-09-05 10:07+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.7\n" + +#. type: Title # +#: ../../guide/en/caching/data.md +#, no-wrap +msgid "Data caching" +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)." +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)." + +#. type: Plain text +#: ../../guide/en/caching/data.md +msgid "To use cache, install [yiisoft/cache](https://github.com/yiisoft/cache) package:" +msgstr "Untuk menggunakan cache, pasang paket [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 "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 "" +"Kode berikut adalah pola penggunaan umum caching data, di mana `$cache` merujuk ke\n" +"instance `Cache` dari paket tersebut:" + +#. type: Fenced code block (php) +#: ../../guide/en/caching/data.md +#, fuzzy, 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 cache, calculate it from scratch.\n" +#| " return getTopProductsFromDatabase($count);\n" +#| " }, 3600);\n" +#| " \n" +#| " return $data;\n" +#| "}\n" +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 "" +"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 cache, calculate it from scratch.\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 "" +"Ketika cache memiliki data yang terkait dengan `$key`, ia akan mengembalikan nilai yang di-cache.\n" +"Jika tidak, ia akan mengeksekusi fungsi anonim yang diberikan untuk menghitung nilai yang akan di-cache dan dikembalikan." + +#. 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 "Jika fungsi anonim membutuhkan beberapa data dari scope luar, Anda dapat meneruskannya menggunakan pernyataan `use`." + +#. type: Title ## +#: ../../guide/en/caching/data.md +#, no-wrap +msgid "Cache handlers" +msgstr "Cache handlers" + +#. 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 "" +"Layanan cache menggunakan handler cache yang kompatibel dengan [PSR-16](https://www.php-fig.org/psr/psr-16/) yang merepresentasikan berbagai\n" +"penyimpanan cache, seperti memori, berkas, dan basis data." + +#. type: Plain text +#: ../../guide/en/caching/data.md +msgid "Yii provides the following handlers:" +msgstr "Yii menyediakan handler berikut:" + +#. 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 "" +"`NullCache` — placeholder cache yang tidak melakukan caching nyata. Tujuan handler ini adalah menyederhanakan\n" +" kode yang perlu memeriksa ketersediaan cache. Misalnya, selama pengembangan atau jika server tidak memiliki\n" +" dukungan cache, Anda dapat mengonfigurasi layanan cache untuk menggunakan handler ini.\n" +" Saat Anda mengaktifkan dukungan cache nyata, Anda dapat beralih menggunakan handler cache yang sesuai.\n" +" Pada kedua kasus, Anda dapat menggunakan kode yang sama tanpa pemeriksaan tambahan." + +#. type: Bullet: '- ' +#: ../../guide/en/caching/data.md +msgid "`ArrayCache` — provides caching for the current request only by storing the values in an array." +msgstr "`ArrayCache` — menyediakan caching hanya untuk permintaan saat ini dengan menyimpan nilai dalam sebuah 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 "" +"[APCu](https://github.com/yiisoft/cache-apcu) — menggunakan ekstensi PHP [APC](https://secure.php.net/manual/en/book.apc.php).\n" +" Ini bisa dianggap sebagai opsi tercepat saat berurusan dengan cache untuk aplikasi terpusat (mis., satu\n" +" server, tanpa load balancer khusus, dll.)." + +#. type: Bullet: '- ' +#: ../../guide/en/caching/data.md +msgid "[Database](https://github.com/yiisoft/cache-db) — uses a database table to store cached data." +msgstr "[Database](https://github.com/yiisoft/cache-db) — menggunakan tabel basis data untuk menyimpan data yang di-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 "" +"[File](https://github.com/yiisoft/cache-file) — menggunakan berkas standar untuk menyimpan data yang di-cache. Ini sangat cocok\n" +" untuk menyimpan potongan data besar, seperti konten halaman." + +#. type: Bullet: '- ' +#: ../../guide/en/caching/data.md +#, fuzzy +#| 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 distributed application (e.g., with several servers, load balancers, etc.)" +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 "" +"[Memcached](https://github.com/yiisoft/cache-memcached) — menggunakan ekstensi PHP [memcached](https://secure.php.net/manual/en/book.memcached.php).\n" +" Ini bisa dianggap sebagai opsi tercepat saat berurusan dengan cache di aplikasi terdistribusi\n" +" (mis., beberapa server, load balancer, dll.)" + +#. type: Plain text +#: ../../guide/en/caching/data.md +#, fuzzy, no-wrap +#| msgid "[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." +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 "" +"[Wincache](https://github.com/yiisoft/cache-wincache) — menggunakan ekstensi PHP [WinCache](https://iis.net/downloads/microsoft/wincache-extension)\n" +" ([lihat juga](https://secure.php.net/manual/en/book.wincache.php))." + +#. 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 "[Anda dapat menemukan lebih banyak handler di packagist.org](https://packagist.org/providers/psr/simple-cache-implementation)." + +#. 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 "" +"> [!TIP]\n" +"> Anda dapat menggunakan penyimpanan cache yang berbeda dalam aplikasi yang sama. Strategi umum adalah:\n" +"> - Gunakan penyimpanan cache berbasis memori untuk menyimpan data kecil tetapi sering digunakan (mis., statistik)\n" +"> - Gunakan penyimpanan cache berbasis berkas atau basis data untuk menyimpan data besar dan jarang digunakan (mis., konten halaman)\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 "" +"Handler cache biasanya disetel dalam [dependency injection container](../concept/di-container.md) sehingga dapat\n" +"dikonfigurasi dan diakses secara global." + +#. 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 "" +"Karena semua handler cache mendukung kumpulan API yang sama, Anda dapat menukar handler cache yang digunakan\n" +"dengan yang lain. Anda dapat melakukannya dengan mengonfigurasi ulang aplikasi tanpa mengubah kode yang menggunakan cache." + +#. type: Title ### +#: ../../guide/en/caching/data.md +#, no-wrap +msgid "Cache keys" +msgstr "Cache keys" + +#. 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 "" +"Sebuah kunci mengidentifikasi secara unik setiap item data yang disimpan di cache. Saat Anda menyimpan sebuah item data,\n" +"Anda harus menentukan kunci untuknya. Nantinya, ketika Anda mengambil item data tersebut, Anda perlu memberikan\n" +"kunci yang sesuai." + +#. 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 "" +"Anda dapat menggunakan string atau nilai arbitrer sebagai kunci cache. Ketika kunci bukan string, ia akan\n" +"diserialisasi menjadi string secara otomatis." + +#. 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 "Strategi umum dalam mendefinisikan kunci cache adalah menyertakan semua faktor penentu dalam bentuk 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 "" +"Ketika aplikasi yang berbeda menggunakan penyimpanan cache yang sama, Anda harus menentukan prefiks kunci cache yang unik\n" +"untuk setiap aplikasi guna menghindari konflik kunci cache.\n" +"Anda dapat melakukannya dengan menggunakan dekorator `\\Yiisoft\\Cache\\PrefixedCache`:" + +#. 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 "" +"$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 "Cache expiration" + +#. 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 "" +"Item data yang disimpan di cache akan tetap di sana selamanya kecuali dihapus karena beberapa kebijakan\n" +"caching. Misalnya, ruang cache penuh dan penyimpanan cache menghapus data tertua.\n" +"Untuk mengubah perilaku ini, Anda dapat menyetel parameter TTL saat memanggil metode untuk menyimpan item data:" + +#. 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 "" +"$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 "" +"Parameter `$ttl` menunjukkan berapa detik item data dapat tetap valid di cache. Ketika Anda mengambil\n" +"item data tersebut, jika waktu kedaluwarsanya telah lewat, metode akan mengeksekusi fungsi dan menyetel nilai yang dihasilkan\n" +"ke dalam cache." + +#. type: Plain text +#: ../../guide/en/caching/data.md +#, fuzzy +#| msgid "You may set default TTL for the cache:" +msgid "You may set the default TTL for the cache:" +msgstr "Anda dapat menyetel TTL bawaan untuk 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 "$cache = new \\Yiisoft\\Cache\\Cache($arrayCache, 60 * 60); // 1 hour\n" + +#. type: Plain text +#: ../../guide/en/caching/data.md +msgid "Additionally, you can invalidate a cache key explicitly:" +msgstr "Selain itu, Anda dapat menginvalidasi kunci cache secara eksplisit:" + +#. type: Fenced code block (php) +#: ../../guide/en/caching/data.md +#, no-wrap +msgid "$cache->remove($key);\n" +msgstr "$cache->remove($key);\n" + +#. type: Title ### +#: ../../guide/en/caching/data.md +#, no-wrap +msgid "Invalidation dependencies" +msgstr "Invalidation dependencies" + +#. 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 "" +"Selain pengaturan kedaluwarsa, perubahan pada yang disebut sebagai **ketergantungan invalidasi** juga dapat menginvalidasi item data yang di-cache.\n" +"Misalnya, `\\Yiisoft\\Cache\\Dependency\\FileDependency` merepresentasikan ketergantungan pada waktu modifikasi sebuah berkas.\n" +"Ketika ketergantungan ini berubah, itu berarti ada sesuatu yang memodifikasi berkas terkait.\n" +"Akibatnya, konten berkas yang usang yang ditemukan di cache harus diinvalidasi." + +#. 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 "" +"Ketergantungan cache adalah objek dari kelas turunan `\\Yiisoft\\Cache\\Dependency\\Dependency`. Ketika Anda\n" +"menyimpan sebuah item data ke cache, Anda dapat menyertakan objek ketergantungan cache terkait. Contohnya," + +#. 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 "" +"/**\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" + +#. type: Plain text +#: ../../guide/en/caching/data.md +msgid "Below is a summary of the available cache dependencies:" +msgstr "Berikut ringkasan ketergantungan cache yang tersedia:" + +#. type: Bullet: '- ' +#: ../../guide/en/caching/data.md +msgid "`\\Yiisoft\\Cache\\Dependency\\ValueDependency`: invalidates the cache when specified value changes." +msgstr "`\\Yiisoft\\Cache\\Dependency\\ValueDependency`: menginvalidasi cache ketika nilai yang ditentukan berubah." + +#. 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 "" +"`\\Yiisoft\\Cache\\Dependency\\CallbackDependency`: menginvalidasi cache ketika hasil dari callback PHP yang ditentukan\n" +" berbeda." + +#. 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 "`\\Yiisoft\\Cache\\Dependency\\FileDependency`: menginvalidasi cache ketika waktu modifikasi terakhir berkas berbeda." + +#. 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 "" +"`\\Yiisoft\\Cache\\Dependency\\TagDependency`: mengaitkan item data yang di-cache dengan satu atau banyak tag. Anda dapat menginvalidasi\n" +" item data yang di-cache dengan tag tertentu dengan memanggil `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 "Anda dapat mengombinasikan banyak ketergantungan menggunakan `\\Yiisoft\\Cache\\Dependency\\AnyDependency` atau `\\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 "Untuk mengimplementasikan ketergantungan Anda sendiri, turunkan dari `\\Yiisoft\\Cache\\Dependency\\Dependency`." + +#. type: Title ### +#: ../../guide/en/caching/data.md +#, no-wrap +msgid "Cache stampede prevention" +msgstr "Cache stampede prevention" + +#. 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 "" +"[Cache stampede](https://en.wikipedia.org/wiki/Cache_stampede) adalah jenis kegagalan berantai yang dapat terjadi ketika sistem komputasi paralel masif\n" +"dengan mekanisme cache berada di bawah beban tinggi.\n" +"Perilaku ini terkadang juga disebut dog-piling." + +#. type: Plain text +#: ../../guide/en/caching/data.md +#, fuzzy +#| 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." +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 "" +"`\\Yiisoft\\Cache\\Cache` menggunakan algoritma bawaan \"Probably early expiration\" yang mencegah cache stampede.\n" +"Algoritma ini secara acak memalsukan cache miss untuk satu pengguna sementara yang lain masih dilayani nilai dari cache.\n" +"Anda dapat mengontrol perilakunya dengan parameter opsional kelima dari `getOrSet()`, yaitu nilai float bernama `$beta`.\n" +"Secara bawaan, beta adalah `1.0`, yang biasanya sudah cukup.\n" +"Semakin tinggi nilainya, semakin awal cache akan dibuat ulang." + +#. 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 "" +"/**\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/guide/po/id/caching_overview.md.po b/_translations/guide/po/id/caching_overview.md.po new file mode 100644 index 00000000..e984ef94 --- /dev/null +++ b/_translations/guide/po/id/caching_overview.md.po @@ -0,0 +1,66 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2025-09-04 11:19+0500\n" +"PO-Revision-Date: 2025-09-05 10:35+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.7\n" + +#. type: Title # +#: en/caching/overview.md +#, no-wrap +msgid "Caching" +msgstr "Caching" + +#. type: Plain text +#: en/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 "" +"Caching adalah cara yang murah dan efektif untuk meningkatkan performa aplikasi.\n" +"Dengan menyimpan data yang relatif statis di cache dan menyajikannya dari cache saat diminta,\n" +"aplikasi menghemat waktu yang sebaliknya diperlukan untuk menghasilkan data dari awal setiap kali." + +#. type: Plain text +#: en/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 "" +"Caching dapat terjadi pada berbagai level dan lokasi dalam sebuah aplikasi. Di sisi server, pada level rendah,\n" +"cache dapat digunakan untuk menyimpan data dasar, seperti daftar artikel terbaru yang diambil dari basis data;\n" +"dan pada level yang lebih tinggi, cache dapat digunakan untuk menyimpan fragmen atau seluruh halaman web, seperti hasil rendering\n" +"artikel terbaru. Di sisi klien, Anda dapat menggunakan HTTP caching untuk menyimpan konten halaman yang terakhir dikunjungi\n" +"di cache browser." + +#. type: Plain text +#: en/caching/overview.md +msgid "Yii supports all these caching mechanisms:" +msgstr "Yii mendukung semua mekanisme caching berikut:" + +#. type: Bullet: '* ' +#: en/caching/overview.md +msgid "[Data caching](data.md)" +msgstr "[Data caching](data.md)" + +#. type: Bullet: '* ' +#: en/caching/overview.md +msgid "[Fragment caching](fragment.md)" +msgstr "[Fragment caching](fragment.md)" + +#. type: Bullet: '* ' +#: en/caching/overview.md +msgid "[Page caching](page.md)" +msgstr "[Page caching](page.md)" + +#. type: Bullet: '* ' +#: en/caching/overview.md +msgid "[HTTP caching](http.md)" +msgstr "[HTTP caching](http.md)" diff --git a/_translations/guide/po/id/concept_aliases.md.po b/_translations/guide/po/id/concept_aliases.md.po new file mode 100644 index 00000000..90c65864 --- /dev/null +++ b/_translations/guide/po/id/concept_aliases.md.po @@ -0,0 +1,348 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2025-09-03 17:50+0500\n" +"PO-Revision-Date: 2025-09-05 10:48+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.7\n" + +#. type: Title # +#: en/concept/aliases.md +#, no-wrap +msgid "Aliases" +msgstr "Aliases" + +#. type: Plain text +#: en/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 "" +"Anda dapat menggunakan alias untuk merepresentasikan path file atau URL sehingga Anda tidak perlu menulis path absolut atau URL secara hard-code di\n" +"proyek Anda. Sebuah alias harus diawali karakter `@` agar dapat dibedakan dari path file dan URL biasa. Alias yang\n" +"didefinisikan tanpa `@` di awal akan diprefiks otomatis dengan karakter `@`." + +#. type: Plain text +#: en/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 "" +"Aplikasi Yii bawaan memiliki beberapa alias yang sudah didefinisikan di `config/params.php`. Misalnya, alias `@public` merepresentasikan\n" +"path web root; `@baseUrl` merepresentasikan URL dasar untuk aplikasi Web yang sedang berjalan." + +#. type: Title ## +#: en/concept/aliases.md +#, no-wrap +msgid "Defining aliases " +msgstr "Defining aliases " + +#. type: Plain text +#: en/concept/aliases.md +msgid "You can define an alias via application's `config/params.php`:" +msgstr "Anda dapat mendefinisikan sebuah alias melalui `config/params.php` aplikasi:" + +#. type: Fenced code block (php) +#: en/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 "" +"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" + +#. type: Plain text +#: en/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 "" +"> [!NOTE]\n" +"> Path file atau URL yang dialias tidak harus selalu merujuk pada file atau sumber daya yang benar-benar ada.\n" + +#. type: Plain text +#: en/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 "" +"Dengan alias yang telah didefinisikan, Anda dapat menurunkan alias baru dengan menambahkan garis miring `/` diikuti satu atau beberapa segmen path.\n" +"Sebagai contoh, `@foo` adalah alias akar (root), sedangkan `@foo/bar/file.php` adalah alias turunan." + +#. type: Plain text +#: en/concept/aliases.md +msgid "You can define an alias using another alias (either root or derived):" +msgstr "Anda dapat mendefinisikan sebuah alias menggunakan alias lain (baik alias akar maupun turunan):" + +#. type: Fenced code block (php) +#: en/concept/aliases.md +#, no-wrap +msgid "'@foobar' => '@foo/bar', \n" +msgstr "'@foobar' => '@foo/bar',\n" + +#. type: Plain text +#: en/concept/aliases.md +msgid "The `yiisoft/aliases` parameter initializes `Aliases` service from [`yiisoft/aliases` package](https://github.com/yiisoft/aliases). You can set extra aliases in runtime by using the service:" +msgstr "" +"Parameter `yiisoft/aliases` menginisialisasi layanan `Aliases` dari [paket `yiisoft/aliases`](https://github.com/yiisoft/aliases).\n" +"Anda dapat menyetel alias tambahan saat runtime menggunakan layanan tersebut:" + +#. type: Fenced code block (php) +#: en/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 "" +"use \\Yiisoft\\Aliases\\Aliases;\n" +"\n" +"public function actionIndex(Aliases $aliases)\n" +"{\n" +" $aliases->set('@uploads', '@root/uploads');\n" +"}\n" + +#. type: Title ## +#: en/concept/aliases.md +#, no-wrap +msgid "Using aliases in configuration " +msgstr "Menggunakan aliases di konfigurasi " + +#. type: Plain text +#: en/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 "Disarankan untuk me-resolve alias pada level konfigurasi, sehingga service menerima URL dan path sebagai string siap pakai:" + +#. type: Fenced code block (php) +#: en/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 "" +" static fn (Aliases $aliases) => new FileCache(\n" +" $aliases->get($params['yiisoft/cache-file']['fileCache']['path'])\n" +" ),\n" +"];\n" + +#. type: Title ## +#: en/concept/aliases.md +#, no-wrap +msgid "Resolving aliases " +msgstr "Me-resolve alias " + +#. type: Plain text +#: en/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 "Anda dapat menggunakan layanan `Aliases`:" + +#. type: Fenced code block (php) +#: en/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 "" +"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 +#: en/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 "" +"Path/URL yang direpresentasikan oleh alias turunan ditentukan dengan mengganti bagian alias akar dengan path/URL yang sesuai\n" +"pada alias turunan tersebut." + +#. type: Plain text +#: en/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 "" +"> [!NOTE]\n" +"> Metode `get()` tidak memeriksa apakah path/URL hasilnya merujuk pada file atau sumber daya yang ada.\n" + +#. type: Plain text +#: en/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 "" +"Alias akar juga dapat berisi karakter garis miring `/`. Metode `get()` cukup cerdas untuk menentukan bagian mana\n" +"dari sebuah alias yang merupakan alias akar, sehingga dapat menentukan path file atau URL yang sesuai dengan benar:" + +#. type: Fenced code block (php) +#: en/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 "" +"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 +#: en/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 "Jika `@foo/bar` tidak didefinisikan sebagai alias akar, pernyataan terakhir akan menghasilkan `/path/to/foo/bar/file.php`." + +#. type: Title ## +#: en/concept/aliases.md +#, no-wrap +msgid "Predefined aliases " +msgstr "Alias bawaan " + +#. type: Plain text +#: en/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 "[Aplikasi Yii](https://github.com/yiisoft/app) mendefinisikan serangkaian alias untuk mereferensikan path file dan URL yang umum digunakan:" + +#. type: Bullet: '- ' +#: en/concept/aliases.md +msgid "`@root` - the base directory of the currently running application." +msgstr "`@root` - direktori dasar dari aplikasi yang sedang berjalan." + +#. type: Bullet: '- ' +#: en/concept/aliases.md +msgid "`@assets` - application's public directory where it publishes assets." +msgstr "`@assets` - direktori publik aplikasi tempat aset dipublikasikan." + +#. type: Bullet: '- ' +#: en/concept/aliases.md +msgid "`@assetsUrl` - URL of base directory with published assets." +msgstr "`@assetsUrl` - URL direktori dasar tempat aset dipublikasikan." + +#. type: Bullet: '- ' +#: en/concept/aliases.md +msgid "`@baseUrl` - the base URL of the currently running Web application. Defaults to `/`." +msgstr "`@baseUrl` - URL dasar aplikasi Web yang sedang berjalan. Bawaannya `/`." + +#. type: Bullet: '- ' +#: en/concept/aliases.md +msgid "`@npm` - node packages directory." +msgstr "`@npm` - direktori paket Node." + +#. type: Bullet: '- ' +#: en/concept/aliases.md +msgid "`@bower` - bower packages directory." +msgstr "`@bower` - direktori paket bower." + +#. type: Bullet: '- ' +#: en/concept/aliases.md +msgid "`@vendor` - Composer's `vendor` directory." +msgstr "`@vendor` - direktori `vendor` milik Composer." + +#. type: Bullet: '- ' +#: en/concept/aliases.md +msgid "`@public` - application's publicly accessible directory that with `index.php`." +msgstr "`@public` - direktori publik aplikasi yang berisi `index.php`." + +#. type: Bullet: '- ' +#: en/concept/aliases.md +msgid "`@runtime` - the runtime path of the currently running application. Defaults to `@root/runtime`." +msgstr "`@runtime` - path runtime aplikasi yang sedang berjalan. Bawaannya `@root/runtime`." + +#. type: Bullet: '- ' +#: en/concept/aliases.md +msgid "`@layout` - the directory with layouts." +msgstr "`@layout` - direktori berkas layout." + +#. type: Bullet: '- ' +#: en/concept/aliases.md +msgid "`@resources` - directory with views, asset sources and other resources." +msgstr "`@resources` - direktori yang berisi view, sumber aset, dan sumber daya lainnya." + +#. type: Bullet: '- ' +#: en/concept/aliases.md +msgid "`@views` - application view templates base directory." +msgstr "`@views` - direktori dasar template view aplikasi." diff --git a/_translations/guide/po/id/concept_autoloading.md.po b/_translations/guide/po/id/concept_autoloading.md.po new file mode 100644 index 00000000..75bf77f2 --- /dev/null +++ b/_translations/guide/po/id/concept_autoloading.md.po @@ -0,0 +1,90 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2025-09-04 07:25+0500\n" +"PO-Revision-Date: 2025-09-05 10:51+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.7\n" + +#. type: Title # +#: en/concept/autoloading.md +#, no-wrap +msgid "Class autoloading" +msgstr "Class autoloading" + +#. type: Plain text +#: en/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 "" +"Karena Yii menggunakan [Composer](https://getcomposer.org) untuk mengelola paket, Yii secara otomatis memuat kelas dari paket-paket tersebut\n" +"tanpa perlu melakukan `require` file-nya secara eksplisit.\n" +"Saat Composer memasang paket, ia menghasilkan sebuah [autoloader yang kompatibel PSR-4](https://www.php-fig.org/psr/psr-4/).\n" +"Untuk menggunakannya, lakukan `require_once` terhadap autoloader `/vendor/autoload.php` di file entry point `index.php` Anda." + +#. type: Plain text +#: en/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 "" +"Anda dapat menggunakan autoloader tidak hanya untuk paket yang diinstal, tetapi juga untuk aplikasi Anda sendiri karena aplikasi Anda juga merupakan sebuah paket.\n" +"Untuk memuat kelas-kelas dari namespace tertentu, tambahkan berikut ini ke `composer.json`:" + +#. type: Fenced code block (json) +#: en/concept/autoloading.md +#, no-wrap +msgid "" +"{\n" +" \"autoload\": {\n" +" \"psr-4\": {\n" +" \"App\\\\\": \"src/\"\n" +" }\n" +" }\n" +"}\n" +msgstr "" +"{\n" +" \"autoload\": {\n" +" \"psr-4\": {\n" +" \"App\\\\\": \"src/\"\n" +" }\n" +" }\n" +"}\n" + +#. type: Plain text +#: en/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 "" +"Di mana `App\\\\` adalah namespace akar dan `src/` adalah direktori tempat kelas-kelas Anda berada. Anda dapat menambahkan lebih banyak sumber (source roots) jika\n" +"diperlukan. Setelah selesai, jalankan `composer dump-autoload` atau cukup `composer du` dan kelas-kelas dari namespace terkait\n" +"akan mulai dimuat secara otomatis." + +#. type: Plain text +#: en/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 "" +"Jika Anda membutuhkan autoloading khusus lingkungan pengembangan yang tidak digunakan saat menjalankan Composer dengan flag `--no-dev`,\n" +"tambahkan ke bagian `autoload-dev` alih-alih `autoload`." + +#. type: Title ## +#: en/concept/autoloading.md +#, no-wrap +msgid "References" +msgstr "Referensi" + +#. type: Bullet: '- ' +#: en/concept/autoloading.md +msgid "[PSR-4: Autoloader](https://www.php-fig.org/psr/psr-4/)." +msgstr "[PSR-4: Autoloader](https://www.php-fig.org/psr/psr-4/)." + +#. type: Bullet: '- ' +#: en/concept/autoloading.md +msgid "[Composer guide on autoloading](https://getcomposer.org/doc/01-basic-usage.md#autoloading)." +msgstr "[Panduan Composer tentang autoloading](https://getcomposer.org/doc/01-basic-usage.md#autoloading)." diff --git a/_translations/guide/po/id/concept_configuration.md.po b/_translations/guide/po/id/concept_configuration.md.po new file mode 100644 index 00000000..e668a218 --- /dev/null +++ b/_translations/guide/po/id/concept_configuration.md.po @@ -0,0 +1,506 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: en/concept/configuration.md en/tutorial/using-yii-with-roadrunner.md +#: en/views/view-injections.md +#, no-wrap +msgid "Configuration" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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/`." +msgstr "" + +#. type: Title ## +#: en/concept/configuration.md +#, no-wrap +msgid "Config plugin" +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "In the application template [yiisoft/config](https://github.com/yiisoft/config) is used. Since writing all application configurations from scratch is a tedious process, many packages offer default configs, and the plugin helps with copying these into the application." +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "To offer default configs, `composer.json` of the package has to have `config-plugin` section. When installing or updating packages with Composer, the plugin reads `config-plugin` sections for each dependency, copies files themselves to application `config/packages/` if they don't yet exist and writes a merge plan to `config/packages/merge_plan.php`. The merge plan defines how to merge the configs into a single big array ready to be passed to [DI container](di-container.md)." +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "Take a look at what's in the \"yiisoft/app\" `composer.json` by default:" +msgstr "" + +#. type: Fenced code block (json) +#: en/concept/configuration.md +#, no-wrap +msgid "" +"\"config-plugin-options\": {\n" +" \"output-directory\": \"config/packages\"\n" +"},\n" +"\"config-plugin\": {\n" +" \"common\": \"config/common/*.php\",\n" +" \"params\": [\n" +" \"config/params.php\",\n" +" \"?config/params-local.php\"\n" +" ],\n" +" \"web\": [\n" +" \"$common\",\n" +" \"config/web/*.php\"\n" +" ],\n" +" \"console\": [\n" +" \"$common\",\n" +" \"config/console/*.php\"\n" +" ],\n" +" \"events\": \"config/events.php\",\n" +" \"events-web\": [\n" +" \"$events\",\n" +" \"config/events-web.php\"\n" +" ],\n" +" \"events-console\": [\n" +" \"$events\",\n" +" \"config/events-console.php\"\n" +" ],\n" +" \"providers\": \"config/providers.php\",\n" +" \"providers-web\": [\n" +" \"$providers\",\n" +" \"config/providers-web.php\"\n" +" ],\n" +" \"providers-console\": [\n" +" \"$providers\",\n" +" \"config/providers-console.php\"\n" +" ],\n" +" \"routes\": \"config/routes.php\"\n" +"},\n" +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "There are many named configs defined. For each name, there is a configuration." +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "A string means that the plugin takes config as is and merges it with same-named configs from packages you require. That happens if these packages have `config-plugin` in their `composer.json`." +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "The array means that the plugin will merge many files in the order they're specified." +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "`?` at the beginning of the file path indicated that the file may be absent. In this case, it's skipped." +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "`$` at the beginning of the name means a reference to another named config." +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "`params` is a bit special because it's reserved for application parameters. These are automatically available as `$params` in all other configuration files." +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "You can learn more about config plugin features [from its documentation](https://github.com/yiisoft/config/blob/master/README.md)." +msgstr "" + +#. type: Title ## +#: en/concept/configuration.md +#, no-wrap +msgid "Config files" +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "Now, as you know how the plugin assembles configs, look at `config` directory:" +msgstr "" + +#. type: Fenced code block +#: en/concept/configuration.md +#, no-wrap +msgid "" +"common/\n" +" application-parameters.php\n" +" i18n.php\n" +" router.php\n" +"console/\n" +"packages/\n" +" yiisoft/\n" +" dist.lock\n" +" merge_plan.php\n" +"web/\n" +" application.php\n" +" psr17.php\n" +"events.php\n" +"events-console.php\n" +"events-web.php\n" +"params.php\n" +"providers.php\n" +"providers-console.php\n" +"providers-web.php\n" +"routes.php\n" +msgstr "" + +#. type: Title ### +#: en/concept/configuration.md +#, no-wrap +msgid "Container configuration" +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "The application consists of a set of services registered in a [dependency container](di-container.md). The config files that responsible for direct dependency container configuration are under `common/`, `console/` and `web/` directories. We use `web/` for config specific to web application and `console/` for config specific to console commands. Both web and console are sharing configuration under `common/`." +msgstr "" + +#. type: Fenced code block (php) +#: en/concept/configuration.md +#, no-wrap +msgid "" +" [\n" +" 'class' => ApplicationParameters::class,\n" +" 'charset()' => [$params['app']['charset']],\n" +" 'name()' => [$params['app']['name']],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "Config plugin passes special `$params` variable to all config files. The code passes its values to the service." +msgstr "" + +#. type: Plain text +#: en/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 +#: en/concept/configuration.md +msgid "For convenience, there is a naming convention for custom string keys:" +msgstr "" + +#. type: Bullet: '1. ' +#: en/concept/configuration.md +msgid "Prefix package name such as `yiisoft/cache-file/custom-definition`." +msgstr "" + +#. type: Bullet: '2. ' +#: en/concept/configuration.md +msgid "In case configuration are for the application itself, skip package prefix, such as `custom-definition`." +msgstr "" + +#. type: Title ### +#: en/concept/configuration.md +#, no-wrap +msgid "Service providers" +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "As an alternative to registering dependencies directly, you can use service providers. Basically, these are classes that given parameters are configuring and registering services within the container. Similar to three dependency configuration files described, there are three configs for specifying service providers: `providers-console.php` for console commands, `providers-web.php` for web application and `providers.php` for both:" +msgstr "" + +#. type: Fenced code block (php) +#: en/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' => [\n" +" 'class' => CacheProvider::class,\n" +" '__construct()' => [\n" +" $params['yiisoft/cache-file']['file-cache']['path'],\n" +" ],\n" +" ],\n" +" // ...\n" +msgstr "" + +#. type: Plain text +#: en/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. These classes could be either created in the project itself or provided by a package." +msgstr "" + +#. type: Plain text +#: en/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 +#: en/concept/configuration.md +msgid "Provider should implement a single method, `public function register(Container $container): void`. In this method you need to add a service to container using `set()` method. Below is a provider for a cache service:" +msgstr "" + +#. type: Fenced code block (php) +#: en/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\\Container;\n" +"use Yiisoft\\Di\\Support\\ServiceProvider;\n" +"\n" +"final readonly class CacheProvider extends ServiceProvider\n" +"{\n" +" public function __construct(\n" +" private string $cachePath = '@runtime/cache'\n" +" )\n" +" {\n" +" $this->cachePath = $cachePath;\n" +" }\n" +"\n" +" public function register(Container $container): void\n" +" {\n" +" $container->set(CacheInterface::class, function (ContainerInterface $container) {\n" +" $aliases = $container->get(Aliases::class);\n" +"\n" +" return new FileCache($aliases->get($this->cachePath));\n" +" });\n" +"\n" +" $container->set(YiiCacheInterface::class, Cache::class);\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ### +#: en/concept/configuration.md +#, no-wrap +msgid "Routes" +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "You can configure how web application responds to certain URLs in `config/routes.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: en/concept/configuration.md +#, no-wrap +msgid "" +"use App\\Controller\\SiteController;\n" +"use Yiisoft\\Router\\Route;\n" +"\n" +"return [\n" +" Route::get('/')->action([SiteController::class, 'index'])->name('site/index')\n" +"];\n" +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "Read more about it in [\"Routes\"](../runtime/routing.md)." +msgstr "" + +#. type: Title # +#: en/concept/configuration.md en/concept/events.md +#, no-wrap +msgid "Events" +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "Many services emit certain events that you can attach to. You could do that via three config files: `events-web.php` for web application events, `events-console.php` for console events and `events.php` for both. The configuration is an array where keys are event names and values are an array of handlers:" +msgstr "" + +#. type: Fenced code block (php) +#: en/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 definition of an invokable class may be here while your `$container->has('the definition)` \n" +" 'di-alias'\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "Read more about it in [\"Events\"](events.md)." +msgstr "" + +#. type: Title ### +#: en/concept/configuration.md +#, no-wrap +msgid "Parameters" +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "Parameters, `config/params.php` store configuration values that are used in other config files to configuring services and service providers." +msgstr "" + +#. type: Plain text +#: en/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 +#: en/concept/configuration.md +msgid "Default application `params.php` looks like the following:" +msgstr "" + +#. type: Fenced code block (php) +#: en/concept/configuration.md +#, no-wrap +msgid "" +" [\n" +" 'charset' => 'UTF-8',\n" +" 'locale' => 'en',\n" +" 'name' => 'My Project',\n" +" ],\n" +"\n" +" 'yiisoft/aliases' => [\n" +" 'aliases' => [\n" +" '@root' => dirname(__DIR__),\n" +" '@assets' => '@root/public/assets',\n" +" '@assetsUrl' => '/assets',\n" +" '@baseUrl' => '/',\n" +" '@message' => '@root/resources/message',\n" +" '@npm' => '@root/node_modules',\n" +" '@public' => '@root/public',\n" +" '@resources' => '@root/resources',\n" +" '@runtime' => '@root/runtime',\n" +" '@vendor' => '@root/vendor',\n" +" '@layout' => '@resources/views/layout',\n" +" '@views' => '@resources/views',\n" +" ],\n" +" ],\n" +"\n" +" 'yiisoft/yii-view' => [\n" +" 'injections' => [\n" +" Reference::to(ContentViewInjection::class),\n" +" Reference::to(CsrfViewInjection::class),\n" +" Reference::to(LayoutViewInjection::class),\n" +" ],\n" +" ],\n" +"\n" +" 'yiisoft/yii-console' => [\n" +" 'commands' => [\n" +" 'hello' => Hello::class,\n" +" ],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "For convenience, there is a naming convention about parameters:" +msgstr "" + +#. type: Bullet: '1. ' +#: en/concept/configuration.md +msgid "Group parameters package name such as `yiisoft/cache-file`." +msgstr "" + +#. type: Bullet: '2. ' +#: en/concept/configuration.md +msgid "In case parameters are for the application itself, as in `app`, skip package prefix." +msgstr "" + +#. type: Bullet: '3. ' +#: en/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. ' +#: en/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 ### +#: en/concept/configuration.md +#, no-wrap +msgid "Package configs" +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "Config plugin described copy default package configurations to `packages/` directory. Once copied you own the configs, so you can adjust these as you like. `yiisoft/` in the default template stands for package vendor. Since only `yiisoft` packages are in template, there's a single directory. `merge_plan.php` is used in runtime to get the order on how configs are merged. Note that for config keys there should be a single source of truth. One config can't override values of another config." +msgstr "" + +#. type: Plain text +#: en/concept/configuration.md +msgid "`dist.lock` is used by the plugin to keep track of changes and display diff between current config and example one." +msgstr "" diff --git a/_translations/guide/po/id/concept_di-container.md.po b/_translations/guide/po/id/concept_di-container.md.po new file mode 100644 index 00000000..92b2921f --- /dev/null +++ b/_translations/guide/po/id/concept_di-container.md.po @@ -0,0 +1,374 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" +"PO-Revision-Date: 2025-09-04 07:37+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../../guide/en/concept/di-container.md +#, no-wrap +msgid "Dependency injection and container" +msgstr "" + +#. type: Title ## +#: ../../guide/en/concept/di-container.md +#, no-wrap +msgid "Dependency injection " +msgstr "" + +#. type: Plain text +#: ../../guide/en/concept/di-container.md +msgid "There are two ways of re-using things in OOP: inheritance and composition." +msgstr "" + +#. type: Plain text +#: ../../guide/en/concept/di-container.md +msgid "Inheritance is simple:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/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 +#: ../../guide/en/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 +#: ../../guide/en/concept/di-container.md +msgid "Another way to handle this is composition:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/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 +#: ../../guide/en/concept/di-container.md +msgid "We've avoided unnecessary inheritance and used interface to reduce coupling. You can replace cache implementation without changing `CachedWidget` so it's becoming more stable." +msgstr "" + +#. type: Plain text +#: ../../guide/en/concept/di-container.md +msgid "The `CacheInterface` here is a dependency: an object another object depends on. The process of putting an instance of dependency into an object (`CachedWidget`) is called dependency injection. There are many ways to perform it:" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/concept/di-container.md +msgid "Constructor injection. Best for mandatory dependencies." +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/concept/di-container.md +msgid "Method injection. Best for optional dependencies." +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/concept/di-container.md +msgid "Property injection. Better to be avoided in PHP except maybe data transfer objects." +msgstr "" + +#. type: Title ### +#: ../../guide/en/concept/di-container.md +#, no-wrap +msgid "Why use private properties " +msgstr "" + +#. type: Plain text +#: ../../guide/en/concept/di-container.md +msgid "In the composition example above, note that the `$cache` property is declared as `private`." +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/concept/di-container.md +msgid "This design choice provides several benefits:" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/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: '- ' +#: ../../guide/en/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: '- ' +#: ../../guide/en/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: '- ' +#: ../../guide/en/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 ## +#: ../../guide/en/concept/di-container.md +#, no-wrap +msgid "DI container " +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/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 +#: ../../guide/en/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: '- ' +#: ../../guide/en/concept/di-container.md +msgid "Define how to instantiate such an API wrapper." +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/concept/di-container.md +msgid "Instantiate it when required and only once per request." +msgstr "" + +#. type: Plain text +#: ../../guide/en/concept/di-container.md +msgid "That's what dependency containers are for." +msgstr "" + +#. type: Plain text +#: ../../guide/en/concept/di-container.md +msgid "A dependency injection (DI) container is an object that knows how to instantiate and configure objects and all their dependent objects. [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." +msgstr "" + +#. type: Plain text +#: ../../guide/en/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: Title ### +#: ../../guide/en/concept/di-container.md +#, no-wrap +msgid "Configuring container " +msgstr "" + +#. type: Plain text +#: ../../guide/en/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) +#: ../../guide/en/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 +#: ../../guide/en/concept/di-container.md +msgid "configuration could be:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/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 +#: ../../guide/en/concept/di-container.md +msgid "That's equal to the following:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/concept/di-container.md +#, no-wrap +msgid "" +"$myService = new MyService(42);\n" +"$myService->setDiscount(10);\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/concept/di-container.md +msgid "There are extra methods of declaring dependencies:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/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" +" // array definition (same as above)\n" +" 'full_definition' => [\n" +" 'class' => EngineMarkOne::class,\n" +" '__construct()' => [42], \n" +" '$propertyName' => 'value',\n" +" 'setX()' => [42],\n" +" ],\n" +"\n" +" // closure\n" +" 'closure' => static function(ContainerInterface $container) {\n" +" return new MyClass($container->get('db'));\n" +" },\n" +"\n" +" // static call\n" +" 'static_call' => [MyFactory::class, 'create'],\n" +"\n" +" // instance of an object\n" +" 'object' => new MyClass(),\n" +"];\n" +msgstr "" + +#. type: Title ### +#: ../../guide/en/concept/di-container.md +#, no-wrap +msgid "Injecting dependencies " +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/concept/di-container.md +msgid "This is primarily done in constructor and handing method of action handlers:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/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 +#: ../../guide/en/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: Title ## +#: ../../guide/en/concept/di-container.md +#, no-wrap +msgid "References " +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/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/guide/po/id/concept_events.md.po b/_translations/guide/po/id/concept_events.md.po new file mode 100644 index 00000000..65836ca2 --- /dev/null +++ b/_translations/guide/po/id/concept_events.md.po @@ -0,0 +1,253 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: en/concept/configuration.md en/concept/events.md +#, no-wrap +msgid "Events" +msgstr "" + +#. type: Plain text +#: en/concept/events.md +msgid "Events allow you to make custom code executed at certain execution points without modifying existing code. You can attach a custom code called \"handler\" to an event so that when the event is triggered, the handler gets executed automatically." +msgstr "" + +#. type: Plain text +#: en/concept/events.md +msgid "For example, when a user is signed up, you need to send a welcome email. You can do it right in the `SignupService` but then, when you additionally need to resize user's avatar image, you'll have to change `SignupService` code again. In other words, `SignupService` will be coupled to both code sending welcome email and code resizing avatar image." +msgstr "" + +#. type: Plain text +#: en/concept/events.md +#, no-wrap +msgid "" +"To avoid it, instead of telling what do after signup explicitly you can, instead, raise `UserSignedUp` event\n" +"and then finish a signup process. The code sending an email and the code resizing avatar image will attach to the event\n" +" and, therefore, will be executed. If you'll ever need to do more on signup, you'll be able to attach extra event\n" +"handlers without modifying `SignupService`. \n" +msgstr "" + +#. type: Plain text +#: en/concept/events.md +msgid "For raising events and attaching handlers to these events, Yii has a special service called event dispatcher. It's available from [yiisoft/event-dispatcher package](https://github.com/yiisoft/event-dispatcher)." +msgstr "" + +#. type: Title ## +#: en/concept/events.md +#, no-wrap +msgid "Event Handlers " +msgstr "" + +#. type: Plain text +#: en/concept/events.md +msgid "An event handler is [PHP callable](https://www.php.net/manual/en/language.types.callable.php) that gets executed when the event it's attached to is triggered." +msgstr "" + +#. type: Plain text +#: en/concept/events.md +msgid "The signature of an event handler is:" +msgstr "" + +#. type: Fenced code block (php) +#: en/concept/events.md +#, no-wrap +msgid "" +"function (EventClass $event) {\n" +" // handle it\n" +"}\n" +msgstr "" + +#. type: Title ## +#: en/concept/events.md +#, no-wrap +msgid "Attaching event handlers " +msgstr "" + +#. type: Plain text +#: en/concept/events.md +msgid "You can attach a handler to an event like the following:" +msgstr "" + +#. type: Fenced code block (php) +#: en/concept/events.md +#, no-wrap +msgid "" +"use Yiisoft\\EventDispatcher\\Provider\\Provider;\n" +"\n" +"final readonly class WelcomeEmailSender\n" +"{\n" +" public function __construct(Provider $provider)\n" +" {\n" +" $provider->attach([$this, 'handleUserSignup']);\n" +" }\n" +"\n" +" public function handleUserSignup(UserSignedUp $event)\n" +" {\n" +" // handle it \n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: en/concept/events.md +msgid "The `attach()` method is accepting a callback. Based on the type of this callback argument, the event type is determined." +msgstr "" + +#. type: Title ## +#: en/concept/events.md +#, no-wrap +msgid "Event handlers order" +msgstr "" + +#. type: Plain text +#: en/concept/events.md +msgid "You may attach one or more handlers to a single event. When an event is triggered, the attached handlers will be called in the order that they were attached to the event. In case an event implements `Psr\\EventDispatcher\\StoppableEventInterface`, event handler can stop executing the rest of the handlers that follow it if `isPropagationStopped()` returns `true`." +msgstr "" + +#. type: Plain text +#: en/concept/events.md +msgid "In general, it's better not to rely on the order of event handlers." +msgstr "" + +#. type: Title ## +#: en/concept/events.md +#, no-wrap +msgid "Raising events " +msgstr "" + +#. type: Plain text +#: en/concept/events.md +msgid "Events are raised like the following:" +msgstr "" + +#. type: Fenced code block (php) +#: en/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" +" }\n" +"\n" +" public function signup(SignupForm $form)\n" +" {\n" +" // handle signup\n" +"\n" +" $event = new UserSignedUp($form);\n" +" $this->eventDispatcher->dispatch($event);\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: en/concept/events.md +msgid "First, you create an event supplying it with data that may be useful for handlers. Then you dispatch the event." +msgstr "" + +#. type: Plain text +#: en/concept/events.md +msgid "The event class itself may look like the following:" +msgstr "" + +#. type: Fenced code block (php) +#: en/concept/events.md +#, no-wrap +msgid "" +"final readonly class UserSignedUp\n" +"{\n" +" public function __construct(\n" +" public SignupForm $form\n" +" )\n" +" {\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ## +#: en/concept/events.md +#, no-wrap +msgid "Events hierarchy" +msgstr "" + +#. type: Plain text +#: en/concept/events.md +msgid "Events don't have any name or wildcard matching on purpose. Event class names and class/interface hierarchy and composition could be used to achieve great flexibility:" +msgstr "" + +#. type: Fenced code block (php) +#: en/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 +#: en/concept/events.md +msgid "With the interface, you can listen to all document-related events:" +msgstr "" + +#. type: Fenced code block (php) +#: en/concept/events.md +#, no-wrap +msgid "" +"$provider->attach(function (DocumentEvent $event) {\n" +" // log events here\n" +"});\n" +msgstr "" + +#. type: Title ## +#: en/concept/events.md +#, no-wrap +msgid "Detaching event handlers " +msgstr "" + +#. type: Plain text +#: en/concept/events.md +msgid "To detach a handler from an event you can call `detach()` method:" +msgstr "" + +#. type: Fenced code block (php) +#: en/concept/events.md +#, no-wrap +msgid "$provider->detach(DocmentEvent::class);\n" +msgstr "" + +#. type: Title ## +#: en/concept/events.md +#, no-wrap +msgid "Configuring application events" +msgstr "" + +#. type: Plain text +#: en/concept/events.md +msgid "You usually assign event handlers via application config. See [\"Configuration\"](configuration.md) for details." +msgstr "" diff --git a/_translations/guide/po/id/concept_immutability.md.po b/_translations/guide/po/id/concept_immutability.md.po new file mode 100644 index 00000000..b564db51 --- /dev/null +++ b/_translations/guide/po/id/concept_immutability.md.po @@ -0,0 +1,223 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" +"PO-Revision-Date: 2025-09-04 11:19+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../../guide/en/concept/immutability.md +#, no-wrap +msgid "Immutability" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 ## +#: ../../guide/en/concept/immutability.md +#, no-wrap +msgid "Mutable pitfalls (what we avoid)" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/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 ## +#: ../../guide/en/concept/immutability.md +#, no-wrap +msgid "Creating an immutable object in PHP" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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) +#: ../../guide/en/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: '- ' +#: ../../guide/en/concept/immutability.md +msgid "We mark the class `final` to prevent subclass mutations; alternatively, design for extension carefully." +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/concept/immutability.md +msgid "Validate in the constructor and `with*` methods so every instance is always valid." +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 ## +#: ../../guide/en/concept/immutability.md +#, no-wrap +msgid "Using clone (and why it is inexpensive)" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/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) +#: ../../guide/en/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 ## +#: ../../guide/en/concept/immutability.md +#, no-wrap +msgid "Usage style" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/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: '- ' +#: ../../guide/en/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 +#: ../../guide/en/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/guide/po/id/databases_db-migrations.md.po b/_translations/guide/po/id/databases_db-migrations.md.po new file mode 100644 index 00000000..ec9935e4 --- /dev/null +++ b/_translations/guide/po/id/databases_db-migrations.md.po @@ -0,0 +1,168 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" +"PO-Revision-Date: 2025-09-04 11:19+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../../guide/en/databases/db-migrations.md +#, no-wrap +msgid "Migrations" +msgstr "" + +#. type: Plain text +#: ../../guide/en/databases/db-migrations.md +msgid "To use migrations, install [yiisoft/db-migration](https://github.com/yiisoft/db-migration/) package:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../../guide/en/databases/db-migrations.md +#, no-wrap +msgid "composer require yiisoft/db-migration\n" +msgstr "" + +#. type: Title ### +#: ../../guide/en/databases/db-migrations.md +#, no-wrap +msgid "Example usage" +msgstr "" + +#. type: Plain text +#: ../../guide/en/databases/db-migrations.md +msgid "First, configure a DI container. Create `config/common/db.php` with the following content:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/databases/db-migrations.md +#, no-wrap +msgid "" +" [\n" +" 'class' => SqliteConnection::class,\n" +" '__construct()' => [\n" +" 'dsn' => 'sqlite:' . __DIR__ . '/Data/yiitest.sq3'\n" +" ]\n" +" ]\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/databases/db-migrations.md +msgid "Add the following to `config/params.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/databases/db-migrations.md +#, no-wrap +msgid "" +"...\n" +"'yiisoft/db-migration' => [\n" +" 'newMigrationNamespace' => 'App\\\\Migration',\n" +" 'sourceNamespaces' => ['App\\\\Migration'],\n" +"],\n" +"...\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/databases/db-migrations.md +msgid "Now test if it works:" +msgstr "" + +#. type: Fenced code block (shell) +#: ../../guide/en/databases/db-migrations.md +#, no-wrap +msgid "./yii list migrate\n" +msgstr "" + +#. type: Title ### +#: ../../guide/en/databases/db-migrations.md +#, no-wrap +msgid "Creating a migration" +msgstr "" + +#. type: Plain text +#: ../../guide/en/databases/db-migrations.md +msgid "To work with migrations, you can use the provided [view](https://github.com/yiisoft/db-migration/tree/master/resources/views)." +msgstr "" + +#. type: Fenced code block (shell) +#: ../../guide/en/databases/db-migrations.md +#, no-wrap +msgid "./yii migrate:create my_first_table --command=table --fields=name,example --table-comment=my_first_table\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/databases/db-migrations.md +msgid "That would generate the following:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/databases/db-migrations.md +#, no-wrap +msgid "" +"createTable('my_first_table', [\n" +" 'id' => $b->primaryKey(),\n" +" 'name',\n" +" 'example',\n" +" ]);\n" +" \n" +" $b->addCommentOnTable('my_first_table', 'dest');\n" +" }\n" +"\n" +" public function down(MigrationBuilder $b): void\n" +" {\n" +" $b->dropTable('my_first_table');\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/databases/db-migrations.md +msgid "For more information [see](https://github.com/yiisoft/db-migration/tree/master/docs/guide/en)" +msgstr "" + +#. type: Title ### +#: ../../guide/en/databases/db-migrations.md +#, no-wrap +msgid "Upgrading from Yii2" +msgstr "" + +#. type: Plain text +#: ../../guide/en/databases/db-migrations.md +msgid "Migrations in Yii2 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." +msgstr "" diff --git a/_translations/guide/po/id/glossary.md.po b/_translations/guide/po/id/glossary.md.po new file mode 100644 index 00000000..250ad388 --- /dev/null +++ b/_translations/guide/po/id/glossary.md.po @@ -0,0 +1,209 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "A" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, fuzzy, no-wrap +#| msgid "Aliases" +msgid "alias" +msgstr "Aliases" + +#. type: Plain text +#: ../../guide/en/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 ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "asset" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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." +msgstr "" + +#. type: Title # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "C" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "configuration" +msgstr "" + +#. type: Plain text +#: ../../guide/en/glossary.md +msgid "The 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 # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "D" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "DI" +msgstr "" + +#. type: Plain text +#: ../../guide/en/glossary.md +msgid "Dependency Injection is a programming technique where an object injects a dependent object. [\"DI\"](concept/di-container.md)" +msgstr "" + +#. type: Title # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "I" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "installation" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "M" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "middleware" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "module" +msgstr "" + +#. type: Plain text +#: ../../guide/en/glossary.md +msgid "The module is a sub-application that groups some code based on a use-case. It's typically used within the main application and may contain URL handlers or console commands." +msgstr "" + +#. type: Title # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "N" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "namespace" +msgstr "" + +#. type: Plain text +#: ../../guide/en/glossary.md +msgid "Namespace refers to a [PHP language feature](https://www.php.net/manual/en/language.namespaces.php)." +msgstr "" + +#. type: Title # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "P" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "package" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 package manager." +msgstr "" + +#. type: Title # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "R" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "rule" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "Q" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "queue" +msgstr "" + +#. type: Plain text +#: ../../guide/en/glossary.md +msgid "A queue is similar to a stack. Queue follows First-In-First-Out methodology." +msgstr "" + +#. type: Title # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "V" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "vendor" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 "" diff --git a/_translations/guide/po/id/intro_upgrade-from-v2.md.po b/_translations/guide/po/id/intro_upgrade-from-v2.md.po new file mode 100644 index 00000000..bab77a79 --- /dev/null +++ b/_translations/guide/po/id/intro_upgrade-from-v2.md.po @@ -0,0 +1,266 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: en/intro/upgrade-from-v2.md +#, no-wrap +msgid "Upgrading from Version 2.0" +msgstr "" + +#. type: Plain text +#: en/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"> If you haven't used Yii2, you can skip this section and get directly to \"[getting started](../start/installation.md)\"\n" +"> section.\n" +msgstr "" + +#. type: Plain text +#: en/intro/upgrade-from-v2.md +msgid "While sharing some common ideas and values, Yii 3 is conceptually different from Yii 2. There is no easy upgrade path, so first [check maintenance policy and end-of-life dates for Yii 2](https://www.yiiframework.com/release-cycle) and consider starting new projects on Yii 3 while keeping existing ones on Yii 2." +msgstr "" + +#. type: Title ## +#: en/intro/upgrade-from-v2.md +#, no-wrap +msgid "PHP requirements" +msgstr "" + +#. type: Plain text +#: en/intro/upgrade-from-v2.md +msgid "Yii3 requires PHP 8.2 or above. As a result, there are language features used that weren't used in Yii 2:" +msgstr "" + +#. type: Bullet: '- ' +#: en/intro/upgrade-from-v2.md +msgid "[Type declarations](https://www.php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration)" +msgstr "" + +#. type: Bullet: '- ' +#: en/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: '- ' +#: en/intro/upgrade-from-v2.md +msgid "[Class constant visibility](https://www.php.net/manual/en/language.oop5.constants.php)" +msgstr "" + +#. type: Bullet: '- ' +#: en/intro/upgrade-from-v2.md +msgid "[Named arguments](https://www.php.net/manual/en/functions.arguments.php#functions.named-arguments)" +msgstr "" + +#. type: Bullet: '- ' +#: en/intro/upgrade-from-v2.md +msgid "[Anonymous classes](https://www.php.net/manual/en/language.oop5.anonymous.php)" +msgstr "" + +#. type: Bullet: '- ' +#: en/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: '- ' +#: en/intro/upgrade-from-v2.md +msgid "[Generators](https://www.php.net/manual/en/language.generators.php)" +msgstr "" + +#. type: Bullet: '- ' +#: en/intro/upgrade-from-v2.md +msgid "[Variadic functions](https://www.php.net/manual/en/functions.arguments.php#functions.variable-arg-list)" +msgstr "" + +#. type: Bullet: '- ' +#: en/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: '- ' +#: en/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: '- ' +#: en/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: '- ' +#: en/intro/upgrade-from-v2.md +msgid "[Attributes](https://www.php.net/manual/en/language.attributes.php)" +msgstr "" + +#. type: Title ## +#: en/intro/upgrade-from-v2.md +#, no-wrap +msgid "Preliminary refactoring" +msgstr "" + +#. type: Plain text +#: en/intro/upgrade-from-v2.md +msgid "It's a good idea to refactor your Yii 2 project before porting it to Yii 3. That would both make porting easier and benefit the project in question while it's not moved to Yii 3 yet." +msgstr "" + +#. type: Title ### +#: en/intro/upgrade-from-v2.md +#, no-wrap +msgid "Use DI instead of the service locator" +msgstr "" + +#. type: Plain text +#: en/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"Since Yii 3 is forcing you to inject dependencies, it's a good idea to prepare and switch from using\n" +"service locator (`Yii::$app->`) to [DI container](https://www.yiiframework.com/doc/guide/2.0/en/concept-di-container).\n" +msgstr "" + +#. type: Plain text +#: en/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"If usage of DI container is problematic for whatever reason, consider moving all calls to `Yii::$app->` to controller\n" +"actions and widgets and passing dependencies manually from a controller to what needs them.\n" +msgstr "" + +#. type: Plain text +#: en/intro/upgrade-from-v2.md +msgid "See [Dependency injection and container](../concept/di-container.md) for an explanation of the idea." +msgstr "" + +#. type: Title ### +#: en/intro/upgrade-from-v2.md +#, no-wrap +msgid "Introduce repositories for getting data" +msgstr "" + +#. type: Plain text +#: en/intro/upgrade-from-v2.md +msgid "Since Active Record isn't the only way to work with a database in Yii 3, consider introducing repositories that would hide details of getting data and gather them in a single place. You can later redo it:" +msgstr "" + +#. type: Fenced code block (php) +#: en/intro/upgrade-from-v2.md +#, no-wrap +msgid "" +"final readonly class PostRepository\n" +"{\n" +" public function getArchive()\n" +" {\n" +" // ...\n" +" }\n" +" \n" +" public function getTop10ForFrontPage()\n" +" {\n" +" // ...\n" +" }\n" +"\n" +"}\n" +msgstr "" + +#. type: Title ### +#: en/intro/upgrade-from-v2.md +#, no-wrap +msgid "Separate domain layer from infrastructure" +msgstr "" + +#. type: Plain text +#: en/intro/upgrade-from-v2.md +msgid "In case you have a rich complicated domain, it's a good idea to separate it from infrastructure provided by a framework that's all the business logic has to go to framework-independent classes." +msgstr "" + +#. type: Title ### +#: en/intro/upgrade-from-v2.md +#, no-wrap +msgid "Move more into components" +msgstr "" + +#. type: Plain text +#: en/intro/upgrade-from-v2.md +msgid "Yii 3 services are conceptually similar to Yii 2 components, so it's a good idea to move reusable parts of your application into components." +msgstr "" + +#. type: Title ## +#: en/intro/upgrade-from-v2.md +#, no-wrap +msgid "Things to learn" +msgstr "" + +#. type: Title ## +#: en/intro/upgrade-from-v2.md en/start/prerequisites.md +#, no-wrap +msgid "Docker" +msgstr "" + +#. type: Plain text +#: en/intro/upgrade-from-v2.md +msgid "Default application templates are using [Docker](https://www.docker.com/get-started/) to run application. It's a good idea to learn how to use it and use it for your own projects since it provides a lot of benefits:" +msgstr "" + +#. type: Bullet: '1. ' +#: en/intro/upgrade-from-v2.md +msgid "Exactly the same environment as in production." +msgstr "" + +#. type: Bullet: '2. ' +#: en/intro/upgrade-from-v2.md +msgid "No need to install anything except Docker itself." +msgstr "" + +#. type: Bullet: '3. ' +#: en/intro/upgrade-from-v2.md +msgid "Environment is per application, not per server." +msgstr "" + +#. type: Title ### +#: en/intro/upgrade-from-v2.md +#, no-wrap +msgid "Environment variables" +msgstr "" + +#. type: Plain text +#: en/intro/upgrade-from-v2.md +msgid "Yii3 application templates are using [environment variables](https://en.wikipedia.org/wiki/Environment_variable) to configure pars of the application. The concept is [very handy for Dockerized applications](https://12factor.net/) but might be alien to users of Yii 1.1 and Yii 2." +msgstr "" + +#. type: Title ### +#: en/intro/upgrade-from-v2.md +#, no-wrap +msgid "Handlers" +msgstr "" + +#. type: Plain text +#: en/intro/upgrade-from-v2.md +msgid "Unlike Yii2, Yii3 doesn't have controllers per se. Instead, it uses [handlers](../structure/handler.md) which are similar to controllers but different." +msgstr "" + +#. type: Title ### +#: en/intro/upgrade-from-v2.md +#, no-wrap +msgid "Application structure" +msgstr "" + +#. type: Plain text +#: en/intro/upgrade-from-v2.md +msgid "Suggested Yii3 application structure is different from Yii 2. It's described in [application structure](../structure/overview.md)." +msgstr "" + +#. type: Plain text +#: en/intro/upgrade-from-v2.md +msgid "Despite that, Yii3 is flexible, so it's still possible to use a structure similar to Yii 2 with Yii 3." +msgstr "" diff --git a/_translations/guide/po/id/intro_what-is-yii.md.po b/_translations/guide/po/id/intro_what-is-yii.md.po new file mode 100644 index 00000000..e402b473 --- /dev/null +++ b/_translations/guide/po/id/intro_what-is-yii.md.po @@ -0,0 +1,145 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" +"PO-Revision-Date: 2025-09-04 07:51+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../../guide/en/intro/what-is-yii.md +#, no-wrap +msgid "What is Yii" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 "" + +#. type: Title ## +#: ../../guide/en/intro/what-is-yii.md +#, no-wrap +msgid "What's Yii best for" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 "" + +#. type: Title ## +#: ../../guide/en/intro/what-is-yii.md +#, no-wrap +msgid "How does Yii compare with other frameworks?" +msgstr "" + +#. type: Plain text +#: ../../guide/en/intro/what-is-yii.md +msgid "If you're already familiar with another framework, you may appreciate knowing how Yii compares:" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/intro/what-is-yii.md +msgid "Yii takes the [philosophy of being practical and helpful](https://github.com/yiisoft/docs/blob/master/001-yii-values.md) achieving:" +msgstr "" + +#. type: Bullet: ' - ' +#: ../../guide/en/intro/what-is-yii.md +msgid "Performance in both development and execution." +msgstr "" + +#. type: Bullet: ' - ' +#: ../../guide/en/intro/what-is-yii.md +msgid "Convenient customizable defaults." +msgstr "" + +#. type: Bullet: ' - ' +#: ../../guide/en/intro/what-is-yii.md +msgid "Practice-orientation." +msgstr "" + +#. type: Bullet: ' - ' +#: ../../guide/en/intro/what-is-yii.md +msgid "Simplicity." +msgstr "" + +#. type: Bullet: ' - ' +#: ../../guide/en/intro/what-is-yii.md +msgid "Explicitness." +msgstr "" + +#. type: Bullet: ' - ' +#: ../../guide/en/intro/what-is-yii.md +msgid "Consistency." +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 "" + +#. type: Plain text +#: ../../guide/en/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 "" + +#. type: Title ## +#: ../../guide/en/intro/what-is-yii.md +#, no-wrap +msgid "Yii versions" +msgstr "" + +#. type: Plain text +#: ../../guide/en/intro/what-is-yii.md +msgid "Yii currently has three major versions available: 1.1, 2.0, and 3.0." +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/intro/what-is-yii.md +msgid "Version 1.1 is the old generation and is now in the feature freeze bugfix mode." +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/intro/what-is-yii.md +msgid "Version 2.0 is a current stable version in the feature freeze bugfix mode." +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/intro/what-is-yii.md +msgid "Version 3.0 is the current version in development. This guide is mainly about version 3." +msgstr "" + +#. type: Title ## +#: ../../guide/en/intro/what-is-yii.md +#, no-wrap +msgid "Requirements and prerequisites" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 "" + +#. type: Plain text +#: ../../guide/en/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 "" diff --git a/_translations/guide/po/id/runtime_cookies.md.po b/_translations/guide/po/id/runtime_cookies.md.po new file mode 100644 index 00000000..d6330079 --- /dev/null +++ b/_translations/guide/po/id/runtime_cookies.md.po @@ -0,0 +1,311 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: id\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/guide/po/id/runtime_handling-errors.md.po b/_translations/guide/po/id/runtime_handling-errors.md.po new file mode 100644 index 00000000..85824f47 --- /dev/null +++ b/_translations/guide/po/id/runtime_handling-errors.md.po @@ -0,0 +1,440 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: en/runtime/handling-errors.md +#, no-wrap +msgid "Handling errors" +msgstr "" + +#. type: Plain text +#: en/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: '- ' +#: en/runtime/handling-errors.md +msgid "[PSR-15](https://www.php-fig.org/psr/psr-15/) middleware for catching unhandled errors." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/handling-errors.md +msgid "PSR-15 middleware for mapping certain exceptions to custom responses." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/handling-errors.md +msgid "Production and debug modes." +msgstr "" + +#. type: Bullet: '- ' +#: en/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: '- ' +#: en/runtime/handling-errors.md +msgid "Takes PHP settings into account." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/handling-errors.md +msgid "Handles out of memory errors, fatal errors, warnings, notices, and exceptions." +msgstr "" + +#. type: Bullet: '- ' +#: en/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: '- ' +#: en/runtime/handling-errors.md +msgid "Detects a response format based on a mime type of the request." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/handling-errors.md +msgid "Supports responding with HTML, plain text, JSON, XML, and headers out of the box." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/handling-errors.md +msgid "You can implement your own error rendering for extra types." +msgstr "" + +#. type: Plain text +#: en/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 ## +#: en/runtime/handling-errors.md +#, no-wrap +msgid "Using error handler" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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) +#: en/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 +#: en/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) +#: en/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 +#: en/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) +#: en/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" +" ErrorHandler::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 +#: en/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 ## +#: en/runtime/handling-errors.md +#, no-wrap +msgid "Rendering error data" +msgstr "" + +#. type: Plain text +#: en/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: '- ' +#: en/runtime/handling-errors.md +msgid "`Yiisoft\\ErrorHandler\\Renderer\\HeaderRenderer` - Renders error into HTTP headers. It's used for `HEAD` request." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/handling-errors.md +msgid "`Yiisoft\\ErrorHandler\\Renderer\\HtmlRenderer` - Renders error into HTML." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/handling-errors.md +msgid "`Yiisoft\\ErrorHandler\\Renderer\\JsonRenderer` - Renders error into JSON." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/handling-errors.md +msgid "`Yiisoft\\ErrorHandler\\Renderer\\PlainTextRenderer` - Renders error into plain text." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/handling-errors.md +msgid "`Yiisoft\\ErrorHandler\\Renderer\\XmlRenderer` - Renders error into XML." +msgstr "" + +#. type: Plain text +#: en/runtime/handling-errors.md +msgid "The renderer produces detailed error data depending on whether debug mode is enabled or disabled." +msgstr "" + +#. type: Plain text +#: en/runtime/handling-errors.md +msgid "An Example of header rendering with a debugging mode turned off:" +msgstr "" + +#. type: Fenced code block +#: en/runtime/handling-errors.md +#, no-wrap +msgid "" +"...\n" +"X-Error-Message: An internal server error occurred.\n" +"...\n" +msgstr "" + +#. type: Plain text +#: en/runtime/handling-errors.md +msgid "An Example of header rendering with a debugging mode turned on:" +msgstr "" + +#. type: Fenced code block +#: en/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 +#: en/runtime/handling-errors.md +msgid "Example of JSON rendering output with a debugging mode turned off:" +msgstr "" + +#. type: Fenced code block (json) +#: en/runtime/handling-errors.md +#, no-wrap +msgid "{\"message\":\"An internal server error occurred.\"}\n" +msgstr "" + +#. type: Plain text +#: en/runtime/handling-errors.md +msgid "An Example of JSON rendering output with debugging mode turned on:" +msgstr "" + +#. type: Fenced code block (json) +#: en/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 +#: en/runtime/handling-errors.md +msgid "Example of HTML rendering with debugging mode turned off:" +msgstr "" + +#. type: Plain text +#: en/runtime/handling-errors.md +msgid "![View production](img/view-production.png)" +msgstr "" + +#. type: Plain text +#: en/runtime/handling-errors.md +msgid "Example of HTML rendering with debugging mode on and a light theme:" +msgstr "" + +#. type: Plain text +#: en/runtime/handling-errors.md +msgid "![View development with light theme](img/view-development-light.png)" +msgstr "" + +#. type: Plain text +#: en/runtime/handling-errors.md +msgid "Example of HTML rendering with debugging mode on and a dark theme:" +msgstr "" + +#. type: Plain text +#: en/runtime/handling-errors.md +msgid "![View development with dark theme](img/view-development-dark.png)" +msgstr "" + +#. type: Plain text +#: en/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 that you register within the error catcher. By default, it supports JSON, XML, and plain text." +msgstr "" + +#. type: Title ### +#: en/runtime/handling-errors.md +#, no-wrap +msgid "Implementing your own renderer" +msgstr "" + +#. type: Plain text +#: en/runtime/handling-errors.md +msgid "You may customize the error response format by providing your own instance of `Yiisoft\\ErrorHandler\\ThrowableRendererInterface` when registering error catcher middleware." +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/handling-errors.md +#, no-wrap +msgid "" +"use Psr\\Http\\Message\\ServerRequestInterface;\n" +"use Yiisoft\\ErrorHandler\\ErrorData;\n" +"use Yiisoft\\ErrorHandler\\ThrowableRendererInterface;\n" +"\n" +"final readonly class MyRenderer implements ThrowableRendererInterface\n" +"{\n" +" public function render(Throwable $t, ServerRequestInterface $request = null): ErrorData\n" +" {\n" +" return new ErrorData($t->getMessage());\n" +" }\n" +"\n" +" public function renderVerbose(Throwable $t, ServerRequestInterface $request = null): ErrorData\n" +" {\n" +" return new ErrorData(\n" +" $t->getMessage(),\n" +" ['X-Custom-Header' => 'value-header'], // Headers to be added to the response.\n" +" );\n" +" }\n" +"};\n" +msgstr "" + +#. type: Plain text +#: en/runtime/handling-errors.md +msgid "You may configure it in the application configuration `config/web.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/handling-errors.md +#, no-wrap +msgid "" +"use Psr\\Container\\ContainerInterface;\n" +"use Psr\\Http\\Message\\ResponseFactoryInterface;\n" +"use Yiisoft\\ErrorHandler\\ErrorHandler;\n" +"use Yiisoft\\ErrorHandler\\Middleware\\ErrorCatcher;\n" +"\n" +"return [\n" +" // ...\n" +" ErrorCatcher::class => static function (ContainerInterface $container): ErrorCatcher {\n" +" $errorCatcher = new ErrorCatcher(\n" +" $container->get(ResponseFactoryInterface::class),\n" +" $container->get(ErrorHandler::class),\n" +" $container,\n" +" );\n" +" // Returns a new instance without renderers by the specified content types.\n" +" $errorCatcher = $errorCatcher->withoutRenderers('application/xml', 'text/xml');\n" +" // Returns a new instance with the specified content type and renderer class.\n" +" return $errorCatcher->withRenderer('my/format', new MyRenderer());\n" +" },\n" +" // ...\n" +"];\n" +msgstr "" + +#. type: Title ## +#: en/runtime/handling-errors.md +#, no-wrap +msgid "Friendly exceptions" +msgstr "" + +#. type: Plain text +#: en/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) +#: en/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 +#: en/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/guide/po/id/runtime_logging.md.po b/_translations/guide/po/id/runtime_logging.md.po new file mode 100644 index 00000000..21229568 --- /dev/null +++ b/_translations/guide/po/id/runtime_logging.md.po @@ -0,0 +1,641 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: en/runtime/logging.md +#, no-wrap +msgid "Logging" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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 +#: en/runtime/logging.md +msgid "Using the Yii logging framework involves the following steps:" +msgstr "" + +#. type: Bullet: '* ' +#: en/runtime/logging.md +msgid "Record [log messages](#log-messages) at various places in your code;" +msgstr "" + +#. type: Bullet: '* ' +#: en/runtime/logging.md +msgid "Configure [log targets](#log-targets) in the application configuration to filter and export log messages;" +msgstr "" + +#. type: Bullet: '* ' +#: en/runtime/logging.md +msgid "Examine the filtered logged messages exported by different targets (e.g. the [Yii debugger](../tool/debugger.md))." +msgstr "" + +#. type: Plain text +#: en/runtime/logging.md +msgid "In this section, the focus in on the first two steps." +msgstr "" + +#. type: Title ## +#: en/runtime/logging.md +#, no-wrap +msgid "Log Messages " +msgstr "" + +#. type: Plain text +#: en/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) +#: en/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 +#: en/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: '- ' +#: en/runtime/logging.md +msgid "`emergency` - System is unusable." +msgstr "" + +#. type: Bullet: '- ' +#: en/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: '- ' +#: en/runtime/logging.md +msgid "`critical` - Critical conditions. Example: Application component unavailable, unexpected exception." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/logging.md +msgid "`error` - Runtime errors that don't require immediate action but should typically be logged and monitored." +msgstr "" + +#. type: Bullet: '- ' +#: en/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: '- ' +#: en/runtime/logging.md +msgid "`notice` - Normal but significant events." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/logging.md +msgid "`info` - Interesting events. Example: User logs in, SQL logs." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/logging.md +msgid "`debug` - Detailed debug information." +msgstr "" + +#. type: Plain text +#: en/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) +#: en/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 +#: en/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 +#: en/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 +#: en/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 +#: en/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 ## +#: en/runtime/logging.md +#, no-wrap +msgid "Log targets " +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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) +#: en/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 +#: en/runtime/logging.md +msgid "In the above code, two log targets are registered:" +msgstr "" + +#. type: Bullet: '* ' +#: en/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 +#: en/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 +#: en/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: '* ' +#: en/runtime/logging.md +msgid "[[\\Yiisoft\\Log\\PsrTarget]]: passes log messages to another PSR-3 compatible logger." +msgstr "" + +#. type: Bullet: '* ' +#: en/runtime/logging.md +msgid "[[\\Yiisoft\\Log\\StreamTarget]]: writes log messages into a specified output stream." +msgstr "" + +#. type: Bullet: '* ' +#: en/runtime/logging.md +msgid "[[\\Yiisoft\\Log\\Target\\Db\\DbTarget]]: saves log messages in database." +msgstr "" + +#. type: Bullet: '* ' +#: en/runtime/logging.md +msgid "[[\\Yiisoft\\Log\\Target\\Email\\EmailTarget]]: sends log messages to pre-specified email addresses." +msgstr "" + +#. type: Bullet: '* ' +#: en/runtime/logging.md +msgid "[[\\Yiisoft\\Log\\Target\\File\\FileTarget]]: saves log messages in files." +msgstr "" + +#. type: Bullet: '* ' +#: en/runtime/logging.md +msgid "[[\\Yiisoft\\Log\\Target\\Syslog\\SyslogTarget]]: saves log messages to syslog by calling the PHP function `syslog()`." +msgstr "" + +#. type: Plain text +#: en/runtime/logging.md +msgid "In the following, we will describe the features common to all log targets." +msgstr "" + +#. type: Title ### +#: en/runtime/logging.md +#, no-wrap +msgid "Message Filtering " +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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 +#: en/runtime/logging.md +msgid "By default, the target will process messages of *any* severity level." +msgstr "" + +#. type: Plain text +#: en/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 +#: en/runtime/logging.md +msgid "By default, the target will process messages of *any* category." +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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) +#: en/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 ### +#: en/runtime/logging.md +#, no-wrap +msgid "Message Formatting " +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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 +#: en/runtime/logging.md +msgid "By default, log messages have the following format:" +msgstr "" + +#. type: Fenced code block +#: en/runtime/logging.md +#, no-wrap +msgid "Timestamp Prefix[Level][Category] Message Context\n" +msgstr "" + +#. type: Plain text +#: en/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) +#: en/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 +#: en/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) +#: en/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 +#: en/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) +#: en/runtime/logging.md +#, no-wrap +msgid "function (\\Yiisoft\\Log\\Message $message, array $commonContext): string;\n" +msgstr "" + +#. type: Plain text +#: en/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) +#: en/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 ### +#: en/runtime/logging.md +#, no-wrap +msgid "Message Trace Level " +msgstr "" + +#. type: Plain text +#: en/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) +#: en/runtime/logging.md +#, no-wrap +msgid "" +"$logger = new \\Yiisoft\\Log\\Logger($targets);\n" +"$logger->setTraceLevel(3);\n" +msgstr "" + +#. type: Plain text +#: en/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) +#: en/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 +#: en/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 ### +#: en/runtime/logging.md +#, no-wrap +msgid "Message flushing and exporting " +msgstr "" + +#. type: Plain text +#: en/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) +#: en/runtime/logging.md +#, no-wrap +msgid "" +"$logger = new \\Yiisoft\\Log\\Logger($targets);\n" +"$logger->setFlushInterval(100); // default is 1000\n" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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) +#: en/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 +#: en/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) +#: en/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 +#: en/runtime/logging.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> Frequent message flushing and exporting will degrade the performance of your application.\n" +msgstr "" + +#. type: Title ### +#: en/runtime/logging.md +#, no-wrap +msgid "Toggling log targets " +msgstr "" + +#. type: Plain text +#: en/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) +#: en/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 +#: en/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 ### +#: en/runtime/logging.md +#, no-wrap +msgid "Creating new targets " +msgstr "" + +#. type: Plain text +#: en/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 +#: en/runtime/logging.md +msgid "The following protected methods will also be available for child targets:" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/logging.md +msgid "`getMessages` - Get a list of log messages ([[\\Yii\\Log\\Message]] instances)." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/logging.md +msgid "`getFormattedMessages` - Get a list of log messages formatted as strings." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/logging.md +msgid "`formatMessages` - Get all log messages formatted as a string." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/logging.md +msgid "`getCommonContext` - Get an array with common context data in the `key => value` format." +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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) +#: en/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/guide/po/id/runtime_request.md.po b/_translations/guide/po/id/runtime_request.md.po new file mode 100644 index 00000000..5ba4a124 --- /dev/null +++ b/_translations/guide/po/id/runtime_request.md.po @@ -0,0 +1,393 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: en/runtime/request.md +#, no-wrap +msgid "Request" +msgstr "" + +#. type: Plain text +#: en/runtime/request.md +msgid "HTTP request has a method, URI, a set of headers and a body:" +msgstr "" + +#. type: Fenced code block +#: en/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 +#: en/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 +#: en/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) +#: en/runtime/request.md +#, no-wrap +msgid "" +"public function view(ServerRequestInterface $request): ResponseInterface\n" +"{\n" +" // ...\n" +"}\n" +msgstr "" + +#. type: Title ## +#: en/runtime/request.md +#, no-wrap +msgid "Method" +msgstr "" + +#. type: Plain text +#: en/runtime/request.md +msgid "The method could be obtained from a request object:" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/request.md +#, no-wrap +msgid "$method = $request->getMethod();\n" +msgstr "" + +#. type: Plain text +#: en/runtime/request.md +msgid "Usually it's one of the:" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "GET" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "POST" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "PUT" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "DELETE" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "HEAD" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "PATCH" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "OPTIONS" +msgstr "" + +#. type: Plain text +#: en/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) +#: en/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 ## +#: en/runtime/request.md +#, no-wrap +msgid "URI" +msgstr "" + +#. type: Plain text +#: en/runtime/request.md +msgid "A URI has:" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "Scheme (`http`, `https`)" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "Host (`yiiframework.com`)" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "Port (`80`, `443`)" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "Path (`/posts/1`)" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "Query string (`page=1&sort=+id`)" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "Fragment (`#anchor`)" +msgstr "" + +#. type: Plain text +#: en/runtime/request.md +msgid "You can obtain `UriInterface` from request like the following:" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/request.md +#, no-wrap +msgid "$uri = $request->getUri();\n" +msgstr "" + +#. type: Plain text +#: en/runtime/request.md +msgid "Then you can get various details from its methods:" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "`getScheme()`" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "`getAuthority()`" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "`getUserInfo()`" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "`getHost()`" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "`getPort()`" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "`getPath()`" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "`getQuery()`" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/request.md +msgid "`getFragment()`" +msgstr "" + +#. type: Title ## +#: en/runtime/request.md en/runtime/response.md +#, no-wrap +msgid "Headers" +msgstr "" + +#. type: Plain text +#: en/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) +#: en/runtime/request.md +#, no-wrap +msgid "" +"$headers = $request->getHeaders();\n" +"foreach ($headers as $name => $values) {\n" +" // ...\n" +"}\n" +msgstr "" + +#. type: Plain text +#: en/runtime/request.md +msgid "To get a single header:" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/request.md +#, no-wrap +msgid "$values = $request->getHeader('Accept-Encoding');\n" +msgstr "" + +#. type: Plain text +#: en/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) +#: en/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 +#: en/runtime/request.md +msgid "To check if a header is present in the request:" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/request.md +#, no-wrap +msgid "" +"if ($request->hasHeader('Accept-Encoding')) {\n" +" // ...\n" +"}\n" +msgstr "" + +#. type: Title ## +#: en/runtime/request.md en/runtime/response.md +#, no-wrap +msgid "Body" +msgstr "" + +#. type: Plain text +#: en/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) +#: en/runtime/request.md +#, no-wrap +msgid "$body = $request->getBody();\n" +msgstr "" + +#. type: Plain text +#: en/runtime/request.md +msgid "The `$body` would be an instance of `Psr\\Http\\Message\\StreamInterface`." +msgstr "" + +#. type: Plain text +#: en/runtime/request.md +msgid "Also, you could get a parsed body:" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/request.md +#, no-wrap +msgid "$bodyParameters = $request->getParsedBody();\n" +msgstr "" + +#. type: Plain text +#: en/runtime/request.md +msgid "Parsing depends on PSR-7 implementation and may require middleware for custom body formats." +msgstr "" + +#. type: Fenced code block (php) +#: en/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 ## +#: en/runtime/request.md +#, no-wrap +msgid "File uploads" +msgstr "" + +#. type: Plain text +#: en/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) +#: en/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: Title ## +#: en/runtime/request.md +#, no-wrap +msgid "Attributes" +msgstr "" + +#. type: Plain text +#: en/runtime/request.md +msgid "Application middleware may set custom request attributes using `withAttribute()` method. You can get these attributes with `getAttribute()`." +msgstr "" diff --git a/_translations/guide/po/id/runtime_response.md.po b/_translations/guide/po/id/runtime_response.md.po new file mode 100644 index 00000000..1d76d428 --- /dev/null +++ b/_translations/guide/po/id/runtime_response.md.po @@ -0,0 +1,211 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: en/runtime/request.md en/runtime/response.md +#, no-wrap +msgid "Headers" +msgstr "" + +#. type: Title ## +#: en/runtime/request.md en/runtime/response.md +#, no-wrap +msgid "Body" +msgstr "" + +#. type: Title # +#: en/runtime/response.md +#, no-wrap +msgid "Response" +msgstr "" + +#. type: Plain text +#: en/runtime/response.md +msgid "HTTP response has status code and message, a set of headers and a body:" +msgstr "" + +#. type: Fenced code block +#: en/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 +#: en/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 +#: en/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) +#: en/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 ## +#: en/runtime/response.md +#, no-wrap +msgid "Status code" +msgstr "" + +#. type: Plain text +#: en/runtime/response.md +msgid "You can set a status code like the following:" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/response.md +#, no-wrap +msgid "" +"use Yiisoft\\Http\\Status;\n" +"\n" +"$response = $response->withStatus(Status::NOT_FOUND);\n" +msgstr "" + +#. type: Plain text +#: en/runtime/response.md +msgid "Majority of status codes are available from `Status` class for convenience and readability." +msgstr "" + +#. type: Plain text +#: en/runtime/response.md +msgid "You can set headers like this:" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/response.md +#, no-wrap +msgid "$response = $response->withHeader('Content-type', 'application/json');\n" +msgstr "" + +#. type: Plain text +#: en/runtime/response.md +msgid "If there is a need to append a header value to the existing header:" +msgstr "" + +#. type: Fenced code block (php) +#: en/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 +#: en/runtime/response.md +msgid "And, if needed, headers could be removed:" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/response.md +#, no-wrap +msgid "$response = $response->withoutHeader('Set-Cookie');\n" +msgstr "" + +#. type: Plain text +#: en/runtime/response.md +msgid "Response body is an object implementing `Psr\\Http\\Message\\StreamInterface`." +msgstr "" + +#. type: Plain text +#: en/runtime/response.md +msgid "You can write to it via the interface itself:" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/response.md +#, no-wrap +msgid "" +"$body = $response->getBody();\n" +"$body->write('Hello');\n" +msgstr "" + +#. type: Title ## +#: en/runtime/response.md +#, no-wrap +msgid "Examples" +msgstr "" + +#. type: Title ### +#: en/runtime/response.md +#, no-wrap +msgid "Redirecting" +msgstr "" + +#. type: Fenced code block (php) +#: en/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: Title ### +#: en/runtime/response.md +#, no-wrap +msgid "Responding with JSON" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/response.md +#, no-wrap +msgid "" +"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(200)\n" +" ->withHeader('Content-Type', 'application/json');\n" +msgstr "" diff --git a/_translations/guide/po/id/runtime_routing.md.po b/_translations/guide/po/id/runtime_routing.md.po new file mode 100644 index 00000000..09396b10 --- /dev/null +++ b/_translations/guide/po/id/runtime_routing.md.po @@ -0,0 +1,514 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: en/runtime/routing.md +#, no-wrap +msgid "Routing and URL generation" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/runtime/routing.md +msgid "The reverse process of routing is *URL generation*, which creates a URL from a given named route and the associated query parameters. When you later request the created URL, the routing process can resolve it back into the original route and query parameters." +msgstr "" + +#. type: Plain text +#: en/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 ## +#: en/runtime/routing.md +#, no-wrap +msgid "Configuring routes" +msgstr "" + +#. type: Plain text +#: en/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) +#: en/runtime/routing.md +#, no-wrap +msgid "" +"action([SiteController::class, 'index'])\n" +" ->name('site/index')\n" +"];\n" +msgstr "" + +#. type: Plain text +#: en/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: '- ' +#: en/runtime/routing.md +msgid "get" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/routing.md +msgid "post" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/routing.md +msgid "put" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/routing.md +msgid "delete" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/routing.md +msgid "patch" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/routing.md +msgid "head" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/routing.md +msgid "options" +msgstr "" + +#. type: Plain text +#: en/runtime/routing.md +msgid "If you need many methods, you can use `methods()`:" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/routing.md +#, no-wrap +msgid "" +"action([SiteController::class, 'user'])\n" +" ->name('site/user')\n" +"];\n" +msgstr "" + +#. type: Plain text +#: en/runtime/routing.md +msgid "All these methods accept a route pattern and a handler. 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. You could specify a handler as:" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/routing.md +msgid "[Middleware](../structure/middleware.md) class name." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/routing.md +msgid "Handler action (an array of [HandlerClass, handlerMethod])." +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/routing.md +msgid "A callable." +msgstr "" + +#. type: Plain text +#: en/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) +#: en/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 +#: en/runtime/routing.md +msgid "The callable is called as is:" +msgstr "" + +#. type: Fenced code block (php) +#: en/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 +#: en/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 +#: en/runtime/routing.md +msgid "Get current request and handler by type-hinting for `ServerRequestInterface` and `RequestHandlerInterface`. You could add extra handlers to wrap primary one with `middleware()` method:" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/routing.md +#, no-wrap +msgid "" +"action([DownloadController::class, 'download'])\n" +" ->name('download/id')\n" +" ->middleware(LimitDownloadRate::class)\n" +"];\n" +msgstr "" + +#. type: Plain text +#: en/runtime/routing.md +msgid "Check [\"the middleware\"](../structure/middleware.md) guide to learn more about how to implement middleware." +msgstr "" + +#. type: Plain text +#: en/runtime/routing.md +msgid "This is especially useful when grouping routes:" +msgstr "" + +#. type: Fenced code block (php) +#: en/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(FormatDataResponseAsJson::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(FormatDataResponseAsJson::class)\n" +" ->name('api/user/profile'),\n" +" )\n" +"];\n" +msgstr "" + +#. type: Plain text +#: en/runtime/routing.md +msgid "Router executes `ApiDataWrapper` before handling any URL starting with `/api`." +msgstr "" + +#. type: Plain text +#: en/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 +#: en/runtime/routing.md +msgid "You can set a default value for a route parameter. For example:" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/routing.md +#, no-wrap +msgid "" +"action([SiteController::class, 'user'])\n" +" ->name('site/user')\n" +" ->defaults(['id' => '42'])\n" +"];\n" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/runtime/routing.md +msgid "In cause URL should be valid for a single host, you can specify it with `host()`." +msgstr "" + +#. type: Title ## +#: en/runtime/routing.md +#, no-wrap +msgid "Routing " +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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 ## +#: en/runtime/routing.md +#, no-wrap +msgid "Generating URLs " +msgstr "" + +#. type: Plain text +#: en/runtime/routing.md +msgid "To generate URL based on a route, a route should have a name:" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/routing.md +#, no-wrap +msgid "" +"name('test/index'),\n" +" Route::post('/test/submit/{id}', [TestController::class, 'submit'])\n" +" ->name('test/submit')\n" +"];\n" +msgstr "" + +#. type: Plain text +#: en/runtime/routing.md +msgid "The generation looks like the following:" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/routing.md +#, no-wrap +msgid "" +"generate('test/submit', ['id' => '42']);\n" +" // ...\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/runtime/routing.md +msgid "Then we use `generate()` method to get actual URL. It accepts a route name and an array of named query parameters. The code will return \"/test/submit/42.\" If you need absolute URL, use `generateAbsolute()` instead." +msgstr "" + +#. type: Title ## +#: en/runtime/routing.md +#, no-wrap +msgid "Route patterns " +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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 ### +#: en/runtime/routing.md +#, no-wrap +msgid "Named Parameters " +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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 +#: en/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 +#: en/runtime/routing.md +msgid "On a route match router fills the associated request attributes 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 +#: en/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. ' +#: en/runtime/routing.md +msgid "`'posts/{year:\\d{4}}/{category}`" +msgstr "" + +#. type: Bullet: '2. ' +#: en/runtime/routing.md +msgid "`'posts'`" +msgstr "" + +#. type: Bullet: '3. ' +#: en/runtime/routing.md +msgid "`'post/{id:\\d+}'`" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/routing.md +msgid "`/posts` match the second pattern;" +msgstr "" + +#. type: Bullet: '- ' +#: en/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: '- ' +#: en/runtime/routing.md +msgid "`/post/100` match a third pattern. The `id` parameter value is 100;" +msgstr "" + +#. type: Bullet: '- ' +#: en/runtime/routing.md +msgid "`/posts/php` doesn't match." +msgstr "" + +#. type: Plain text +#: en/runtime/routing.md +msgid "When generating URLs, you should use the following parameters:" +msgstr "" + +#. type: Fenced code block (php) +#: en/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 ### +#: en/runtime/routing.md +#, no-wrap +msgid "Optional parts " +msgstr "" + +#. type: Plain text +#: en/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) +#: en/runtime/routing.md +#, no-wrap +msgid "" +"use \\Yiisoft\\Router\\Route;\n" +"\n" +"Route::get('/posts[/{id}]')->defaults(['id' => '1']);\n" +msgstr "" + +#. type: Plain text +#: en/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/guide/po/id/runtime_sessions.md.po b/_translations/guide/po/id/runtime_sessions.md.po new file mode 100644 index 00000000..6d8c2a9c --- /dev/null +++ b/_translations/guide/po/id/runtime_sessions.md.po @@ -0,0 +1,250 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: en/runtime/sessions.md +#, no-wrap +msgid "Sessions" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/runtime/sessions.md +msgid "To add it to your application, use composer:" +msgstr "" + +#. type: Fenced code block (shell) +#: en/runtime/sessions.md +#, no-wrap +msgid "composer require yiisoft/session\n" +msgstr "" + +#. type: Title ## +#: en/runtime/sessions.md +#, no-wrap +msgid "Configuring middleware" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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) +#: en/runtime/sessions.md +#, no-wrap +msgid "" +"middleware(SessionMiddleware::class)\n" +" ->routes(\n" +" // ...\n" +" )\n" +"];\n" +msgstr "" + +#. type: Plain text +#: en/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) +#: en/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" +" CsrfMiddleware::class,\n" +" SessionMiddleware::class, // <-- add this\n" +" ErrorCatcher::class,\n" +" ]\n" +" );\n" +" }),\n" +" ],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Title ## +#: en/runtime/sessions.md +#, no-wrap +msgid "Opening and closing session" +msgstr "" + +#. type: Fenced code block (php) +#: en/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 +#: en/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 +#: en/runtime/sessions.md +msgid "There are two more ways to close a session:" +msgstr "" + +#. type: Fenced code block (php) +#: en/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 ## +#: en/runtime/sessions.md +#, no-wrap +msgid "Working with session data" +msgstr "" + +#. type: Plain text +#: en/runtime/sessions.md +msgid "Usually you will use the following methods to work with session data:" +msgstr "" + +#. type: Fenced code block (php) +#: en/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 ## +#: en/runtime/sessions.md +#, no-wrap +msgid "Flash messages" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/runtime/sessions.md +msgid "`FlashInteface` usage is the following:" +msgstr "" + +#. type: Fenced code block (php) +#: en/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 ## +#: en/runtime/sessions.md +#, no-wrap +msgid "Custom session storage" +msgstr "" + +#. type: Plain text +#: en/runtime/sessions.md +msgid "When using `Yiisoft\\Session\\Session`, you can use your own storage implementation:" +msgstr "" + +#. type: Fenced code block (php) +#: en/runtime/sessions.md +#, no-wrap +msgid "" +"$handler = new MySessionHandler();\n" +"$session = new \\Yiisoft\\Session\\Session([], $handler);\n" +msgstr "" + +#. type: Plain text +#: en/runtime/sessions.md +msgid "Custom storage must implement `\\SessionHandlerInterface`." +msgstr "" diff --git a/_translations/guide/po/id/security_authentication.md.po b/_translations/guide/po/id/security_authentication.md.po new file mode 100644 index 00000000..5bbe89ad --- /dev/null +++ b/_translations/guide/po/id/security_authentication.md.po @@ -0,0 +1,311 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" +"PO-Revision-Date: 2025-09-04 11:19+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../../guide/en/security/authentication.md +#, no-wrap +msgid "Authentication" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/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: '* ' +#: ../../guide/en/security/authentication.md +msgid "Configure the `Yiisoft\\Yii\\Web\\User\\User` service;" +msgstr "" + +#. type: Bullet: '* ' +#: ../../guide/en/security/authentication.md +msgid "Create a class implementing the `\\Yiisoft\\Auth\\IdentityInterface` interface;" +msgstr "" + +#. type: Bullet: '* ' +#: ../../guide/en/security/authentication.md +msgid "Create a class implementing the `\\Yiisoft\\Auth\\IdentityRepositoryInterface` interface;" +msgstr "" + +#. type: Title ## +#: ../../guide/en/security/authentication.md +#, no-wrap +msgid "Configuring `Yiisoft\\Yii\\Web\\User\\User` " +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authentication.md +msgid "The `Yiisoft\\Yii\\Web\\User\\User` 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) +#: ../../guide/en/security/authentication.md +#, no-wrap +msgid "" +"use Yiisoft\\Session\\Session;\n" +"use Yiisoft\\Session\\SessionInterface;\n" +"use Yiisoft\\Auth\\IdentityRepositoryInterface;\n" +"use Psr\\Container\\ContainerInterface;\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" +" \n" +" \n" +" // User:\n" +" IdentityRepositoryInterface::class => static function (ContainerInterface $container) {\n" +" // instead of a Cycle-based repository, you can use any implementation\n" +" return $container->get(\\Cycle\\ORM\\ORMInterface::class)->getRepository(\\App\\Entity\\User::class);\n" +" },\n" +"];\n" +msgstr "" + +#. type: Title ## +#: ../../guide/en/security/authentication.md +#, no-wrap +msgid "Implementing`\\Yiisoft\\Auth\\IdentityInterface` " +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authentication.md +msgid "The identity class must implement the `\\Yiisoft\\Auth\\IdentityInterface` which has a single method:" +msgstr "" + +#. type: Bullet: '* ' +#: ../../guide/en/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 +#: ../../guide/en/security/authentication.md +msgid "In the following example, an identity class is implemented as a pure PHP object." +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/security/authentication.md +#, no-wrap +msgid "" +"id;\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ## +#: ../../guide/en/security/authentication.md +#, no-wrap +msgid "Implementing`\\Yiisoft\\Auth\\IdentityRepositoryInterface` " +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authentication.md +msgid "The identity repository class must implement the `\\Yiisoft\\Auth\\IdentityRepositoryInterface` which has the following methods:" +msgstr "" + +#. type: Bullet: '* ' +#: ../../guide/en/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: '* ' +#: ../../guide/en/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 +#: ../../guide/en/security/authentication.md +msgid "A dummy implementation may look like the following:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/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 ## +#: ../../guide/en/security/authentication.md +#, no-wrap +msgid "Using `\\Yiisoft\\User\\User` " +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authentication.md +msgid "You can use `\\Yiisoft\\User\\User` 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) +#: ../../guide/en/security/authentication.md +#, no-wrap +msgid "" +"use \\Psr\\Http\\Message\\ServerRequestInterface;\n" +"use \\Yiisoft\\User\\User;\n" +"\n" +"final readonly class SiteController\n" +"{\n" +" public function actionIndex(ServerRequestInterface $request, User $user)\n" +" { \n" +" if ($user->isGuest()) {\n" +" // user is guest\n" +" } else {\n" +" $identity = $user->getIdentity();\n" +" // do something based on identity\n" +" } \n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authentication.md +msgid "`isGuest()` determines if user is logged in or not. `getIdentity()` returns an instance of identity." +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authentication.md +msgid "To log in a user, you may use the following code:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/security/authentication.md +#, no-wrap +msgid "" +"$identity = $identityRepository->findByEmail($email);\n" +"\n" +"/* @var $user \\Yiisoft\\User\\User */\n" +"$user->login($identity);\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/security/authentication.md +msgid "To log out a user, call" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/security/authentication.md +#, no-wrap +msgid "" +"/* @var $user \\Yiisoft\\User\\User */\n" +"$user->logout();\n" +msgstr "" + +#. type: Title ## +#: ../../guide/en/security/authentication.md +#, no-wrap +msgid "Authentication Events " +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authentication.md +msgid "The user service raises a few events during the login and logout processes." +msgstr "" + +#. type: Bullet: '* ' +#: ../../guide/en/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: '* ' +#: ../../guide/en/security/authentication.md +msgid "`\\Yiisoft\\User\\Event\\AfterLogin`: raised after a successful login." +msgstr "" + +#. type: Bullet: '* ' +#: ../../guide/en/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: '* ' +#: ../../guide/en/security/authentication.md +msgid "`\\Yiisoft\\User\\Event\\AfterLogout`: raised after a successful logout." +msgstr "" + +#. type: Plain text +#: ../../guide/en/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/guide/po/id/security_authorization.md.po b/_translations/guide/po/id/security_authorization.md.po new file mode 100644 index 00000000..3be5fef1 --- /dev/null +++ b/_translations/guide/po/id/security_authorization.md.po @@ -0,0 +1,678 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" +"PO-Revision-Date: 2025-09-04 11:19+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "Authorization" +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authorization.md +msgid "Authorization is the process of verifying that a user has enough permission to do something." +msgstr "" + +#. type: Title ## +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "Checking for permission " +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authorization.md +msgid "You can check if a user has certain permissions by using `\\Yiisoft\\User\\User` service:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "" +"namespace App\\Blog\\Post;\n" +"\n" +"use Yiisoft\\Router\\CurrentRoute;\n" +"use Yiisoft\\User\\User;\n" +"\n" +"final readonly class PostController\n" +"{\n" +" public function actionEdit(CurrentRoute $route, User $user, PostRepository $postRepository)\n" +" {\n" +" $postId = $route->getArgument('id');\n" +" if ($postId === null) {\n" +" // respond with 404 \n" +" }\n" +" \n" +" $post = $postRepository->findByPK($postId);\n" +" if ($post === null) {\n" +" // respond with 404 \n" +" }\n" +"\n" +" if (!$this->canEditPost($user, $post)) {\n" +" // respond with 403 \n" +" }\n" +" \n" +" // continue with editing a post\n" +" }\n" +" \n" +" private function canEditPost(User $user, Post $post): bool\n" +" {\n" +" return $post->getAuthorId() === $user->getId() || $user->can('updatePost'); \n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authorization.md +msgid "Behind the scenes, `Yiisoft\\Yii\\Web\\User\\User::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 ## +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "Role-based access control (RBAC) " +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/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 +#: ../../guide/en/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 +#: ../../guide/en/security/authorization.md +msgid "To ease description next, there are some basic RBAC concepts first." +msgstr "" + +#. type: Title ### +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "Basic concepts " +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/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 +#: ../../guide/en/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 ### +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "Configuring RBAC " +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authorization.md +msgid "RBAC is available via `yiisoft/rbac` package, so you need to require it:" +msgstr "" + +#. type: Fenced code block +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "composer require yiisoft/rbac\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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) +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "" +"use \\Psr\\Container\\ContainerInterface;\n" +"use Yiisoft\\Rbac\\Manager\\PhpManager;\n" +"use Yiisoft\\Rbac\\RuleFactory\\ClassNameRuleFactory;\n" +"\n" +"return [\n" +" \\Yiisoft\\Access\\AccessCheckerInterface::class => static function (ContainerInterface $container) {\n" +" $aliases = $container->get(\\Yiisoft\\Aliases\\Aliases::class);\n" +" return new PhpManager(new ClassNameRuleFactory(), $aliases->get('@rbac'));\n" +" }\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authorization.md +msgid "`\\Yiisoft\\Rbac\\Manager\\PhpManager` uses PHP script files to store authorization data. The files are under `@rbac` alias. 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 ### +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "Building authorization data " +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authorization.md +msgid "Building authorization data is all about the following tasks:" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/security/authorization.md +msgid "defining roles and permissions;" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/security/authorization.md +msgid "establishing relations between roles and permissions;" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/security/authorization.md +msgid "defining rules;" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/security/authorization.md +msgid "associating rules with roles and permissions;" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/security/authorization.md +msgid "assigning roles to users." +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/security/authorization.md +msgid "Either way, in the end, you'll get the following RBAC hierarchy:" +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authorization.md +msgid "![Simple RBAC hierarchy](img/rbac-hierarchy-1.svg \"Simple RBAC hierarchy\")" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 ### +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "Using console command" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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) +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "" +"manager;\n" +"\n" +" $auth->removeAll(); \n" +" \n" +" $createPost = (new Permission('createPost'))->withDescription('Create a post'); \n" +" $auth->add($createPost);\n" +"\n" +" $updatePost = (new Permission('updatePost'))->withDescription('Update post');\n" +" $auth->add($updatePost);\n" +"\n" +" // add the \"author\" role and give this role the \"createPost\" permission\n" +" $author = new Role('author');\n" +" $auth->add($author);\n" +" $auth->addChild($author, $createPost);\n" +"\n" +" // add the \"admin\" role and give this role the \"updatePost\" permission\n" +" // as well as the permissions of the \"author\" role\n" +" $admin = new Role('admin');\n" +" $auth->add($admin);\n" +" $auth->addChild($admin, $updatePost);\n" +" $auth->addChild($admin, $author);\n" +"\n" +" // Assign roles to users. 1 and 2 are IDs returned by IdentityInterface::getId()\n" +" // usually implemented in your User model.\n" +" $auth->assign($author, 2);\n" +" $auth->assign($admin, 1);\n" +" \n" +" return ExitCode::OK;\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authorization.md +msgid "You can execute the command above from the console the following way:" +msgstr "" + +#. type: Fenced code block +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "./yii rbac:init\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 #### +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "Using migrations" +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "**TODO**: finish it when migrations are implemented.\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/security/authorization.md +msgid "Create new migration using `./yii migrate:create init_rbac` then implement creating a hierarchy:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "" +"removeAll(); \n" +" \n" +" $createPost = (new Permission('createPost'))->withDescription('Create a post'); \n" +" $auth->add($createPost);\n" +"\n" +" $updatePost = (new Permission('updatePost'))->withDescription('Update post');\n" +" $auth->add($updatePost);\n" +"\n" +" // add the \"author\" role and give this role the \"createPost\" permission\n" +" $author = new Role('author');\n" +" $auth->add($author);\n" +" $auth->addChild($author, $createPost);\n" +"\n" +" // add the \"admin\" role and give this role the \"updatePost\" permission\n" +" // as well as the permissions of the \"author\" role\n" +" $admin = new Role('admin');\n" +" $auth->add($admin);\n" +" $auth->addChild($admin, $updatePost);\n" +" $auth->addChild($admin, $author);\n" +"\n" +" // Assign roles to users. 1 and 2 are IDs returned by IdentityInterface::getId()\n" +" // usually implemented in your User model.\n" +" $auth->assign($author, 2);\n" +" $auth->assign($admin, 1);\n" +" }\n" +" \n" +" public function down()\n" +" {\n" +" $auth = /* obtain auth */;\n" +"\n" +" $auth->removeAll();\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/security/authorization.md +msgid "You could apply migration by using `./yii migrate`." +msgstr "" + +#. type: Title ## +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "Assigning roles to users" +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "TODO: update when signup implemented in demo / template.\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/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) +#: ../../guide/en/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" +" $auth = \\Yii::$app->authManager;\n" +" $authorRole = $auth->getRole('author');\n" +" $auth->assign($authorRole, $user->getId());\n" +"\n" +" return $user;\n" +" }\n" +"\n" +" return null;\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 `authManager`." +msgstr "" + +#. type: Title ### +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "Using rules " +msgstr "" + +#. type: Plain text +#: ../../guide/en/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) +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "" +"namespace App\\User\\Rbac;\n" +"\n" +"use Yiisoft\\Rbac\\Item;\n" +"use \\Yiisoft\\Rbac\\Rule;\n" +"\n" +"/**\n" +" * Checks if the authorID matches user passed via params.\n" +" */\n" +"final readonly class AuthorRule extends Rule\n" +"{\n" +" private const NAME = 'isAuthor';\n" +"\n" +" public function __construct() {\n" +" parent::__construct(self::NAME);\n" +" }\n" +"\n" +" public function execute(string $userId, Item $item, array $parameters = []): bool\n" +" {\n" +" return isset($params['post']) ? $params['post']->getAuthorId() == $userId : false;\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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) +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "" +"/** @var \\Yiisoft\\Rbac\\ManagerInterface $auth */\n" +"\n" +"// add the rule\n" +"$rule = new AuthorRule();\n" +"$auth->add($rule);\n" +"\n" +"// add the \"updateOwnPost\" permission and associate the rule with it.\n" +"$updateOwnPost = (new \\Yiisoft\\Rbac\\Permission('updateOwnPost'))\n" +" ->withDescription('Update own post')\n" +" ->withRuleName($rule->getName());\n" +"$auth->add($updateOwnPost);\n" +"\n" +"// \"updateOwnPost\" will be used from \"updatePost\"\n" +"$auth->addChild($updateOwnPost, $updatePost);\n" +"\n" +"// allow \"author\" to update their own posts\n" +"$auth->addChild($author, $updateOwnPost);\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authorization.md +msgid "Now you've got the following hierarchy:" +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authorization.md +msgid "![RBAC hierarchy with a rule](img/rbac-hierarchy-2.svg \"RBAC hierarchy with a rule\")" +msgstr "" + +#. type: Title ### +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "Access check " +msgstr "" + +#. type: Plain text +#: ../../guide/en/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) +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "" +"namespace App\\Blog\\Post;\n" +"\n" +"use Psr\\Http\\Message\\ServerRequestInterface;\n" +"use Yiisoft\\User\\User;\n" +"\n" +"final readonly class PostController\n" +"{\n" +" public function actionEdit(ServerRequestInterface $request, User $user, PostRepository $postRepository)\n" +" {\n" +" $postId = $request->getAttribute('id');\n" +" if ($postId === null) {\n" +" // respond with 404 \n" +" }\n" +" \n" +" $post = $postRepository->findByPK($postId);\n" +" if ($post === null) {\n" +" // respond with 404 \n" +" }\n" +"\n" +" if (!$this->canEditPost($user, $post)) {\n" +" // respond with 403 \n" +" }\n" +" \n" +" // continue with editing a post\n" +" }\n" +" \n" +" private function canEditPost(User $user, Post $post): bool\n" +" {\n" +" return $user->can('updatePost', ['post' => $post]); \n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/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 +#: ../../guide/en/security/authorization.md +msgid "![Access check](img/rbac-access-check-1.svg \"Access check\")" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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) +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "" +"if ($user->can('updatePost', ['post' => $post])) {\n" +" // update post\n" +"}\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authorization.md +msgid "Here is what happens if the current user is John:" +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authorization.md +msgid "![Access check](img/rbac-access-check-2.svg \"Access check\")" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/security/authorization.md +msgid "In the case of Jane, it's a bit simpler since she is an admin:" +msgstr "" + +#. type: Plain text +#: ../../guide/en/security/authorization.md +msgid "![Access check](img/rbac-access-check-3.svg \"Access check\")" +msgstr "" + +#. type: Title ## +#: ../../guide/en/security/authorization.md +#, no-wrap +msgid "Implementing your own access checker" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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) +#: ../../guide/en/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/guide/po/id/security_best-practices.md.po b/_translations/guide/po/id/security_best-practices.md.po new file mode 100644 index 00000000..eb87f27e --- /dev/null +++ b/_translations/guide/po/id/security_best-practices.md.po @@ -0,0 +1,491 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-04 08:00+0500\n" +"PO-Revision-Date: 2025-09-04 08:00+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: en/concept/autoloading.md en/security/best-practices.md +#, no-wrap +msgid "References" +msgstr "Referensi" + +#. type: Title # +#: en/security/best-practices.md +#, no-wrap +msgid "Security best practices" +msgstr "" + +#. type: Plain text +#: en/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 ## +#: en/security/best-practices.md +#, no-wrap +msgid "Basic principles" +msgstr "" + +#. type: Plain text +#: en/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. ' +#: en/security/best-practices.md +msgid "Filter input." +msgstr "" + +#. type: Bullet: '2. ' +#: en/security/best-practices.md +msgid "Escape output." +msgstr "" + +#. type: Title ### +#: en/security/best-practices.md +#, no-wrap +msgid "Filter input" +msgstr "" + +#. type: Plain text +#: en/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) +#: en/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 +#: en/security/best-practices.md +msgid "In Yii, most probably you'll use [form validation](../input/validation.md) to do similar checks." +msgstr "" + +#. type: Plain text +#: en/security/best-practices.md +msgid "Further reading on the topic:" +msgstr "" + +#. type: Bullet: '- ' +#: en/security/best-practices.md +msgid "" +msgstr "" + +#. type: Bullet: '- ' +#: en/security/best-practices.md +msgid "" +msgstr "" + +#. type: Title ### +#: en/security/best-practices.md +#, no-wrap +msgid "Escape output" +msgstr "" + +#. type: Plain text +#: en/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: '- ' +#: en/security/best-practices.md +msgid "" +msgstr "" + +#. type: Bullet: '- ' +#: en/security/best-practices.md +msgid "" +msgstr "" + +#. type: Bullet: '- ' +#: en/security/best-practices.md +msgid "" +msgstr "" + +#. type: Title ## +#: en/security/best-practices.md +#, no-wrap +msgid "Avoiding SQL injections" +msgstr "" + +#. type: Plain text +#: en/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) +#: en/security/best-practices.md +#, no-wrap +msgid "" +"$username = $_GET['username'];\n" +"$sql = \"SELECT * FROM user WHERE username = '$username'\";\n" +msgstr "" + +#. type: Plain text +#: en/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) +#: en/security/best-practices.md +#, no-wrap +msgid "SELECT * FROM user WHERE username = ''; DROP TABLE user; --'\n" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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 +#: en/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) +#: en/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: '- ' +#: en/security/best-practices.md +msgid "" +msgstr "" + +#. type: Title ## +#: en/security/best-practices.md +#, no-wrap +msgid "Avoiding XSS" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/security/best-practices.md +msgid "Avoiding XSS is quite easy in Yii. There are two cases:" +msgstr "" + +#. type: Bullet: '1. ' +#: en/security/best-practices.md +msgid "You want to output data as plain text." +msgstr "" + +#. type: Bullet: '2. ' +#: en/security/best-practices.md +msgid "You want to output data as HTML." +msgstr "" + +#. type: Plain text +#: en/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) +#: en/security/best-practices.md +#, no-wrap +msgid "\n" +msgstr "" + +#. type: Plain text +#: en/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 ## +#: en/security/best-practices.md +#, no-wrap +msgid "Avoiding CSRF" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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 +#: en/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 +#: en/security/best-practices.md +msgid "For this reason, Yii applies extra mechanisms to protect against CSRF attacks." +msgstr "" + +#. type: Plain text +#: en/security/best-practices.md +msgid "To avoid CSRF, you should always:" +msgstr "" + +#. type: Bullet: '1. ' +#: en/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. ' +#: en/security/best-practices.md +msgid "Keep Yii CSRF protection enabled." +msgstr "" + +#. type: Plain text +#: en/security/best-practices.md +msgid "Yii has CSRF protection as `Yiisoft\\Yii\\Web\\Middleware\\Csrf` middleware. Make sure it's in your application middleware stack." +msgstr "" + +#. type: Bullet: '- ' +#: en/security/best-practices.md +msgid "" +msgstr "" + +#. type: Bullet: '- ' +#: en/security/best-practices.md +msgid "" +msgstr "" + +#. type: Title ## +#: en/security/best-practices.md +#, no-wrap +msgid "Avoiding file exposure" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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 ## +#: en/security/best-practices.md +#, no-wrap +msgid "Avoiding debug info and tools in production" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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 +#: en/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: '- ' +#: en/security/best-practices.md +msgid "" +msgstr "" + +#. type: Bullet: '- ' +#: en/security/best-practices.md +msgid "" +msgstr "" + +#. type: Title ## +#: en/security/best-practices.md +#, no-wrap +msgid "Using secure connection over TLS" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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 ## +#: en/security/best-practices.md +#, no-wrap +msgid "Secure server configuration" +msgstr "" + +#. type: Plain text +#: en/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 ### +#: en/security/best-practices.md +#, no-wrap +msgid "Avoiding `Host`-header attacks" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/security/best-practices.md +msgid "For more information about the server configuration, please refer to the documentation of your webserver:" +msgstr "" + +#. type: Bullet: '- ' +#: en/security/best-practices.md +msgid "Apache 2: " +msgstr "" + +#. type: Bullet: '- ' +#: en/security/best-practices.md +msgid "Nginx: " +msgstr "" + +#. type: Title ### +#: en/security/best-practices.md +#, no-wrap +msgid "Configuring SSL peer validation" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/security/best-practices.md +#, no-wrap +msgid "cURL error 60: SSL certificate problem: unable to get local issuer certificate\n" +msgstr "" + +#. type: Plain text +#: en/security/best-practices.md +msgid "or" +msgstr "" + +#. type: Fenced code block +#: en/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 +#: en/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. ' +#: en/security/best-practices.md +msgid "Download [https://curl.haxx.se/ca/cacert.pem](https://curl.haxx.se/ca/cacert.pem)." +msgstr "" + +#. type: Bullet: '2. ' +#: en/security/best-practices.md +msgid "Add the following to your php.ini:" +msgstr "" + +#. type: Fenced code block +#: en/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 +#: en/security/best-practices.md +msgid "Note that you should keep the file up to date." +msgstr "" + +#. type: Bullet: '- ' +#: en/security/best-practices.md +msgid "[OWASP top 10](https://owasp.org/Top10/)" +msgstr "" + +#. type: Bullet: '- ' +#: en/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: '- ' +#: en/security/best-practices.md +msgid "[PHP manual: security](https://www.php.net/manual/en/security.php)" +msgstr "" + +#. type: Bullet: '- ' +#: en/security/best-practices.md +msgid "[Information security at STackExchange](https://security.stackexchange.com/)" +msgstr "" diff --git a/_translations/guide/po/id/security_cryptography.md.po b/_translations/guide/po/id/security_cryptography.md.po new file mode 100644 index 00000000..133b8c44 --- /dev/null +++ b/_translations/guide/po/id/security_cryptography.md.po @@ -0,0 +1,232 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: id\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/guide/po/id/security_overview.md.po b/_translations/guide/po/id/security_overview.md.po new file mode 100644 index 00000000..a2d5f03c --- /dev/null +++ b/_translations/guide/po/id/security_overview.md.po @@ -0,0 +1,67 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: id\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 "" + +#. 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/guide/po/id/security_passwords.md.po b/_translations/guide/po/id/security_passwords.md.po new file mode 100644 index 00000000..2fd31a11 --- /dev/null +++ b/_translations/guide/po/id/security_passwords.md.po @@ -0,0 +1,77 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: id\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/guide/po/id/security_trusted-request.md.po b/_translations/guide/po/id/security_trusted-request.md.po new file mode 100644 index 00000000..c4038ab9 --- /dev/null +++ b/_translations/guide/po/id/security_trusted-request.md.po @@ -0,0 +1,76 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: id\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/guide/po/id/start_creating-project.md.po b/_translations/guide/po/id/start_creating-project.md.po new file mode 100644 index 00000000..6242dfd0 --- /dev/null +++ b/_translations/guide/po/id/start_creating-project.md.po @@ -0,0 +1,127 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: en/start/creating-project.md +#, no-wrap +msgid "Creating a project" +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/start/creating-project.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> If you want to use another web server,\n" +"> see [\"Configuring web servers\"](../../../cookbook/en/configuring-webservers/general.md).\n" +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/start/creating-project.md +msgid "You can create a new project from a template using the [Composer](https://getcomposer.org) package manager:" +msgstr "" + +#. type: Fenced code block +#: en/start/creating-project.md +#, no-wrap +msgid "composer create-project yiisoft/app your_project\n" +msgstr "" + +#. type: Plain text +#: en/start/creating-project.md +msgid "Docker users can run the following command:" +msgstr "" + +#. type: Fenced code block (sh) +#: en/start/creating-project.md +#, no-wrap +msgid "docker run --rm -it -v \"$(pwd):/app\" composer/composer create-project yiisoft/app your_project\n" +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/start/creating-project.md +msgid "Go into the newly created directory and run:" +msgstr "" + +#. type: Fenced code block (sh) +#: en/start/creating-project.md +#, no-wrap +msgid "APP_ENV=dev ./yii serve --port=80\n" +msgstr "" + +#. type: Plain text +#: en/start/creating-project.md +msgid "For Docker users, run:" +msgstr "" + +#. type: Fenced code block +#: en/start/creating-project.md +#, no-wrap +msgid "make up\n" +msgstr "" + +#. type: Plain text +#: en/start/creating-project.md +msgid "Open your browser to the URL `http://localhost/`." +msgstr "" + +#. type: Plain text +#: en/start/creating-project.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> The HTTP server listens on port 80. If that port is already in use, specify the port via `--port` or, in case of Docker,\n" +"> `DEV_PORT` in the `docker/.env` file.\n" +msgstr "" + +#. type: Plain text +#: en/start/creating-project.md +msgid "![Successful Installation of Yii](img/app-installed.png)" +msgstr "" + +#. type: Plain text +#: en/start/creating-project.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> [← What do you need to know?](prerequisites.md) | \n" +"> [Running applications →](workflow.md)\n" +msgstr "" diff --git a/_translations/guide/po/id/start_databases.md.po b/_translations/guide/po/id/start_databases.md.po new file mode 100644 index 00000000..070b58e4 --- /dev/null +++ b/_translations/guide/po/id/start_databases.md.po @@ -0,0 +1,122 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: en/start/databases.md +#, no-wrap +msgid "Working with databases" +msgstr "" + +#. type: Plain text +#: en/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: '- ' +#: en/start/databases.md +msgid "[Yii DB](https://github.com/yiisoft/db)" +msgstr "" + +#. type: Bullet: '- ' +#: en/start/databases.md +msgid "[Yii Active Record](https://github.com/yiisoft/active-record)" +msgstr "" + +#. type: Bullet: '- ' +#: en/start/databases.md +msgid "[Cycle](https://github.com/cycle) via [Yii Cycle package](https://github.com/yiisoft/yii-cycle)" +msgstr "" + +#. type: Bullet: '- ' +#: en/start/databases.md +msgid "[Doctrine](https://www.doctrine-project.org/) via [Yii Doctrine package](https://github.com/stargazer-team/yii-doctrine)" +msgstr "" + +#. type: Bullet: '- ' +#: en/start/databases.md +msgid "[PDO](https://www.php.net/manual/en/book.pdo.php)" +msgstr "" + +#. type: Plain text +#: en/start/databases.md +msgid "For non-relational ones, there are usually official libraries available:" +msgstr "" + +#. type: Bullet: '- ' +#: en/start/databases.md +msgid "[ElasticSearch](https://github.com/elastic/elasticsearch-php)" +msgstr "" + +#. type: Bullet: '- ' +#: en/start/databases.md +msgid "[Redis](https://redis.io/docs/clients/#php)" +msgstr "" + +#. type: Bullet: '- ' +#: en/start/databases.md +msgid "..." +msgstr "" + +#. type: Plain text +#: en/start/databases.md +msgid "In this guide, we will focus on working with relational databases using Yii DB." +msgstr "" + +#. type: Title ## +#: en/start/databases.md +#, no-wrap +msgid "Configuring connection" +msgstr "" + +#. type: Title ## +#: en/start/databases.md +#, no-wrap +msgid "Creating and applying migration" +msgstr "" + +#. type: Title ## +#: en/start/databases.md +#, no-wrap +msgid "Inserting" +msgstr "" + +#. type: Title ## +#: en/start/databases.md +#, no-wrap +msgid "Selecting" +msgstr "" + +#. type: Title ## +#: en/start/databases.md +#, no-wrap +msgid "Using data package" +msgstr "" + +#. type: Title ### +#: en/start/databases.md +#, no-wrap +msgid "Pagination" +msgstr "" + +#. type: Plain text +#: en/start/databases.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> [← Working with forms](forms.md) |\n" +"> [Generating code with Gii →](gii.md)\n" +msgstr "" diff --git a/_translations/guide/po/id/start_forms.md.po b/_translations/guide/po/id/start_forms.md.po new file mode 100644 index 00000000..7c2477a9 --- /dev/null +++ b/_translations/guide/po/id/start_forms.md.po @@ -0,0 +1,344 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: en/start/forms.md +#, no-wrap +msgid "Working with forms" +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/start/forms.md +msgid "Through this tutorial, you will learn how to:" +msgstr "" + +#. type: Bullet: '* ' +#: en/start/forms.md +msgid "Create a form model to represent the data entered by a user through a form." +msgstr "" + +#. type: Bullet: '* ' +#: en/start/forms.md +msgid "Declare rules to validate the data entered." +msgstr "" + +#. type: Bullet: '* ' +#: en/start/forms.md +msgid "Build an HTML form in a view." +msgstr "" + +#. type: Title ## +#: en/start/forms.md +#, no-wrap +msgid "Installing form package" +msgstr "" + +#. type: Plain text +#: en/start/forms.md +msgid "To install form package, issue the following command in your application directory:" +msgstr "" + +#. type: Fenced code block +#: en/start/forms.md +#, no-wrap +msgid "composer require yiisoft/form-model\n" +msgstr "" + +#. type: Plain text +#: en/start/forms.md +msgid "For Docker that would be:" +msgstr "" + +#. type: Fenced code block +#: en/start/forms.md +#, no-wrap +msgid "make composer require yiisoft/form-model\n" +msgstr "" + +#. type: Title ## +#: en/start/forms.md +#, no-wrap +msgid "Creating a form " +msgstr "" + +#. type: Plain text +#: en/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/App/Controller/Echo/Form.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: en/start/forms.md +#, no-wrap +msgid "" +" " +msgstr "" + +#. type: Plain text +#: en/start/forms.md +msgid "Now that you have a form, use it in your action from \"[Saying Hello](hello.md)\"." +msgstr "" + +#. type: Plain text +#: en/start/forms.md +msgid "Here's what you end up with in `/src/Controller/Echo/Action.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: en/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 "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/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 "" + +#. type: Fenced code block (php) +#: en/start/forms.md +#, no-wrap +msgid "" +"routes(\n" +" Route::get('/')\n" +" ->action(\\App\\Controller\\HomePage\\Action::class)\n" +" ->name('home'),\n" +" Route::methods([Method::GET, Method::POST], '/say')\n" +" ->action(\\App\\Controller\\Echo\\Action::class)\n" +" ->name('echo/say'),\n" +" ),\n" +"];\n" +msgstr "" + +#. type: Title ## +#: en/start/forms.md +#, no-wrap +msgid "Adjusting view" +msgstr "" + +#. type: Plain text +#: en/start/forms.md +msgid "To render a form, you need to change your view, `src/Controller/Echo/template.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: en/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 "" + +#. type: Plain text +#: en/start/forms.md +msgid "If the form is valid, you display a message. The rest initializes and renders the form." +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Fenced code block (php) +#: en/start/forms.md +#, no-wrap +msgid "" +"'yiisoft/yii-view-renderer' => [\n" +" 'injections' => [\n" +" Reference::to(CsrfViewInjection::class),\n" +" ],\n" +"],\n" +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/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 "" + +#. type: Title ## +#: en/start/forms.md +#, no-wrap +msgid "Trying it Out " +msgstr "" + +#. type: Plain text +#: en/start/forms.md +msgid "To see how it works, use your browser to access the following URL:" +msgstr "" + +#. type: Fenced code block +#: en/start/forms.md +#, no-wrap +msgid "http://localhost:8080/say\n" +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/start/forms.md +msgid "![Form with a validation error](img/form-error.png)" +msgstr "" + +#. type: Plain text +#: en/start/forms.md +msgid "After you enter a valid message and click the \"submit\" button, the page echoes the data that you entered." +msgstr "" + +#. type: Plain text +#: en/start/forms.md +msgid "![Form with a success message](img/form-success.png)" +msgstr "" + +#. type: Title ## +#: en/start/forms.md en/start/hello.md +#, no-wrap +msgid "Summary " +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/start/forms.md +msgid "In the next section, you will learn how to work with databases, which are needed in nearly every application." +msgstr "" + +#. type: Plain text +#: en/start/forms.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> [← Saying hello](hello.md) |\n" +"> [Working with databases →](databases.md)\n" +msgstr "" diff --git a/_translations/guide/po/id/start_gii.md.po b/_translations/guide/po/id/start_gii.md.po new file mode 100644 index 00000000..295bc6d5 --- /dev/null +++ b/_translations/guide/po/id/start_gii.md.po @@ -0,0 +1,31 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: en/start/gii.md +#, no-wrap +msgid "Generating code with Gii" +msgstr "" + +#. type: Plain text +#: en/start/gii.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> [← Working with databases](databases.md) |\n" +"> [Looking ahead →](looking-ahead.md)\n" +msgstr "" diff --git a/_translations/guide/po/id/start_hello.md.po b/_translations/guide/po/id/start_hello.md.po new file mode 100644 index 00000000..6ab30ee9 --- /dev/null +++ b/_translations/guide/po/id/start_hello.md.po @@ -0,0 +1,288 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: en/start/forms.md en/start/hello.md +#, no-wrap +msgid "Summary " +msgstr "" + +#. type: Title # +#: en/start/hello.md +#, no-wrap +msgid "Saying hello" +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/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](../structure/views.md) for building the response." +msgstr "" + +#. type: Plain text +#: en/start/hello.md +msgid "Through this tutorial, you will learn three things:" +msgstr "" + +#. type: Bullet: '1. ' +#: en/start/hello.md +msgid "How to create a handler to respond to a request." +msgstr "" + +#. type: Bullet: '2. ' +#: en/start/hello.md +msgid "How to map URL to the handler." +msgstr "" + +#. type: Bullet: '3. ' +#: en/start/hello.md +msgid "How to create a [view](../structure/view.md) to compose the response's content." +msgstr "" + +#. type: Title ## +#: en/start/hello.md +#, no-wrap +msgid "Creating a handler " +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/start/hello.md +msgid "Create `src/Controller/Echo/Action.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: en/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 "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/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 "" + +#. type: Title ## +#: en/start/hello.md +#, no-wrap +msgid "Configuring router" +msgstr "" + +#. type: Plain text +#: en/start/hello.md +msgid "Now, to map your handler to URL, you need to add a route in `config/common/routes.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: en/start/hello.md +#, no-wrap +msgid "" +"routes(\n" +" Route::get('/')\n" +" ->action(\\App\\Controller\\HomePage\\Action::class)\n" +" ->name('home'),\n" +" Route::get('/say[/{message}]')\n" +" ->action(\\App\\Controller\\Echo\\Action::class)\n" +" ->name('echo/say'),\n" +" ),\n" +"];\n" +msgstr "" + +#. type: Plain text +#: en/start/hello.md +msgid "In the above, you map the `/say[/{message}]` pattern to `\\App\\Controller\\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` request attribute. `[]` marks this part of the pattern as optional." +msgstr "" + +#. type: Plain text +#: en/start/hello.md +msgid "You also give a `echo/say` name to this route to be able to generate URLs pointing to it." +msgstr "" + +#. type: Title ## +#: en/start/hello.md +#, no-wrap +msgid "Trying it out " +msgstr "" + +#. type: Plain text +#: en/start/hello.md +msgid "After creating the action and the view open `http://localhost/say/Hello+World` in your browser." +msgstr "" + +#. type: Plain text +#: en/start/hello.md +msgid "This URL displays a page with \"The message is: Hello World\"." +msgstr "" + +#. type: Plain text +#: en/start/hello.md +msgid "If you omit the `message` parameter in the URL, the page displays \"The message is: Hello!\"." +msgstr "" + +#. type: Title ## +#: en/start/hello.md +#, no-wrap +msgid "Creating a View Template " +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/start/hello.md +msgid "For the \"Hello\" task, create a `src/Controller/Echo/template.php` template that prints the `message` parameter received from the action method:" +msgstr "" + +#. type: Fenced code block (php) +#: en/start/hello.md +#, no-wrap +msgid "" +"\n" +"\n" +"

The message is:

\n" +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/start/hello.md +msgid "To use the view, you need to change `src/Controller/Echo/Action.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: en/start/hello.md +#, no-wrap +msgid "" +"viewRenderer->render(__DIR__ . '/template', [\n" +" 'message' => $message,\n" +" ]);\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: en/start/hello.md +msgid "Now open your browser and check it again. You should see the similar text but with a layout applied." +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/start/hello.md +msgid "You've also learned about routing in Yii, which acts as the bridge between user requests and handlers." +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/start/hello.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> [← Running applications](workflow.md) |\n" +"> [Working with forms →](forms.md)\n" +msgstr "" diff --git a/_translations/guide/po/id/start_looking-ahead.md.po b/_translations/guide/po/id/start_looking-ahead.md.po new file mode 100644 index 00000000..525d305c --- /dev/null +++ b/_translations/guide/po/id/start_looking-ahead.md.po @@ -0,0 +1,35 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: en/start/looking-ahead.md +#, no-wrap +msgid "Looking ahead" +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/start/looking-ahead.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> [← Generating code with Gii](gii.md)\n" +msgstr "" diff --git a/_translations/guide/po/id/start_prerequisites.md.po b/_translations/guide/po/id/start_prerequisites.md.po new file mode 100644 index 00000000..0292c982 --- /dev/null +++ b/_translations/guide/po/id/start_prerequisites.md.po @@ -0,0 +1,105 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: en/intro/upgrade-from-v2.md en/start/prerequisites.md +#, no-wrap +msgid "Docker" +msgstr "" + +#. type: Title # +#: en/start/prerequisites.md +#, no-wrap +msgid "What do you need to know?" +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Title ## +#: en/start/prerequisites.md +#, no-wrap +msgid "PHP" +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Title ## +#: en/start/prerequisites.md +#, no-wrap +msgid "Object-oriented programming" +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/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 "" + +#. type: Title ## +#: en/start/prerequisites.md +#, no-wrap +msgid "Command line and Composer" +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Title ## +#: en/start/prerequisites.md +#, no-wrap +msgid "HTTP" +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/start/prerequisites.md +msgid "Also, you will benefit from familiarizing yourself with [twelve-factor app](https://12factor.net/) principles." +msgstr "" + +#. type: Plain text +#: en/start/prerequisites.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> [Creating a project →](creating-project.md)\n" +msgstr "" diff --git a/_translations/guide/po/id/start_workflow.md.po b/_translations/guide/po/id/start_workflow.md.po new file mode 100644 index 00000000..a3198d51 --- /dev/null +++ b/_translations/guide/po/id/start_workflow.md.po @@ -0,0 +1,221 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: en/start/workflow.md +#, no-wrap +msgid "Running applications" +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/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 "" + +#. type: Title ## +#: en/start/workflow.md +#, no-wrap +msgid "Functionality " +msgstr "" + +#. type: Plain text +#: en/start/workflow.md +msgid "The installed application has only the homepage, which displays when you access the URL `http://localhost/`. It shares a common layout that you can reuse on further pages." +msgstr "" + +#. type: Plain text +#: en/start/workflow.md +#, no-wrap +msgid "" +"\n" +msgstr "" + +#. type: Plain text +#: en/start/workflow.md +msgid "In addition to the web application, you can access a console script via `APP_ENV=dev ./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 "" + +#. type: Title ## +#: en/start/workflow.md +#, no-wrap +msgid "Application structure " +msgstr "" + +#. type: Plain text +#: en/start/workflow.md +msgid "The most important directories and files in your application are (assuming the application's root directory is `app`):" +msgstr "" + +#. type: Fenced code block +#: en/start/workflow.md +#, no-wrap +msgid "" +"assets/ Application assets to be published.\n" +"config/ Configuration.\n" +" common/ Configs applied to both console and web.\n" +" di/ DI container configuration.\n" +" aliasess.php Aliases.\n" +" application.php Application configuration.\n" +" bootstrap.php Bootstrap configuration.\n" +" params.php Various parameters used in DI configs.\n" +" routes.php Application routes.\n" +" console/ Configs applied to console.\n" +" commands.php Registered console commands.\n" +" params.php Various parameters used in DI configs.\n" +" web/ Configs applied to web.\n" +" di/ DI container configuration.\n" +" params.php Various parameters used in DI configs.\n" +" environments/ Environment-based configs.\n" +" dev/ Configs applied in dev environment.\n" +" params.php Various parameters used in DI configs.\n" +" prod/ Configs applied in prod environment.\n" +" params.php Various parameters used in DI configs.\n" +" test/ Configs applied in test environment.\n" +" params.php Various parameters used in DI configs. \n" +" configuration.php Defines how to read application configs.\n" +" .merge-plan.php Merge plan to assemble configs according to. Build using `configuration.php`.\n" +"docker/ Docker configuration.\n" +" dev/ Dev environment.\n" +" .env Environment variables.\n" +" compose.yml Services for dev environment.\n" +" prod/ Prod environment.\n" +" .env Environment variables.\n" +" compose.yml Services for prod environment.\n" +" test/ Test environment.\n" +" .env Environment variables.\n" +" compose.yml Services for test environment.\n" +" .env Common environment variables.\n" +" compose.yml Common services.\n" +" Dockerfile Images to use.\n" +"public/ Files publically accessible from the Internet.\n" +" assets/ Published assets.\n" +" index.php Entry script for web.\n" +"runtime/ Files generated during runtime.\n" +"src/ Application source code.\n" +" Command/ Console commands.\n" +" Controller/ Controllers.\n" +" Handler/ Custom handler for 404.\n" +" Layout/ Layouts.\n" +" autoload.php Autoloader.\n" +" Environment.php Environment helper.\n" +"tests/ A set of Codeception tests for the application. \n" +"vendor/ Installed Composer packages.\n" +".gitignore Files and directories to be ignored by Git.\n" +".php-cs-fixer.php PHP Coding Standards Fixer configuration.\n" +"c3.php Codeception code coverage script.\n" +"condeception.yml Codeception configuration.\n" +"composer.json Composer configuration.\n" +"composer.lock Composer lock file.\n" +"Makefile Makefile with shortcut commands.\n" +"psalm.xml Psalm configuration.\n" +"rector.php Rector configuration.\n" +"yii Console application entry point.\n" +msgstr "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/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 "" + +#. type: Plain text +#: en/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 "" + +#. type: Title ## +#: en/start/workflow.md +#, no-wrap +msgid "Request Lifecycle " +msgstr "" + +#. type: Plain text +#: en/start/workflow.md +msgid "The following diagram shows how an application handles a request." +msgstr "" + +#. type: Plain text +#: en/start/workflow.md +msgid "![Request Lifecycle](img/request-lifecycle.svg)" +msgstr "" + +#. type: Bullet: '1. ' +#: en/start/workflow.md +msgid "A user makes a request to the [entry script](../structure/entry-script.md) `public/index.php`." +msgstr "" + +#. type: Bullet: '2. ' +#: en/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 "" + +#. type: Bullet: '3. ' +#: en/start/workflow.md +msgid "Request factory creates a request object based on a raw request that came from a user." +msgstr "" + +#. type: Bullet: '4. ' +#: en/start/workflow.md +msgid "Application passes a request object through a middleware array configured. One of these is typically a router." +msgstr "" + +#. type: Bullet: '5. ' +#: en/start/workflow.md +msgid "The Router finds out what handler to execute based on request and configuration." +msgstr "" + +#. type: Bullet: '6. ' +#: en/start/workflow.md +msgid "The handler may load some data, possibly from a database." +msgstr "" + +#. type: Bullet: '7. ' +#: en/start/workflow.md +msgid "The handler forms a response by using data. Either directly or with the help of the view package." +msgstr "" + +#. type: Bullet: '8. ' +#: en/start/workflow.md +msgid "Emitter receives the response and takes care of sending the response to the user's browser." +msgstr "" + +#. type: Plain text +#: en/start/workflow.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> [← Creating a project](creating-project.md) |\n" +"> [Saying hello →](hello.md)\n" +msgstr "" diff --git a/_translations/guide/po/id/structure_action.md.po b/_translations/guide/po/id/structure_action.md.po new file mode 100644 index 00000000..20721c67 --- /dev/null +++ b/_translations/guide/po/id/structure_action.md.po @@ -0,0 +1,178 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: en/structure/action.md +#, no-wrap +msgid "Actions" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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) +#: en/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 +#: en/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) +#: en/structure/action.md +#, no-wrap +msgid "" +"use Yiisoft\\Router\\Route;\n" +"\n" +"Route::get('/')->action([FrontPageAction::class, 'run']),\n" +msgstr "" + +#. type: Plain text +#: en/structure/action.md +msgid "The class itself would be like:" +msgstr "" + +#. type: Fenced code block (php) +#: en/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 run(ServerRequestInterface $request): ResponseInterface\n" +" {\n" +" // build response for a front page \n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: en/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) +#: en/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 +#: en/structure/action.md +msgid "The class itself would look like the following:" +msgstr "" + +#. type: Fenced code block (php) +#: en/structure/action.md +#, no-wrap +msgid "" +"use \\Psr\\Http\\Message\\ServerRequestInterface;\n" +"use \\Psr\\Http\\Message\\ResponseInterface;\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(ServerRequestInterface $request): ResponseInterface\n" +" {\n" +" // render a single post \n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: en/structure/action.md +msgid "We usually call such a class \"controller.\"" +msgstr "" + +#. type: Title ## +#: en/structure/action.md +#, no-wrap +msgid "Autowiring" +msgstr "" + +#. type: Plain text +#: en/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) +#: en/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 +#: en/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/guide/po/id/structure_application.md.po b/_translations/guide/po/id/structure_application.md.po new file mode 100644 index 00000000..64cf9f6e --- /dev/null +++ b/_translations/guide/po/id/structure_application.md.po @@ -0,0 +1,47 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: en/structure/application.md +#, no-wrap +msgid "Application" +msgstr "" + +#. type: Plain text +#: en/structure/application.md +msgid "The primary purpose of the web application and its runner in Yii 3 is to process requests to get responses." +msgstr "" + +#. type: Plain text +#: en/structure/application.md +msgid "Typically, the runtime consists of:" +msgstr "" + +#. type: Bullet: '1. ' +#: en/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. ' +#: en/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. ' +#: en/structure/application.md +msgid "Shutdown. Fire `ApplicationShutdown` event." +msgstr "" diff --git a/_translations/guide/po/id/structure_domain.md.po b/_translations/guide/po/id/structure_domain.md.po new file mode 100644 index 00000000..f01ca094 --- /dev/null +++ b/_translations/guide/po/id/structure_domain.md.po @@ -0,0 +1,185 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: en/concept/autoloading.md en/security/best-practices.md +#: en/structure/domain.md en/tutorial/console-applications.md +#, no-wrap +msgid "References" +msgstr "Referensi" + +#. type: Title # +#: en/structure/domain.md +#, no-wrap +msgid "Domain" +msgstr "" + +#. type: Plain text +#: en/structure/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 +#: en/structure/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 ## +#: en/structure/domain.md +#, no-wrap +msgid "Bounded context" +msgstr "" + +#. type: Plain text +#: en/structure/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 ## +#: en/structure/domain.md +#, no-wrap +msgid "Building blocks" +msgstr "" + +#. type: Plain text +#: en/structure/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: '- ' +#: en/structure/domain.md en/structure/service.md +#, no-wrap +msgid "Entity" +msgstr "" + +#. type: Plain text +#: en/structure/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 ### +#: en/structure/domain.md +#, no-wrap +msgid "Value object" +msgstr "" + +#. type: Plain text +#: en/structure/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 ### +#: en/structure/domain.md +#, no-wrap +msgid "Aggregate" +msgstr "" + +#. type: Plain text +#: en/structure/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 +#: en/structure/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 ### +#: en/structure/domain.md +#, no-wrap +msgid "Domain event" +msgstr "" + +#. type: Plain text +#: en/structure/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 ### +#: en/structure/domain.md +#, no-wrap +msgid "Data transfer object" +msgstr "" + +#. type: Plain text +#: en/structure/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 ### +#: en/structure/domain.md +#, no-wrap +msgid "Service" +msgstr "" + +#. type: Plain text +#: en/structure/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: Bullet: '- ' +#: en/structure/domain.md en/structure/service.md +#, no-wrap +msgid "Repository" +msgstr "" + +#. type: Plain text +#: en/structure/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 +#: en/structure/domain.md +msgid "Repository is usually implemented as a service." +msgstr "" + +#. type: Title ### +#: en/structure/domain.md +#, no-wrap +msgid "Instantiating building blocks" +msgstr "" + +#. type: Plain text +#: en/structure/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: Bullet: '- ' +#: en/structure/domain.md +msgid "[BoundedContext by Martin Fowler](https://martinfowler.com/bliki/BoundedContext.html)" +msgstr "" + +#. type: Bullet: '- ' +#: en/structure/domain.md +msgid "[ValueObject by Martin Fowler](https://martinfowler.com/bliki/ValueObject.html)" +msgstr "" + +#. type: Bullet: '- ' +#: en/structure/domain.md +msgid "[Aggregate by Marting Fowler](https://martinfowler.com/bliki/DDD_Aggregate.html)" +msgstr "" diff --git a/_translations/guide/po/id/structure_entry-script.md.po b/_translations/guide/po/id/structure_entry-script.md.po new file mode 100644 index 00000000..edb10ad6 --- /dev/null +++ b/_translations/guide/po/id/structure_entry-script.md.po @@ -0,0 +1,192 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: en/structure/entry-script.md +#, no-wrap +msgid "Entry scripts" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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 +#: en/structure/entry-script.md +msgid "Entry script for console application is `./yii`." +msgstr "" + +#. type: Plain text +#: en/structure/entry-script.md +msgid "Entry scripts mainly perform the following work with the help of `ApplicationRunner`:" +msgstr "" + +#. type: Bullet: '* ' +#: en/structure/entry-script.md +msgid "Register [Composer autoloader](https://getcomposer.org/doc/01-basic-usage.md#autoloading);" +msgstr "" + +#. type: Bullet: '* ' +#: en/structure/entry-script.md +msgid "Obtain configuration;" +msgstr "" + +#. type: Bullet: '* ' +#: en/structure/entry-script.md +msgid "Use configuration to initialize a dependency injection container;" +msgstr "" + +#. type: Bullet: '* ' +#: en/structure/entry-script.md +msgid "Get an instance of the request." +msgstr "" + +#. type: Bullet: '* ' +#: en/structure/entry-script.md +msgid "Pass it to `Application` to handle and get a response from it." +msgstr "" + +#. type: Bullet: '* ' +#: en/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 ## +#: en/structure/entry-script.md +#, no-wrap +msgid "Web Applications " +msgstr "" + +#. type: Plain text +#: en/structure/entry-script.md +msgid "The following is the code in the entry script for the application template:" +msgstr "" + +#. type: Fenced code block (php) +#: en/structure/entry-script.md +#, no-wrap +msgid "" +"debug();\n" +"// Run application:\n" +"$runner->run();\n" +msgstr "" + +#. type: Title ## +#: en/structure/entry-script.md +#, no-wrap +msgid "Console Applications " +msgstr "" + +#. type: Plain text +#: en/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) +#: en/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 ## +#: en/structure/entry-script.md +#, no-wrap +msgid "Alternative runtimes" +msgstr "" + +#. type: Plain text +#: en/structure/entry-script.md +msgid "For alternative runtimes such as RoadRunner or Swoole, special entry scripts should be used. See:" +msgstr "" + +#. type: Bullet: '- ' +#: en/structure/entry-script.md +msgid "[Using Yii with RoadRunner](../tutorial/using-yii-with-roadrunner.md)" +msgstr "" + +#. type: Bullet: '- ' +#: en/structure/entry-script.md +msgid "[Using Yii with Swoole](../tutorial/using-yii-with-swoole.md)" +msgstr "" diff --git a/_translations/guide/po/id/structure_handler.md.po b/_translations/guide/po/id/structure_handler.md.po new file mode 100644 index 00000000..39bb1cb3 --- /dev/null +++ b/_translations/guide/po/id/structure_handler.md.po @@ -0,0 +1,22 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: en/structure/handler.md +#, no-wrap +msgid "Request handlers" +msgstr "" diff --git a/_translations/guide/po/id/structure_middleware.md.po b/_translations/guide/po/id/structure_middleware.md.po new file mode 100644 index 00000000..9e1e2221 --- /dev/null +++ b/_translations/guide/po/id/structure_middleware.md.po @@ -0,0 +1,310 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" +"PO-Revision-Date: 2025-09-04 11:19+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../../guide/en/structure/middleware.md +#, no-wrap +msgid "Middleware" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/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: '- ' +#: ../../guide/en/structure/middleware.md +msgid "Pass the request to the next middleware performing some work before / after it." +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/structure/middleware.md +msgid "Form the response and return it." +msgstr "" + +#. type: Plain text +#: ../../guide/en/structure/middleware.md +msgid "Depending on middleware used, application behavior may vary significantly." +msgstr "" + +#. type: Plain text +#: ../../guide/en/structure/middleware.md +msgid "![Middleware](img/middleware.svg)" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/structure/middleware.md +msgid "![Middleware](img/middleware_alternative.svg)" +msgstr "" + +#. type: Title ## +#: ../../guide/en/structure/middleware.md +#, no-wrap +msgid "Using middleware" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/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 +#: ../../guide/en/structure/middleware.md +msgid "Now register the middleware in DI container configuration `config/web.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/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 +#: ../../guide/en/structure/middleware.md +msgid "In the `config/routes.php`, add new route:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/structure/middleware.md +#, no-wrap +msgid "" +"([SiteController::class, 'auth'])\n" +" ->name('site/auth')\n" +" ->addMiddleware(BasicAuthentication::class)\n" +"];\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/structure/middleware.md +msgid "The action itself could be the following:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/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 +#: ../../guide/en/structure/middleware.md +msgid "Basic authentication middleware wrote to request `username` attribute, so you can access the data if needed." +msgstr "" + +#. type: Plain text +#: ../../guide/en/structure/middleware.md +msgid "To apply middleware to application overall regardless of URL, adjust `config/application.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/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" +" CsrfMiddleware::class,\n" +" Router::class,\n" +" ]\n" +" );\n" +" }),\n" +" 'fallbackHandler' => Reference::to(NotFoundHandler::class),\n" +" ],\n" +" ],\n" +"];\n" +msgstr "" + +#. type: Title ## +#: ../../guide/en/structure/middleware.md +#, no-wrap +msgid "Creating your own middleware" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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) +#: ../../guide/en/structure/middleware.md +#, no-wrap +msgid "public function process(ServerRequestInterface $request, RequestHandlerInterface $next): ResponseInterface;\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 ### +#: ../../guide/en/structure/middleware.md +#, no-wrap +msgid "Forming a response directly" +msgstr "" + +#. type: Plain text +#: ../../guide/en/structure/middleware.md +msgid "To respond directly, one needs a response factory passed via constructor:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/structure/middleware.md +#, no-wrap +msgid "" +"responseFactory->createResponse();\n" +" $response->getBody()->write('Hello!');\n" +" return $response;\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title ### +#: ../../guide/en/structure/middleware.md +#, no-wrap +msgid "Delegating handling to the next middleware" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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) +#: ../../guide/en/structure/middleware.md +#, no-wrap +msgid "return $next->handle($request);\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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) +#: ../../guide/en/structure/middleware.md +#, no-wrap +msgid "" +"$request = $request->withAttribute('answer', 42);\n" +"return $next->handle();\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/structure/middleware.md +msgid "To get it in the next middleware:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/structure/middleware.md +#, no-wrap +msgid "$answer = $request->getAttribute('answer');\n" +msgstr "" + +#. type: Title ### +#: ../../guide/en/structure/middleware.md +#, no-wrap +msgid "Capturing response to manipulate it" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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) +#: ../../guide/en/structure/middleware.md +#, no-wrap +msgid "" +"$response = $next->handle($request);\n" +"// extra handing\n" +"return $response;\n" +msgstr "" diff --git a/_translations/guide/po/id/structure_overview.md.po b/_translations/guide/po/id/structure_overview.md.po new file mode 100644 index 00000000..d596490a --- /dev/null +++ b/_translations/guide/po/id/structure_overview.md.po @@ -0,0 +1,159 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: en/structure/overview.md +#, no-wrap +msgid "Overview" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/structure/overview.md +msgid "For example, if the application is an online store, the context could be:" +msgstr "" + +#. type: Bullet: '- ' +#: en/structure/overview.md +msgid "Customer" +msgstr "" + +#. type: Bullet: ' - ' +#: en/structure/overview.md +msgid "Profile" +msgstr "" + +#. type: Bullet: ' - ' +#: en/structure/overview.md +msgid "Products list" +msgstr "" + +#. type: Bullet: ' - ' +#: en/structure/overview.md +msgid "Checkout" +msgstr "" + +#. type: Bullet: '- ' +#: en/structure/overview.md +msgid "Logistics" +msgstr "" + +#. type: Bullet: '- ' +#: en/structure/overview.md +msgid "Delivery" +msgstr "" + +#. type: Bullet: ' - ' +#: en/structure/overview.md +msgid "Addresses" +msgstr "" + +#. type: Bullet: '- ' +#: en/structure/overview.md +msgid "Helpdesk" +msgstr "" + +#. type: Bullet: ' - ' +#: en/structure/overview.md +msgid "Support" +msgstr "" + +#. type: Bullet: ' - ' +#: en/structure/overview.md +msgid "Claims" +msgstr "" + +#. type: Bullet: ' - ' +#: en/structure/overview.md +msgid "Returns" +msgstr "" + +#. type: Bullet: '- ' +#: en/structure/overview.md +msgid "Accounting" +msgstr "" + +#. type: Bullet: ' - ' +#: en/structure/overview.md +msgid "Transactions" +msgstr "" + +#. type: Bullet: ' - ' +#: en/structure/overview.md +msgid "Taxes" +msgstr "" + +#. type: Plain text +#: en/structure/overview.md +msgid "For a \"Customer\" context, residing under `App\\Customer` namespace, structure would be:" +msgstr "" + +#. type: Fenced code block +#: en/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 +#: en/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 +#: en/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 +#: en/structure/overview.md +msgid "Besides, Yii applications also have the following:" +msgstr "" + +#. type: Bullet: '* ' +#: en/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: '* ' +#: en/structure/overview.md +msgid "[services](service.md): they're typically stateless objects registered within dependency container and provide various action methods." +msgstr "" + +#. type: Bullet: '* ' +#: en/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/guide/po/id/structure_package.md.po b/_translations/guide/po/id/structure_package.md.po new file mode 100644 index 00000000..c240592c --- /dev/null +++ b/_translations/guide/po/id/structure_package.md.po @@ -0,0 +1,341 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: en/structure/package.md +#, no-wrap +msgid "Packages" +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "Reusable code could be released as [a Composer package](https://getcomposer.org/doc/05-repositories.md#package). It could be an infrastructure library, a module representing one of the application contexts or, basically, any reusable code." +msgstr "" + +#. type: Title ## +#: en/structure/package.md +#, no-wrap +msgid "Using packages " +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "By default, Composer installs packages registered on [Packagist](https://packagist.org/) — the biggest repository for open source PHP packages. You can look for packages on Packagist. You may also [create your own repository](https://getcomposer.org/doc/05-repositories.md#repository) and configure Composer to use it. This is useful if you're developing private packages that you want to share within your projects only." +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "Packages installed by Composer are stored in the `vendor` directory of your project. Because the Composer is a dependency manager, when it installs a package, it will also install all its dependent packages." +msgstr "" + +#. type: Plain text +#: en/structure/package.md +#, no-wrap +msgid "" +"> [!WARNING]\n" +"> `vendor` directory of your application should never be modified.\n" +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "A package could be installed with the following command:" +msgstr "" + +#. type: Fenced code block +#: en/structure/package.md +#, no-wrap +msgid "composer install vendor-name/package-name\n" +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "After it's done, Composer modifies `composer.json` and `composer.lock`. The former defines what packages to install, and their version constraints the latter stores a snapshot of exact versions actually installed." +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "Classes from the package will be available immediately via [autoloading](../concept/autoloading.md)." +msgstr "" + +#. type: Title ## +#: en/structure/package.md +#, no-wrap +msgid "Creating packages " +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "You may consider creating a package when you feel the need to share with other people your great code. A package can contain any code you like, such as a helper class, a widget, a service, middleware, the whole module, etc." +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "Below are the basic steps you may follow." +msgstr "" + +#. type: Bullet: '1. ' +#: en/structure/package.md +msgid "Create a project for your package and host it on a VCS repository, such as [GitHub.com](https://github.com). The development and maintenance work for the package should be done on this repository." +msgstr "" + +#. type: Bullet: '2. ' +#: en/structure/package.md +msgid "Under the root directory of the project, create a file named `composer.json` as required by Composer. Please refer to the next subsection for more details." +msgstr "" + +#. type: Bullet: '3. ' +#: en/structure/package.md +msgid "Register your package with a Composer repository, such as [Packagist](https://packagist.org/), so that other users can find and install your package using Composer." +msgstr "" + +#. type: Title ### +#: en/structure/package.md +#, no-wrap +msgid "`composer.json` " +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "Each Composer package must have a `composer.json` file in its root directory. The file contains the metadata about the package. You may find the complete specification about this file in the [Composer Manual](https://getcomposer.org/doc/01-basic-usage.md#composer-json-project-setup). The following example shows the `composer.json` file for the `yiisoft/yii-widgets` package:" +msgstr "" + +#. type: Fenced code block (json) +#: en/structure/package.md +#, no-wrap +msgid "" +"{\n" +" \"name\": \"yiisoft/yii-widgets\",\n" +" \"type\": \"library\",\n" +" \"description\": \"Yii widgets collection\",\n" +" \"keywords\": [\n" +" \"yii\",\n" +" \"widgets\"\n" +" ],\n" +" \"homepage\": \"https://www.yiiframework.com/\",\n" +" \"license\": \"BSD-3-Clause\",\n" +" \"support\": {\n" +" \"issues\": \"https://github.com/yiisoft/yii-widgets/issues?state=open\",\n" +" \"forum\": \"https://www.yiiframework.com/forum/\",\n" +" \"wiki\": \"https://www.yiiframework.com/wiki/\",\n" +" \"irc\": \"ircs://irc.libera.chat:6697/yii\",\n" +" \"chat\": \"https://t.me/yii3en\",\n" +" \"source\": \"https://github.com/yiisoft/yii-widgets\"\n" +" },\n" +" \"funding\": [\n" +" {\n" +" \"type\": \"opencollective\",\n" +" \"url\": \"https://opencollective.com/yiisoft\"\n" +" },\n" +" {\n" +" \"type\": \"github\",\n" +" \"url\": \"https://github.com/sponsors/yiisoft\"\n" +" }\n" +" ],\n" +" \"require\": {\n" +" \"php\": \"^7.4|^8.0\",\n" +" \"yiisoft/aliases\": \"^1.1|^2.0\",\n" +" \"yiisoft/cache\": \"^1.0\",\n" +" \"yiisoft/html\": \"^2.0\",\n" +" \"yiisoft/view\": \"^4.0\",\n" +" \"yiisoft/widget\": \"^1.0\"\n" +" },\n" +" \"require-dev\": {\n" +" \"phpunit/phpunit\": \"^9.5\",\n" +" \"roave/infection-static-analysis-plugin\": \"^1.16\",\n" +" \"spatie/phpunit-watcher\": \"^1.23\",\n" +" \"vimeo/psalm\": \"^4.18\",\n" +" \"yiisoft/psr-dummy-provider\": \"^1.0\",\n" +" \"yiisoft/test-support\": \"^1.3\"\n" +" },\n" +" \"autoload\": {\n" +" \"psr-4\": {\n" +" \"Yiisoft\\\\Yii\\\\Widgets\\\\\": \"src\"\n" +" }\n" +" },\n" +" \"autoload-dev\": {\n" +" \"psr-4\": {\n" +" \"Yiisoft\\\\Yii\\\\Widgets\\\\Tests\\\\\": \"tests\"\n" +" }\n" +" },\n" +" \"extra\": {\n" +" \"branch-alias\": {\n" +" \"dev-master\": \"3.0.x-dev\"\n" +" }\n" +" },\n" +" \"scripts\": {\n" +" \"test\": \"phpunit --testdox --no-interaction\",\n" +" \"test-watch\": \"phpunit-watcher watch\"\n" +" },\n" +" \"config\": {\n" +" \"sort-packages\": true,\n" +" \"allow-plugins\": {\n" +" \"infection/extension-installer\": true,\n" +" \"composer/package-versions-deprecated\": true\n" +" }\n" +" }\n" +"}\n" +msgstr "" + +#. type: Title #### +#: en/structure/package.md +#, no-wrap +msgid "Package Name " +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "Each Composer package should have a package name which uniquely identifies the package among all others. The format of package names is `vendorName/projectName`. For example, in the package name `yiisoft/queue`, the vendor name, and the project name are `yiisoft` and `queue`, respectively." +msgstr "" + +#. type: Plain text +#: en/structure/package.md +#, no-wrap +msgid "" +"> [!WARNING]\n" +"> Don't use `yiisoft` as your vendor name as it's reserved for use by the Yii itself.\n" +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "We recommend you prefix `yii-` to the project name for packages that aren't able to work as general PHP packages and require Yii application. This will allow users to more easily tell whether a package is Yii specific." +msgstr "" + +#. type: Title #### +#: en/structure/package.md +#, no-wrap +msgid "Dependencies " +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "If your extension depends on other packages, you should list them in `require` section of `composer.json`. Make sure you also list appropriate version constraints (e.g. `^1.0`, `@stable`) for each dependent package. Use stable dependencies when your extension is released in a stable version." +msgstr "" + +#. type: Title #### +#: en/structure/package.md +#, no-wrap +msgid "Class Autoloading " +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "In order for your classes to be autoloaded, you should specify the `autoload` entry in the `composer.json` file, like shown below:" +msgstr "" + +#. type: Fenced code block (json) +#: en/structure/package.md +#, no-wrap +msgid "" +"{\n" +" // ....\n" +"\n" +" \"autoload\": {\n" +" \"psr-4\": {\n" +" \"MyVendorName\\\\MyPackageName\\\\\": \"src\"\n" +" }\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "You may list one or multiple root namespaces and their corresponding file paths." +msgstr "" + +#. type: Title ### +#: en/structure/package.md +#, no-wrap +msgid "Recommended Practices " +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "Because packages are meant to be used by other people, you often need to make an extra effort during development. Below, we introduce some common and recommended practices in creating high-quality extensions." +msgstr "" + +#. type: Title #### +#: en/structure/package.md +#, no-wrap +msgid "Testing " +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "You want your package to run flawlessly without bringing problems to other people. To reach this goal, you should test your extension before releasing it to the public." +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "It's recommended that you create various test cases to cover your extension code rather than relying on manual tests. Each time before you release a new version of your package, you may run these test cases to make sure everything is in good shape. For more details, please refer to the [Testing](../testing/overview.md) section." +msgstr "" + +#. type: Title #### +#: en/structure/package.md +#, no-wrap +msgid "Versioning " +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "You should give each release of your extension a version number (e.g. `1.0.1`). We recommend you follow the [semantic versioning](https://semver.org) practice when determining what version numbers should be used." +msgstr "" + +#. type: Title #### +#: en/structure/package.md +#, no-wrap +msgid "Releasing " +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "To let other people know about your package, you need to release it to the public." +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "If it's the first time you're releasing a package, you should register it in a Composer repository, such as [Packagist](https://packagist.org/). After that, all you need to do is create a release tag (for example, `v1.0.1`) on the VCS repository of your extension and notify the Composer repository about the new release. People will then be able to find the new release and install or update the package through the Composer repository." +msgstr "" + +#. type: Plain text +#: en/structure/package.md +msgid "In the release of your package, in addition to code files, you should also consider including the following to help other people learn about and use your extension:" +msgstr "" + +#. type: Bullet: '* ' +#: en/structure/package.md +msgid "A readme file in the package root directory: it describes what your extension does and how to install and use it. We recommend you write it in [Markdown](https://daringfireball.net/projects/markdown/) format and name the file as `README.md`." +msgstr "" + +#. type: Bullet: '* ' +#: en/structure/package.md +msgid "A changelog file in the package root directory: it lists what changes are made in each release. The file may be written in Markdown format and named as `CHANGELOG.md`." +msgstr "" + +#. type: Bullet: '* ' +#: en/structure/package.md +msgid "An upgrade file in the package root directory: it gives the instructions on how to upgrade from older releases of the extension. The file may be written in Markdown format and named as `UPGRADE.md`." +msgstr "" + +#. type: Bullet: '* ' +#: en/structure/package.md +msgid "Tutorials, demos, screenshots, etc.: these are needed if your extension provides many features that can't be fully covered in the readme file." +msgstr "" + +#. type: Bullet: '* ' +#: en/structure/package.md +msgid "API documentation: your code should be well-documented to allow other people to more easily read and understand it." +msgstr "" diff --git a/_translations/guide/po/id/structure_service.md.po b/_translations/guide/po/id/structure_service.md.po new file mode 100644 index 00000000..15cf8628 --- /dev/null +++ b/_translations/guide/po/id/structure_service.md.po @@ -0,0 +1,194 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Bullet: '- ' +#: en/structure/domain.md en/structure/service.md +#, no-wrap +msgid "Entity" +msgstr "" + +#. type: Bullet: '- ' +#: en/structure/domain.md en/structure/service.md +#, no-wrap +msgid "Repository" +msgstr "" + +#. type: Title # +#: en/structure/service.md +#, no-wrap +msgid "Service components" +msgstr "" + +#. type: Plain text +#: en/structure/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) +#: en/structure/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 +#: en/structure/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) +#: en/structure/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 +#: en/structure/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 ## +#: en/structure/service.md +#, no-wrap +msgid "Service dependencies and configuration" +msgstr "" + +#. type: Plain text +#: en/structure/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: '- ' +#: en/structure/service.md +msgid "After the service is created, it shouldn't be re-configured in runtime." +msgstr "" + +#. type: Bullet: '- ' +#: en/structure/service.md +msgid "DI container instance usually **shouldn't** be injected as a dependency. Prefer concrete interfaces." +msgstr "" + +#. type: Bullet: '- ' +#: en/structure/service.md +msgid "In case of complicated or \"heavy\" initialization, try to postpone it until the service method is called." +msgstr "" + +#. type: Plain text +#: en/structure/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) +#: en/structure/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 ## +#: en/structure/service.md +#, no-wrap +msgid "Service methods" +msgstr "" + +#. type: Plain text +#: en/structure/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) +#: en/structure/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 +#: en/structure/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 ## +#: en/structure/service.md +#, no-wrap +msgid "Is everything a service?" +msgstr "" + +#. type: Plain text +#: en/structure/service.md +msgid "Often it makes sense to choose another class type to place your code into. Check:" +msgstr "" + +#. type: Bullet: '- ' +#: en/structure/service.md +msgid "Widget" +msgstr "" + +#. type: Bullet: '- ' +#: en/structure/service.md +msgid "[Middleware](middleware.md)" +msgstr "" diff --git a/_translations/guide/po/id/tutorial_console-applications.md.po b/_translations/guide/po/id/tutorial_console-applications.md.po new file mode 100644 index 00000000..53862c09 --- /dev/null +++ b/_translations/guide/po/id/tutorial_console-applications.md.po @@ -0,0 +1,140 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: en/concept/autoloading.md en/security/best-practices.md +#: en/structure/domain.md en/tutorial/console-applications.md +#, no-wrap +msgid "References" +msgstr "Referensi" + +#. type: Title # +#: en/tutorial/console-applications.md +#, no-wrap +msgid "Console applications" +msgstr "" + +#. type: Plain text +#: en/tutorial/console-applications.md +msgid "Console applications are mainly used to create utility, background processing and maintenance tasks." +msgstr "" + +#. type: Plain text +#: en/tutorial/console-applications.md +msgid "To get support for console application in your project, get `yiisoft/yii-console` via composer:" +msgstr "" + +#. type: Fenced code block +#: en/tutorial/console-applications.md +#, no-wrap +msgid "composer require yiisoft/yii-console\n" +msgstr "" + +#. type: Plain text +#: en/tutorial/console-applications.md +msgid "After it's installed, you can access the entry point as" +msgstr "" + +#. type: Fenced code block +#: en/tutorial/console-applications.md +#, no-wrap +msgid "./yii\n" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/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) +#: en/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 +#: en/tutorial/console-applications.md +msgid "Now register the command in `config/params.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: en/tutorial/console-applications.md +#, no-wrap +msgid "" +"return [\n" +" 'console' => [\n" +" 'commands' => [\n" +" 'demo/hello' => App\\Demo\\HelloCommand::class,\n" +" ],\n" +" ], \n" +"];\n" +msgstr "" + +#. type: Plain text +#: en/tutorial/console-applications.md +msgid "After it's done, the command could be executed as" +msgstr "" + +#. type: Fenced code block +#: en/tutorial/console-applications.md +#, no-wrap +msgid "./yii demo:hello Alice\n" +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/console-applications.md +msgid "[Symfony Console component guide](https://symfony.com/doc/current/components/console.html)" +msgstr "" diff --git a/_translations/guide/po/id/tutorial_mailing.md.po b/_translations/guide/po/id/tutorial_mailing.md.po new file mode 100644 index 00000000..fd96c3b4 --- /dev/null +++ b/_translations/guide/po/id/tutorial_mailing.md.po @@ -0,0 +1,606 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: id\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/guide/po/id/tutorial_performance-tuning.md.po b/_translations/guide/po/id/tutorial_performance-tuning.md.po new file mode 100644 index 00000000..36b0d8bb --- /dev/null +++ b/_translations/guide/po/id/tutorial_performance-tuning.md.po @@ -0,0 +1,343 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" +"PO-Revision-Date: 2025-09-04 11:19+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../../guide/en/tutorial/performance-tuning.md +#, no-wrap +msgid "Performance tuning" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 ## +#: ../../guide/en/tutorial/performance-tuning.md +#, no-wrap +msgid "Optimizing your PHP Environment " +msgstr "" + +#. type: Plain text +#: ../../guide/en/tutorial/performance-tuning.md +msgid "A well-configured PHP environment is important. To get maximum performance:" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/tutorial/performance-tuning.md +msgid "Use the latest stable PHP version. Major releases of PHP may bring significant performance improvements." +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/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: '- ' +#: ../../guide/en/tutorial/performance-tuning.md +msgid "[Tune `realpath()` cache](https://github.com/samdark/realpath_cache_tuner)." +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/tutorial/performance-tuning.md +msgid "Make sure [XDebug](https://xdebug.org/) isn't installed in the production environment." +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/tutorial/performance-tuning.md +msgid "Try [PHP 7 preloading](https://wiki.php.net/rfc/preload)." +msgstr "" + +#. type: Title ## +#: ../../guide/en/tutorial/performance-tuning.md +#, no-wrap +msgid "Optimizing your code " +msgstr "" + +#. type: Plain text +#: ../../guide/en/tutorial/performance-tuning.md +msgid "Beyond environment configuration, there are code-level optimizations that can improve your application's performance:" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/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: '- ' +#: ../../guide/en/tutorial/performance-tuning.md +msgid "[Speeding up array_merge()](https://www.exakat.io/speeding-up-array_merge/)" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/tutorial/performance-tuning.md +msgid "[Move that foreach() inside the method](https://www.exakat.io/move-that-foreach-inside-the-method/)" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/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: '- ' +#: ../../guide/en/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 +#: ../../guide/en/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 ## +#: ../../guide/en/tutorial/performance-tuning.md +#, no-wrap +msgid "Using caching techniques " +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 ## +#: ../../guide/en/tutorial/performance-tuning.md +#, no-wrap +msgid "Optimizing session storage " +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/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) +#: ../../guide/en/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 ## +#: ../../guide/en/tutorial/performance-tuning.md +#, no-wrap +msgid "Optimizing databases " +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/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 +#: ../../guide/en/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 +#: ../../guide/en/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 ## +#: ../../guide/en/tutorial/performance-tuning.md +#, no-wrap +msgid "Optimizing composer autoloader " +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/tutorial/performance-tuning.md +#, no-wrap +msgid "composer dumpautoload -o\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 ## +#: ../../guide/en/tutorial/performance-tuning.md +#, no-wrap +msgid "Processing data offline " +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/tutorial/performance-tuning.md +msgid "There are two methods to process data offline: pull and push." +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/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 ## +#: ../../guide/en/tutorial/performance-tuning.md +#, no-wrap +msgid "Using preloading" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/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 +#: ../../guide/en/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 ### +#: ../../guide/en/tutorial/performance-tuning.md +#, no-wrap +msgid "Preloading benchmarks" +msgstr "" + +#. type: Plain text +#: ../../guide/en/tutorial/performance-tuning.md +msgid "The application template benchmark includes configuring classes to injected dependencies in the bootstrap script." +msgstr "" + +#. type: Plain text +#: ../../guide/en/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) +#: ../../guide/en/tutorial/performance-tuning.md +#, no-wrap +msgid "ab -n 1000 -c 10 -t 10\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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) +#: ../../guide/en/tutorial/performance-tuning.md +#, no-wrap +msgid "composer install --optimize-autoloader --no-dev\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/tutorial/performance-tuning.md +msgid "With preloading enabled, the entire composer class map (825 files) was used:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/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 #### +#: ../../guide/en/tutorial/performance-tuning.md +#, no-wrap +msgid "Test results" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/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 ## +#: ../../guide/en/tutorial/performance-tuning.md +#, no-wrap +msgid "Performance profiling " +msgstr "" + +#. type: Plain text +#: ../../guide/en/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: Bullet: '- ' +#: ../../guide/en/tutorial/performance-tuning.md +msgid "[Yii debug toolbar and debugger](https://github.com/yiisoft/yii2-debug/blob/master/docs/guide/README.md)" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/tutorial/performance-tuning.md +msgid "[Blackfire](https://blackfire.io/)" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/tutorial/performance-tuning.md +msgid "[XHProf](https://secure.php.net/manual/en/book.xhprof.php)" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/tutorial/performance-tuning.md +msgid "[XDebug profiler](https://xdebug.org/docs/profiler)" +msgstr "" diff --git a/_translations/guide/po/id/tutorial_using-with-event-loop.md.po b/_translations/guide/po/id/tutorial_using-with-event-loop.md.po new file mode 100644 index 00000000..00ec392a --- /dev/null +++ b/_translations/guide/po/id/tutorial_using-with-event-loop.md.po @@ -0,0 +1,131 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" +"PO-Revision-Date: 2025-09-04 11:19+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../../guide/en/tutorial/using-with-event-loop.md +#, no-wrap +msgid "Using Yii with event loop" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/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 +#: ../../guide/en/tutorial/using-with-event-loop.md +msgid "There are multiple tools that could be used to achieve it. Notably, [FrankenPHP](https://frankenphp.dev/), [RoadRunner](https://roadrunner.dev/) and [Swoole](https://www.swoole.co.uk/)." +msgstr "" + +#. type: Title ## +#: ../../guide/en/tutorial/using-with-event-loop.md +#, no-wrap +msgid "Event loop implications" +msgstr "" + +#. type: Plain text +#: ../../guide/en/tutorial/using-with-event-loop.md +msgid "Event loop worker basically looks like the following:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/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 +#: ../../guide/en/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 +#: ../../guide/en/tutorial/using-with-event-loop.md +msgid "That means that there's more to consider when developing applications." +msgstr "" + +#. type: Title ### +#: ../../guide/en/tutorial/using-with-event-loop.md +#, no-wrap +msgid "Processing is blocking" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 ### +#: ../../guide/en/tutorial/using-with-event-loop.md +#, no-wrap +msgid "Services and state" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/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) +#: ../../guide/en/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 ## +#: ../../guide/en/tutorial/using-with-event-loop.md +#, no-wrap +msgid "Integrations" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/tutorial/using-with-event-loop.md +msgid "[RoadRunner](using-yii-with-roadrunner.md)" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/tutorial/using-with-event-loop.md +msgid "[Swoole](using-yii-with-swoole.md)" +msgstr "" diff --git a/_translations/guide/po/id/tutorial_using-yii-with-roadrunner.md.po b/_translations/guide/po/id/tutorial_using-yii-with-roadrunner.md.po new file mode 100644 index 00000000..396e6341 --- /dev/null +++ b/_translations/guide/po/id/tutorial_using-yii-with-roadrunner.md.po @@ -0,0 +1,182 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +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: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: en/concept/configuration.md en/tutorial/using-yii-with-roadrunner.md +#: en/views/view-injections.md +#, no-wrap +msgid "Configuration" +msgstr "" + +#. type: Title # +#: en/tutorial/using-yii-with-roadrunner.md +#, no-wrap +msgid "Using Yii with RoadRunner" +msgstr "" + +#. type: Plain text +#: en/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: Title ## +#: en/tutorial/using-yii-with-roadrunner.md +#: en/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "Installation" +msgstr "" + +#. type: Plain text +#: en/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 +#: en/tutorial/using-yii-with-roadrunner.md +#, no-wrap +msgid "composer require yiisoft/yii-runner-roadrunner\n" +msgstr "" + +#. type: Plain text +#: en/tutorial/using-yii-with-roadrunner.md +msgid "After installation is done, run" +msgstr "" + +#. type: Fenced code block +#: en/tutorial/using-yii-with-roadrunner.md +#, no-wrap +msgid "./vendor/bin/rr get\n" +msgstr "" + +#. type: Plain text +#: en/tutorial/using-yii-with-roadrunner.md +msgid "That would download ready to use RoadRunner server `rr` binary." +msgstr "" + +#. type: Plain text +#: en/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) +#: en/tutorial/using-yii-with-roadrunner.md +#, no-wrap +msgid "" +"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" +" num_workers: 4\n" +" max_jobs: 64\n" +" middleware: [\"static\", \"headers\"]\n" +" static:\n" +" dir: \"public\"\n" +" forbid: [\".php\", \".htaccess\"]\n" +" headers:\n" +" response:\n" +" \"Cache-Control\": \"no-cache\"\n" +"\n" +"reload:\n" +" interval: 1s\n" +" patterns: [ \".php\" ]\n" +" services:\n" +" http:\n" +" recursive: true\n" +" dirs: [ \".\" ]\n" +"\n" +"logs:\n" +" mode: production\n" +" level: warn\n" +msgstr "" + +#. type: Plain text +#: en/tutorial/using-yii-with-roadrunner.md +msgid "We're specifying that entry script is `worker.php`, there should be three workers on port 8080, `public` directory files are static ones except `.php` and `.htaccess`. Also, we're sending an additional header." +msgstr "" + +#. type: Plain text +#: en/tutorial/using-yii-with-roadrunner.md +msgid "Create `/worker.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: en/tutorial/using-yii-with-roadrunner.md +#, no-wrap +msgid "" +"run();\n" +msgstr "" + +#. type: Title ## +#: en/tutorial/using-yii-with-roadrunner.md +#: en/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "Starting a server" +msgstr "" + +#. type: Plain text +#: en/tutorial/using-yii-with-roadrunner.md +#: en/tutorial/using-yii-with-swoole.md +msgid "To start a server, execute the following command:" +msgstr "" + +#. type: Fenced code block +#: en/tutorial/using-yii-with-roadrunner.md +#, no-wrap +msgid "./rr serve -d\n" +msgstr "" + +#. type: Title ## +#: en/tutorial/using-yii-with-roadrunner.md +#, no-wrap +msgid "On worker scope" +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/using-yii-with-roadrunner.md +msgid "Each worker's scope is isolated from other workers. Memory isn't shared." +msgstr "" + +#. type: Bullet: '- ' +#: en/tutorial/using-yii-with-roadrunner.md +msgid "A single worker serves multiple requests where the scope is shared." +msgstr "" + +#. type: Bullet: '- ' +#: en/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/guide/po/id/tutorial_using-yii-with-swoole.md.po b/_translations/guide/po/id/tutorial_using-yii-with-swoole.md.po new file mode 100644 index 00000000..e653cfb6 --- /dev/null +++ b/_translations/guide/po/id/tutorial_using-yii-with-swoole.md.po @@ -0,0 +1,196 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" +"PO-Revision-Date: 2025-09-04 11:19+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../../guide/en/tutorial/using-yii-with-roadrunner.md +#: ../../guide/en/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "Installation" +msgstr "" + +#. type: Title ## +#: ../../guide/en/tutorial/using-yii-with-roadrunner.md +#: ../../guide/en/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "Starting a server" +msgstr "" + +#. type: Plain text +#: ../../guide/en/tutorial/using-yii-with-roadrunner.md +#: ../../guide/en/tutorial/using-yii-with-swoole.md +msgid "To start a server, execute the following command:" +msgstr "" + +#. type: Title # +#: ../../guide/en/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "Using Yii with Swoole" +msgstr "" + +#. type: Plain text +#: ../../guide/en/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "" +"[Swoole](https://www.swoole.co.uk/) is a PHP network framework distributed as a PECL extension. It allows you built-in async,\n" +"multiple threads I/O modules. Developers can use sync or async, coroutine API to write the applications.\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/tutorial/using-yii-with-swoole.md +msgid "In the context of Yii, it allows running request handlers 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 +#: ../../guide/en/tutorial/using-yii-with-swoole.md +msgid "Swoole works on Linux and macOS and can be installed via pecl:" +msgstr "" + +#. type: Fenced code block (bash) +#: ../../guide/en/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "pecl install swoole\n" +msgstr "" + +#. type: Title ## +#: ../../guide/en/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "Putting up a server" +msgstr "" + +#. type: Plain text +#: ../../guide/en/tutorial/using-yii-with-swoole.md +msgid "Since Swoole doesn't have built-in PSR-7 support, you need a package fixing so:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "composer require ilexn/swoole-convent-psr7\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/tutorial/using-yii-with-swoole.md +msgid "Create an entry script, `server.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "" +"withDefinitions($config->get('web'))\n" +" ->withProviders($config->get('providers-web'));\n" +"$container = new Container($containerConfig);\n" +"\n" +"$bootstrapList = $config->get('bootstrap-web');\n" +"foreach ($bootstrapList as $callback) {\n" +" if (!(is_callable($callback))) {\n" +" $type = is_object($callback) ? get_class($callback) : gettype($callback);\n" +"\n" +" throw new \\RuntimeException(\"Bootstrap callback must be callable, $type given.\");\n" +" }\n" +" $callback($container);\n" +"}\n" +"\n" +"$application = $container->get(Application::class);\n" +"\n" +"$serverRequestFactory = new \\Ilex\\SwoolePsr7\\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 Swoole\\HTTP\\Server('0.0.0.0', 9501);\n" +"\n" +"$server->on('start', static function (Swoole\\Http\\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 (Swoole\\Http\\Request $request, Swoole\\Http\\Response $response) use ($serverRequestFactory, $application, $container) {\n" +" $psr7Response = null;\n" +" try {\n" +" $requestContainer = clone $container;\n" +" $psr7Request = $serverRequestFactory->createFromSwoole($request);\n" +" $psr7Response = $application->handle($psr7Request);\n" +" \n" +" $converter = new \\Ilex\\SwoolePsr7\\SwooleResponseConverter($response);\n" +" $converter->send($psr7Response);\n" +" } catch (\\Throwable $t) {\n" +" // TODO: render it properly\n" +" $response->end($t->getMessage());\n" +" } finally {\n" +" $application->afterEmit($psr7Response ?? null);\n" +" $container->get(\\Yiisoft\\Di\\StateResetter::class)->reset();\n" +" $container = $requestContainer; \n" +" }\n" +"});\n" +"\n" +"$server->on('shutdown', static function (Swoole\\Http\\Server $server) use ($application) {\n" +" $application->shutdown();\n" +"});\n" +"\n" +"$server->start();\n" +msgstr "" + +#. type: Fenced code block +#: ../../guide/en/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "php server.php\n" +msgstr "" + +#. type: Title ## +#: ../../guide/en/tutorial/using-yii-with-swoole.md +#, no-wrap +msgid "On scope" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 "" diff --git a/_translations/guide/po/id/views_view-injections.md.po b/_translations/guide/po/id/views_view-injections.md.po new file mode 100644 index 00000000..08f21f2d --- /dev/null +++ b/_translations/guide/po/id/views_view-injections.md.po @@ -0,0 +1,189 @@ +# Indonesian translations for PACKAGE package +# Copyright (C) 2025 Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" +"PO-Revision-Date: 2025-09-04 11:19+0500\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title ## +#: ../../guide/en/concept/configuration.md +#: ../../guide/en/tutorial/using-yii-with-roadrunner.md +#: ../../guide/en/views/view-injections.md +#, no-wrap +msgid "Configuration" +msgstr "" + +#. type: Title # +#: ../../guide/en/views/view-injections.md +#, no-wrap +msgid "View injections" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/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) +#: ../../guide/en/views/view-injections.md +#, fuzzy, no-wrap +#| msgid "composer require yiisoft/cache\n" +msgid "composer require yiisoft/yii-view-renderer\n" +msgstr "composer require yiisoft/cache\n" + +#. type: Plain text +#: ../../guide/en/views/view-injections.md +msgid "In config `params.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/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 ## +#: ../../guide/en/views/view-injections.md +#, no-wrap +msgid "New injections" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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) +#: ../../guide/en/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 +#: ../../guide/en/views/view-injections.md +msgid "Add your new Injection to `params.php`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/views/view-injections.md +#, no-wrap +msgid "" +"'yiisoft/yii-view' => [\n" +" 'injections' => [\n" +" ...,\n" +" Reference::to(MyCustomParametersInjection::class),\n" +" ],\n" +" ],\n" +msgstr "" + +#. type: Title ## +#: ../../guide/en/views/view-injections.md +#, no-wrap +msgid "Using Separate Injections for Different Layouts" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 +#: ../../guide/en/views/view-injections.md +msgid "Create your custom ViewInjection for a specific layout:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/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 +#: ../../guide/en/views/view-injections.md +msgid "Add your new injection to `params.php` under specific layout name. In the following example, it is `@layout/cart`:" +msgstr "" + +#. type: Fenced code block (php) +#: ../../guide/en/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 "" + +#. type: Plain text +#: ../../guide/en/views/view-injections.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> [← Template engines](template-engines.md) |\n" +"> [Scripts, styles and metatags →](script-style-meta.md)\n" +msgstr "" diff --git a/guide/po/README.md/ru/README.md.ru.po b/_translations/guide/po/ru/README.md.po similarity index 75% rename from guide/po/README.md/ru/README.md.ru.po rename to _translations/guide/po/ru/README.md.po index 8f44d3be..2f2ab158 100644 --- a/guide/po/README.md/ru/README.md.ru.po +++ b/_translations/guide/po/ru/README.md.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2025-09-04 10:36+0500\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" "PO-Revision-Date: 2025-09-03 17:50+0500\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -17,623 +17,618 @@ 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 # -#: en/README.md +#: ../../guide/en/README.md #, no-wrap msgid "The definitive guide to Yii 3.0" msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "We release this guide under the [Terms of Yii Documentation](https://www.yiiframework.com/license#docs)." msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "Introduction +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[About Yii](intro/what-is-yii.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Upgrading from version 2.0](intro/upgrade-from-v2.md) +" msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "Getting started -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[What do you need to know?](start/prerequisites.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Creating a project](start/creating-project.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Running applications](start/workflow.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Saying hello](start/hello.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Working with forms](start/forms.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Working with databases](start/databases.md) !" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Generating code with Gii](start/gii.md) -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Looking ahead](start/looking-ahead.md) +" msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "Application structure +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Application structure overview](structure/overview.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Entry scripts](structure/entry-script.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Application](structure/application.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Service components](structure/service.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Actions](structure/action.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Domain](structure/domain.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Middleware](structure/middleware.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Packages](structure/package.md) +" msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "Key concepts +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Class autoloading](concept/autoloading.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Dependency injection container](concept/di-container.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Configuration](concept/configuration.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Aliases](concept/aliases.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Events](concept/events.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Immutability](concept/immutability.md) +" msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "Handling requests +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Routing and URL generation](runtime/routing.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Request](runtime/request.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Response](runtime/response.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Sessions](runtime/sessions.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Cookies](runtime/cookies.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Handling errors](runtime/handling-errors.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Logging](runtime/logging.md) +" msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "Views -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Views](views/view.md) -" msgstr "" #. type: Bullet: '* ' -#: en/README.md -msgid "[Widgets](views/widget.md) -" -msgstr "" - -#. type: Bullet: '* ' -#: en/README.md -msgid "[Assets](views/asset.md) -" +#: ../../guide/en/README.md +msgid "[Template engines](views/template-engines.md) -" msgstr "" #. type: Bullet: '* ' -#: en/README.md -msgid "[Working with client scripts](views/client-scripts.md) -" +#: ../../guide/en/README.md +msgid "[View injections](views/view-injections.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md -msgid "[Theming](views/theming.md) -" +#: ../../guide/en/README.md +msgid "[Scripts, styles and metatags](views/script-style-meta.md)" msgstr "" #. type: Bullet: '* ' -#: en/README.md -msgid "[Template engines](views/template-engines.md) -" +#: ../../guide/en/README.md +msgid "[Assets](views/asset.md) -" msgstr "" #. type: Bullet: '* ' -#: en/README.md -msgid "[View injections](views/view-injections.md) +" +#: ../../guide/en/README.md +msgid "[Widgets](views/widget.md) -" msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "Working with databases +-" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Database access objects](db-dao.md): Connecting to a database, basic queries, transactions, and schema manipulation" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Query builder](db-query-builder.md): Querying the database using a simple abstraction layer" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Active record](db-active-record.md): The Active Record ORM, retrieving and manipulating records, and defining relations" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Migrations](databases/db-migrations.md): +" msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "Getting data from users -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Creating forms](input/forms.md) -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Validating input](https://github.com/yiisoft/validator/blob/master/docs/guide/en/README.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Uploading files](input/file-upload.md) -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Collecting tabular input](input/tabular-input.md) -" msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "Displaying data -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Data formatting](output/formatting.md) -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Pagination](output/pagination.md) -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Sorting](output/sorting.md) -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Data providers](output/data-providers.md) -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Data widgets](output/data-widgets.md) -" msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "Security +-" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Security overview](security/overview.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Authentication](security/authentication.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Authorization](security/authorization.md) +-" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Working with passwords](security/passwords.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Cryptography](security/cryptography.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Best practices](security/best-practices.md) +" msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "Caching +-" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Caching overview](caching/overview.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Data caching](caching/data.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Fragment caching](caching/fragment.md) -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Page caching](caching/page.md) -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[HTTP caching](caching/http.md) -" msgstr "" #. type: Title - -#: en/README.md +#: ../../guide/en/README.md #, no-wrap msgid "REST APIs -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Quick start](rest/quick-start.md)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Resources](rest/resources.md)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Controllers](rest/controllers.md)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Routing](rest/routing.md)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Authentication](rest/authentication.md)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Rate limiting](rest/rate-limiting.md)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Versioning](rest/versioning.md)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Error handling](rest/error-handling.md)" msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "Development tools -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "Debug toolbar and debugger" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "Generating code using Gii" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "Generating API documentation" msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "Testing -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Testing overview](testing/overview.md)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Testing environment setup](testing/environment-setup.md)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Unit tests](testing/unit.md)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Functional tests](testing/functional.md)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Acceptance tests](testing/acceptance.md)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Fixtures](testing/fixtures.md)" msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "Special topics -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Building application from scratch](tutorial/start-from-scratch.md) -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Console applications](tutorial/console-applications.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Docker](tutorial/docker.md) -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Internationalization](tutorial/i18n.md) -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Mailing](tutorial/mailing.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Performance tuning](tutorial/performance-tuning.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Using Yii with event loop](tutorial/using-with-event-loop.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Using Yii with RoadRunner](tutorial/using-yii-with-roadrunner.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Using Yii with Swoole](tutorial/using-yii-with-swoole.md) +" msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "Widgets -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[GridView](https://www.yiiframework.com/doc-2.0/yii-grid-gridview.html)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[ListView](https://www.yiiframework.com/doc-2.0/yii-widgets-listview.html)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[DetailView](https://www.yiiframework.com/doc-2.0/yii-widgets-detailview.html)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[ActiveForm](https://www.yiiframework.com/doc-2.0/guide-input-forms.html#activerecord-based-forms-activeform)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Menu](https://www.yiiframework.com/doc-2.0/yii-widgets-menu.html)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[LinkPager](https://www.yiiframework.com/doc-2.0/yii-widgets-linkpager.html)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[LinkSorter](https://www.yiiframework.com/doc-2.0/yii-widgets-linksorter.html)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Bootstrap widgets](https://www.yiiframework.com/extension/yiisoft/yii2-bootstrap/doc/guide)" msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "Helpers +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Arrays](https://github.com/yiisoft/arrays/)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Files](https://github.com/yiisoft/files/)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Html](https://github.com/yiisoft/html/)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Json](https://github.com/yiisoft/json)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Network utilities](https://github.com/yiisoft/network-utilities/)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[VarDumper](https://github.com/yiisoft/var-dumper)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Strings](https://github.com/yiisoft/strings)" msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "Extras +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Glossary](glossary.md)" msgstr "" diff --git a/guide/po/caching_data.md/ru/caching_data.md.ru.po b/_translations/guide/po/ru/caching_data.md.po similarity index 82% rename from guide/po/caching_data.md/ru/caching_data.md.ru.po rename to _translations/guide/po/ru/caching_data.md.po index 4b0147e8..9e5206f9 100644 --- a/guide/po/caching_data.md/ru/caching_data.md.ru.po +++ b/_translations/guide/po/ru/caching_data.md.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2025-09-04 11:19+0500\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" "PO-Revision-Date: 2025-09-04 11:19+0500\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -17,35 +17,35 @@ 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 # -#: en/caching/data.md +#: ../../guide/en/caching/data.md #, no-wrap msgid "Data caching" msgstr "" #. type: Plain text -#: en/caching/data.md +#: ../../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 -#: en/caching/data.md +#: ../../guide/en/caching/data.md msgid "To use cache, install [yiisoft/cache](https://github.com/yiisoft/cache) package:" msgstr "" #. type: Fenced code block (shell) -#: en/caching/data.md +#: ../../guide/en/caching/data.md #, fuzzy, no-wrap #| msgid "composer install yiisoft/security\n" msgid "composer require yiisoft/cache\n" msgstr "composer install yiisoft/security\n" #. type: Plain text -#: en/caching/data.md +#: ../../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) -#: en/caching/data.md +#: ../../guide/en/caching/data.md #, no-wrap msgid "" "public function getTopProducts(\\Yiisoft\\Cache\\CacheInterface $cache): array\n" @@ -54,7 +54,7 @@ msgid "" " \n" " // Try retrieving $data from cache.\n" " $data = $cache->getOrSet($key, function (\\Psr\\SimpleCache\\CacheInterface $cache) use ($count) {\n" -" // Can't find $data in cache, calculate it from scratch.\n" +" // Can't find $data in a cache, calculate it from scratch.\n" " return getTopProductsFromDatabase($count);\n" " }, 3600);\n" " \n" @@ -63,73 +63,77 @@ msgid "" msgstr "" #. type: Plain text -#: en/caching/data.md +#: ../../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 -#: en/caching/data.md +#: ../../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 ## -#: en/caching/data.md +#: ../../guide/en/caching/data.md #, no-wrap msgid "Cache handlers" msgstr "" #. type: Plain text -#: en/caching/data.md +#: ../../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 -#: en/caching/data.md +#: ../../guide/en/caching/data.md msgid "Yii provides the following handlers:" msgstr "" #. type: Bullet: '- ' -#: en/caching/data.md +#: ../../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: '- ' -#: en/caching/data.md +#: ../../guide/en/caching/data.md msgid "`ArrayCache` — provides caching for the current request only by storing the values in an array." msgstr "" #. type: Bullet: '- ' -#: en/caching/data.md +#: ../../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: '- ' -#: en/caching/data.md +#: ../../guide/en/caching/data.md msgid "[Database](https://github.com/yiisoft/cache-db) — uses a database table to store cached data." msgstr "" #. type: Bullet: '- ' -#: en/caching/data.md +#: ../../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: '- ' -#: 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 distributed application (e.g., with several servers, load balancers, etc.)" +#: ../../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: Bullet: '- ' -#: en/caching/data.md -msgid "[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." +#. 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 -#: en/caching/data.md +#: ../../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 -#: en/caching/data.md +#: ../../guide/en/caching/data.md #, no-wrap msgid "" "> [!TIP]\n" @@ -139,43 +143,43 @@ msgid "" msgstr "" #. type: Plain text -#: en/caching/data.md +#: ../../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 -#: en/caching/data.md +#: ../../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 ### -#: en/caching/data.md +#: ../../guide/en/caching/data.md #, no-wrap msgid "Cache keys" msgstr "" #. type: Plain text -#: en/caching/data.md +#: ../../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 -#: en/caching/data.md +#: ../../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 -#: en/caching/data.md +#: ../../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 -#: en/caching/data.md +#: ../../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) -#: en/caching/data.md +#: ../../guide/en/caching/data.md #, no-wrap msgid "" "$arrayCacheWithPrefix = new \\Yiisoft\\Cache\\PrefixedCache(new \\Yiisoft\\Cache\\ArrayCache(), 'myapp_');\n" @@ -183,18 +187,18 @@ msgid "" msgstr "" #. type: Title ### -#: en/caching/data.md +#: ../../guide/en/caching/data.md #, no-wrap msgid "Cache expiration" msgstr "" #. type: Plain text -#: en/caching/data.md +#: ../../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) -#: en/caching/data.md +#: ../../guide/en/caching/data.md #, no-wrap msgid "" "$ttl = 3600;\n" @@ -204,50 +208,50 @@ msgid "" msgstr "" #. type: Plain text -#: en/caching/data.md +#: ../../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 -#: en/caching/data.md -msgid "You may set default TTL for the cache:" +#: ../../guide/en/caching/data.md +msgid "You may set the default TTL for the cache:" msgstr "" #. type: Fenced code block (php) -#: en/caching/data.md +#: ../../guide/en/caching/data.md #, no-wrap msgid "$cache = new \\Yiisoft\\Cache\\Cache($arrayCache, 60 * 60); // 1 hour\n" msgstr "" #. type: Plain text -#: en/caching/data.md +#: ../../guide/en/caching/data.md msgid "Additionally, you can invalidate a cache key explicitly:" msgstr "" #. type: Fenced code block (php) -#: en/caching/data.md +#: ../../guide/en/caching/data.md #, no-wrap msgid "$cache->remove($key);\n" msgstr "" #. type: Title ### -#: en/caching/data.md +#: ../../guide/en/caching/data.md #, no-wrap msgid "Invalidation dependencies" msgstr "" #. type: Plain text -#: en/caching/data.md +#: ../../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 -#: en/caching/data.md +#: ../../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) -#: en/caching/data.md +#: ../../guide/en/caching/data.md #, no-wrap msgid "" "/**\n" @@ -266,58 +270,58 @@ msgid "" msgstr "" #. type: Plain text -#: en/caching/data.md +#: ../../guide/en/caching/data.md msgid "Below is a summary of the available cache dependencies:" msgstr "" #. type: Bullet: '- ' -#: en/caching/data.md +#: ../../guide/en/caching/data.md msgid "`\\Yiisoft\\Cache\\Dependency\\ValueDependency`: invalidates the cache when specified value changes." msgstr "" #. type: Bullet: '- ' -#: en/caching/data.md +#: ../../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: '- ' -#: en/caching/data.md +#: ../../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: '- ' -#: en/caching/data.md +#: ../../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 -#: en/caching/data.md +#: ../../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 -#: en/caching/data.md +#: ../../guide/en/caching/data.md msgid "To implement your own dependency, extend from `\\Yiisoft\\Cache\\Dependency\\Dependency`." msgstr "" #. type: Title ### -#: en/caching/data.md +#: ../../guide/en/caching/data.md #, no-wrap msgid "Cache stampede prevention" msgstr "" #. type: Plain text -#: en/caching/data.md +#: ../../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 -#: 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." +#: ../../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) -#: en/caching/data.md +#: ../../guide/en/caching/data.md #, no-wrap msgid "" "/**\n" diff --git a/guide/po/caching_overview.md/ru/caching_overview.md.ru.po b/_translations/guide/po/ru/caching_overview.md.po similarity index 100% rename from guide/po/caching_overview.md/ru/caching_overview.md.ru.po rename to _translations/guide/po/ru/caching_overview.md.po diff --git a/guide/po/concept_aliases.md/ru/concept_aliases.md.ru.po b/_translations/guide/po/ru/concept_aliases.md.po similarity index 100% rename from guide/po/concept_aliases.md/ru/concept_aliases.md.ru.po rename to _translations/guide/po/ru/concept_aliases.md.po diff --git a/guide/po/concept_autoloading.md/ru/concept_autoloading.md.ru.po b/_translations/guide/po/ru/concept_autoloading.md.po similarity index 100% rename from guide/po/concept_autoloading.md/ru/concept_autoloading.md.ru.po rename to _translations/guide/po/ru/concept_autoloading.md.po diff --git a/guide/po/concept_configuration.md/ru/concept_configuration.md.ru.po b/_translations/guide/po/ru/concept_configuration.md.po similarity index 100% rename from guide/po/concept_configuration.md/ru/concept_configuration.md.ru.po rename to _translations/guide/po/ru/concept_configuration.md.po diff --git a/guide/po/concept_di-container.md/ru/concept_di-container.md.ru.po b/_translations/guide/po/ru/concept_di-container.md.po similarity index 91% rename from guide/po/concept_di-container.md/ru/concept_di-container.md.ru.po rename to _translations/guide/po/ru/concept_di-container.md.po index 4ce7c00b..2682655f 100644 --- a/guide/po/concept_di-container.md/ru/concept_di-container.md.ru.po +++ b/_translations/guide/po/ru/concept_di-container.md.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" -"POT-Creation-Date: 2025-09-05 12:06+0000\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" "PO-Revision-Date: 2025-09-04 07:50+0500\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -18,29 +18,29 @@ msgstr "" "X-Generator: Poedit 3.7\n" #. type: Title # -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md #, no-wrap msgid "Dependency injection and container" msgstr "Внедрение зависимостей и контейнер внедрения зависимостей" #. type: Title ## -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md #, no-wrap msgid "Dependency injection " msgstr "Внедрение зависимостей " #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "There are two ways of re-using things in OOP: inheritance and composition." msgstr "В ООП существует два способа повторного использования кода: наследование и композиция." #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "Inheritance is simple:" msgstr "Наследование — это просто:" #. type: Fenced code block (php) -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md #, no-wrap msgid "" "class Cache\n" @@ -84,17 +84,19 @@ msgstr "" "}\n" #. type: Plain text -#: en/concept/di-container.md -msgid "The issue here is that these two are becoming unnecessarily coupled or inter-dependent making them more fragile." +#: ../../guide/en/concept/di-container.md +#, fuzzy +#| msgid "The issue here is that these two are becoming unnecessarily coupled or inter-dependent making them more fragile." +msgid "The issue here is that these two are becoming unnecessarily coupled or inter-dependent, making them more fragile." msgstr "Проблема здесь в том, что эти два класса становятся излишне сопряженными или взаимозависимыми, что делает их более хрупкими." #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "Another way to handle this is composition:" msgstr "Есть способ справиться с этой проблемой — композиция:" #. type: Fenced code block (php) -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md #, no-wrap msgid "" "interface CacheInterface\n" @@ -161,84 +163,84 @@ msgstr "" "}\n" #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "We've avoided unnecessary inheritance and used interface to reduce coupling. You can replace cache implementation without changing `CachedWidget` so it's becoming more stable." msgstr "" "Мы избежали ненужного наследования и использовали интерфейс, чтобы уменьшить сопряженность.\n" "Вы можете заменить реализацию кэша без изменения класса `CachedWidget`, поэтому он становится более стабильным." #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "The `CacheInterface` here is a dependency: an object another object depends on. The process of putting an instance of dependency into an object (`CachedWidget`) is called dependency injection. There are many ways to perform it:" msgstr "" "Здесь `CacheInterface` это зависимость — объект, от которого зависит другой объект. \n" "Процесс помещения экземпляра объекта зависимости в объект (`CachedWidget`) называется внедрением зависимости. Существует множество способов его реализации:" #. type: Bullet: '- ' -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "Constructor injection. Best for mandatory dependencies." msgstr "Внедрение через конструктор. Лучше всего подходит для обязательных зависимостей." #. type: Bullet: '- ' -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "Method injection. Best for optional dependencies." msgstr "Через метод. Лучше использовать для необязательных зависимостей." #. type: Bullet: '- ' -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "Property injection. Better to be avoided in PHP except maybe data transfer objects." msgstr "Через свойство. Лучше избегать использования в PHP, за исключением, может быть, объектов передачи данных (DTO)" #. type: Title ### -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md #, fuzzy, no-wrap #| msgid "References " msgid "Why use private properties " msgstr "Полезные ссылки " #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "In the composition example above, note that the `$cache` property is declared as `private`." msgstr "" #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/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 -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "This design choice provides several benefits:" msgstr "" #. type: Bullet: '- ' -#: en/concept/di-container.md +#: ../../guide/en/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: '- ' -#: en/concept/di-container.md +#: ../../guide/en/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: '- ' -#: en/concept/di-container.md +#: ../../guide/en/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: '- ' -#: en/concept/di-container.md +#: ../../guide/en/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 ## -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md #, no-wrap msgid "DI container " msgstr "Контейнер внедрения зависимостей " #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md #, fuzzy #| msgid "Injecting basic dependencies is simple and easy. 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." 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." @@ -247,7 +249,7 @@ msgstr "" "Вы выбираете место, где вас не волнуют зависимости, которые обычно являются обработчиками действий и которые вы не собираетесь тестировать, создаете экземпляры необходимых зависимостей и передаете их в зависимые классы." #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md #, fuzzy #| msgid "It works well when there aren't many 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 hard to debug mistakes." 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." @@ -256,7 +258,7 @@ msgstr "" "Когда их много, и каждая зависимость сама имеет зависимости, создание всей иерархии становится утомительным процессом, который требует большого количества кода и может привести к трудно отлаживаемым ошибкам." #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md #, fuzzy #| msgid "Additionally, lots of dependencies, such as certain third party API wrapper, are the same for any class using it. So it makes sense to:" 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:" @@ -265,24 +267,24 @@ msgstr "" "Поэтому имеет смысл:" #. type: Bullet: '- ' -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md #, fuzzy #| msgid "Define how to instantiate such API wrapper once." msgid "Define how to instantiate such an API wrapper." msgstr "Определить, как создать экземпляр такой обертки API один раз." #. type: Bullet: '- ' -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "Instantiate it when required and only once per request." msgstr "Создавать его экземпляр при необходимости и только один раз за запрос." #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "That's what dependency containers are for." msgstr "Именно для этого нужны контейнеры зависимостей." #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "A dependency injection (DI) container is an object that knows how to instantiate and configure objects and all their dependent objects. [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." msgstr "" "Контейнер внедрения зависимостей (DI-контейнер) — это объект, который знает, как создавать и настраивать объекты и все зависимые от них объекты.\n" @@ -290,18 +292,18 @@ msgstr "" "Здесь мы в основном поясним использование DI-контейнера, предоставляемого Yii." #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/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 "Yii реализует DI-контейнер через пакет [yiisoft/di](https://github.com/yiisoft/di) и [yiisoft/injector](https://github.com/yiisoft/injector)." #. type: Title ### -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md #, no-wrap msgid "Configuring container " msgstr "Конфигурирование контейнера " #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/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 "" "Поскольку для создания нового объекта вам нужны его зависимости, вам следует зарегестрировать их как можно раньше.\n" @@ -309,7 +311,7 @@ msgstr "" "Например, для следующего сервиса:" #. type: Fenced code block (php) -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md #, no-wrap msgid "" "final class MyService implements MyServiceInterface\n" @@ -336,12 +338,12 @@ msgstr "" " }\n" #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "configuration could be:" msgstr "конфигурация может быть:" #. type: Fenced code block (php) -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md #, no-wrap msgid "" "return [\n" @@ -361,12 +363,12 @@ msgstr "" "];\n" #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "That's equal to the following:" msgstr "Это соответствует:" #. type: Fenced code block (php) -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md #, no-wrap msgid "" "$myService = new MyService(42);\n" @@ -376,12 +378,12 @@ msgstr "" "$myService->setDiscount(10);\n" #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "There are extra methods of declaring dependencies:" msgstr "Существуют дополнительные методы объявления зависимостей:" #. type: Fenced code block (php) -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md #, no-wrap msgid "" "return [\n" @@ -433,25 +435,25 @@ msgstr "" "];\n" #. type: Title ### -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md #, no-wrap msgid "Injecting dependencies " msgstr "Внедрение зависимостей " #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md #, fuzzy #| msgid "Directly referencing container in a class is a bad idea since the code becomes non-generic, coupled to 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." 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 "Непосредственное обращение к контейнеру в классе — плохая идея, так как код становится не универсальным, сопряжен с интерфейсом контейнера и, что еще хуже, зависимости становятся скрытыми. Поэтому Yii инвертирует управление, автоматически вводя объекты из контейнера в конструкторы и методы, основываясь на типах аргументов." #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "This is primarily done in constructor and handing method of action handlers:" msgstr "В основном это делается в конструкторе и методе, обрабатывающем действие:" #. type: Fenced code block (php) -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md #, no-wrap msgid "" "use \\Yiisoft\\Cache\\CacheInterface;\n" @@ -500,7 +502,7 @@ msgstr "" "}\n" #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md #, fuzzy #| 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, get dependencies of these types from a container and pass 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, 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." 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." @@ -511,12 +513,12 @@ msgstr "" "Достаточно объявить нужную вам зависимость, и она будет получена из контейнера автоматически." #. type: Title ## -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md #, no-wrap msgid "References " msgstr "Полезные ссылки " #. type: Bullet: '- ' -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "[Inversion of Control Containers and the Dependency Injection pattern by Martin Fowler](https://martinfowler.com/articles/injection.html)" msgstr "[Inversion of Control Containers and the Dependency Injection pattern Мартина Фаулера](https://martinfowler.com/articles/injection.html)" diff --git a/guide/po/concept_events.md/ru/concept_events.md.ru.po b/_translations/guide/po/ru/concept_events.md.po similarity index 100% rename from guide/po/concept_events.md/ru/concept_events.md.ru.po rename to _translations/guide/po/ru/concept_events.md.po diff --git a/guide/po/concept_immutability.md/ru/concept_immutability.md.ru.po b/_translations/guide/po/ru/concept_immutability.md.po similarity index 88% rename from guide/po/concept_immutability.md/ru/concept_immutability.md.ru.po rename to _translations/guide/po/ru/concept_immutability.md.po index a6ba0b22..449b6936 100644 --- a/guide/po/concept_immutability.md/ru/concept_immutability.md.ru.po +++ b/_translations/guide/po/ru/concept_immutability.md.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2025-09-04 11:19+0500\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" "PO-Revision-Date: 2025-09-04 11:19+0500\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -17,24 +17,24 @@ 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 # -#: en/concept/immutability.md +#: ../../guide/en/concept/immutability.md #, no-wrap msgid "Immutability" msgstr "" #. type: Plain text -#: en/concept/immutability.md +#: ../../guide/en/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 ## -#: en/concept/immutability.md +#: ../../guide/en/concept/immutability.md #, no-wrap msgid "Mutable pitfalls (what we avoid)" msgstr "" #. type: Fenced code block (php) -#: en/concept/immutability.md +#: ../../guide/en/concept/immutability.md #, no-wrap msgid "" "// A shared base query built once and reused:\n" @@ -49,18 +49,18 @@ msgid "" msgstr "" #. type: Title ## -#: en/concept/immutability.md +#: ../../guide/en/concept/immutability.md #, no-wrap msgid "Creating an immutable object in PHP" msgstr "" #. type: Plain text -#: en/concept/immutability.md +#: ../../guide/en/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) -#: en/concept/immutability.md +#: ../../guide/en/concept/immutability.md #, no-wrap msgid "" "final class Money\n" @@ -138,17 +138,17 @@ msgid "" msgstr "" #. type: Bullet: '- ' -#: en/concept/immutability.md +#: ../../guide/en/concept/immutability.md msgid "We mark the class `final` to prevent subclass mutations; alternatively, design for extension carefully." msgstr "" #. type: Bullet: '- ' -#: en/concept/immutability.md +#: ../../guide/en/concept/immutability.md msgid "Validate in the constructor and `with*` methods so every instance is always valid." msgstr "" #. type: Plain text -#: en/concept/immutability.md +#: ../../guide/en/concept/immutability.md #, no-wrap msgid "" "> [!TIP]\n" @@ -157,23 +157,23 @@ msgid "" msgstr "" #. type: Title ## -#: en/concept/immutability.md +#: ../../guide/en/concept/immutability.md #, no-wrap -msgid "Using clone (and why it is cheap)" +msgid "Using clone (and why it is inexpensive)" msgstr "" #. type: Plain text -#: en/concept/immutability.md +#: ../../guide/en/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 -#: en/concept/immutability.md +#: ../../guide/en/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) -#: en/concept/immutability.md +#: ../../guide/en/concept/immutability.md #, no-wrap msgid "" "final class Order\n" @@ -203,22 +203,22 @@ msgid "" msgstr "" #. type: Title ## -#: en/concept/immutability.md +#: ../../guide/en/concept/immutability.md #, no-wrap msgid "Usage style" msgstr "" #. type: Bullet: '- ' -#: en/concept/immutability.md +#: ../../guide/en/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: '- ' -#: en/concept/immutability.md +#: ../../guide/en/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 -#: en/concept/immutability.md +#: ../../guide/en/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/guide/po/databases_db-migrations.md/ru/databases_db-migrations.md.ru.po b/_translations/guide/po/ru/databases_db-migrations.md.po similarity index 77% rename from guide/po/databases_db-migrations.md/ru/databases_db-migrations.md.ru.po rename to _translations/guide/po/ru/databases_db-migrations.md.po index 04de7706..5c4091b7 100644 --- a/guide/po/databases_db-migrations.md/ru/databases_db-migrations.md.ru.po +++ b/_translations/guide/po/ru/databases_db-migrations.md.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2025-09-04 11:19+0500\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" "PO-Revision-Date: 2025-09-04 11:19+0500\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -17,36 +17,36 @@ 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 # -#: en/databases/db-migrations.md +#: ../../guide/en/databases/db-migrations.md #, no-wrap msgid "Migrations" msgstr "" #. type: Plain text -#: en/databases/db-migrations.md +#: ../../guide/en/databases/db-migrations.md msgid "To use migrations, install [yiisoft/db-migration](https://github.com/yiisoft/db-migration/) package:" msgstr "" #. type: Fenced code block (shell) -#: en/databases/db-migrations.md +#: ../../guide/en/databases/db-migrations.md #, fuzzy, no-wrap #| msgid "composer install yiisoft/security\n" msgid "composer require yiisoft/db-migration\n" msgstr "composer install yiisoft/security\n" #. type: Title ### -#: en/databases/db-migrations.md +#: ../../guide/en/databases/db-migrations.md #, no-wrap msgid "Example usage" msgstr "" #. type: Plain text -#: en/databases/db-migrations.md -msgid "First, configure DI container. Create `config/common/db.php` with the following content:" +#: ../../guide/en/databases/db-migrations.md +msgid "First, configure a DI container. Create `config/common/db.php` with the following content:" msgstr "" #. type: Fenced code block (php) -#: en/databases/db-migrations.md +#: ../../guide/en/databases/db-migrations.md #, no-wrap msgid "" "=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#. type: Title # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "A" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, fuzzy, no-wrap +#| msgid "Aliases" +msgid "alias" +msgstr "Псевдонимы (алиасы)" + +#. type: Plain text +#: ../../guide/en/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 ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "asset" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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." +msgstr "" + +#. type: Title # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "C" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, fuzzy, no-wrap +msgid "configuration" +msgstr "конфигурация может быть:" + +#. type: Plain text +#: ../../guide/en/glossary.md +msgid "The 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 # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "D" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "DI" +msgstr "" + +#. type: Plain text +#: ../../guide/en/glossary.md +msgid "Dependency Injection is a programming technique where an object injects a dependent object. [\"DI\"](concept/di-container.md)" +msgstr "" + +#. type: Title # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "I" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "installation" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "M" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "middleware" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "module" +msgstr "" + +#. type: Plain text +#: ../../guide/en/glossary.md +msgid "The module is a sub-application that groups some code based on a use-case. It's typically used within the main application and may contain URL handlers or console commands." +msgstr "" + +#. type: Title # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "N" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "namespace" +msgstr "" + +#. type: Plain text +#: ../../guide/en/glossary.md +#, fuzzy +#| msgid "[PHP manual: security](https://www.php.net/manual/en/security.php)" +msgid "Namespace refers to a [PHP language feature](https://www.php.net/manual/en/language.namespaces.php)." +msgstr "[Руководство по PHP: безопасность](https://www.php.net/manual/en/security.php)" + +#. type: Title # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "P" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "package" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 package manager." +msgstr "" + +#. type: Title # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "R" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "rule" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "Q" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "queue" +msgstr "" + +#. type: Plain text +#: ../../guide/en/glossary.md +msgid "A queue is similar to a stack. Queue follows First-In-First-Out methodology." +msgstr "" + +#. type: Title # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "V" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "vendor" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 "" diff --git a/guide/po/intro_upgrade-from-v2.md/ru/intro_upgrade-from-v2.md.ru.po b/_translations/guide/po/ru/intro_upgrade-from-v2.md.po similarity index 100% rename from guide/po/intro_upgrade-from-v2.md/ru/intro_upgrade-from-v2.md.ru.po rename to _translations/guide/po/ru/intro_upgrade-from-v2.md.po diff --git a/guide/po/intro_what-is-yii.md/ru/intro_what-is-yii.md.ru.po b/_translations/guide/po/ru/intro_what-is-yii.md.po similarity index 89% rename from guide/po/intro_what-is-yii.md/ru/intro_what-is-yii.md.ru.po rename to _translations/guide/po/ru/intro_what-is-yii.md.po index 3d25b3a9..0a362099 100644 --- a/guide/po/intro_what-is-yii.md/ru/intro_what-is-yii.md.ru.po +++ b/_translations/guide/po/ru/intro_what-is-yii.md.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" -"POT-Creation-Date: 2025-09-04 07:51+0500\n" -"PO-Revision-Date: 2025-09-04 07:58+0500\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" +"PO-Revision-Date: 2025-09-11 10:24+0500\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: ru\n" @@ -18,13 +18,13 @@ msgstr "" "X-Generator: Poedit 3.7\n" #. type: Title # -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md #, no-wrap msgid "What is Yii" msgstr "Что такое Yii?" #. type: Plain text -#: en/intro/what-is-yii.md +#: ../../guide/en/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 "" "Yii – это высокопроизводительный пакетный PHP фреймворк, предназначенный для разработки современных веб-приложений. \n" @@ -32,13 +32,13 @@ msgstr "" "Также Yii может расшифровываться как акроним **Yes It Is**!" #. type: Title ## -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md #, no-wrap msgid "What's Yii best for" msgstr "Для каких задач больше всего подходит Yii?" #. type: Plain text -#: en/intro/what-is-yii.md +#: ../../guide/en/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 "" "Yii – это универсальный веб-фреймворк.\n" @@ -46,53 +46,53 @@ msgstr "" "Благодаря его архитектуре и отличной поддержке кеширования, фреймворк особенно подходит для разработки таких крупных проектов, как порталы, CMS, магазины или RESTful-приложения." #. type: Title ## -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md #, no-wrap msgid "How does Yii compare with other frameworks?" msgstr "Сравнение Yii с другими фреймворками" #. type: Plain text -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md msgid "If you're already familiar with another framework, you may appreciate knowing how Yii compares:" msgstr "Если вы уже знакомы с другими фреймворками, вам наверняка будет интересно сравнить их с Yii:" #. type: Bullet: '- ' -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md msgid "Yii takes the [philosophy of being practical and helpful](https://github.com/yiisoft/docs/blob/master/001-yii-values.md) achieving:" msgstr "Yii придерживается [философии практичности и полезности] (https://github.com/yiisoft/docs/blob/master/001-yii-values.md), достигая следующего:" #. type: Bullet: ' - ' -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md msgid "Performance in both development and execution." msgstr "Производительность как в разработке, так и во время выполнения." #. type: Bullet: ' - ' -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md msgid "Convenient customizable defaults." msgstr "Удобные изменяемые настройки по-умолчанию." #. type: Bullet: ' - ' -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md msgid "Practice-orientation." msgstr "Практикоориентированность." #. type: Bullet: ' - ' -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md msgid "Simplicity." msgstr "Простота." #. type: Bullet: ' - ' -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md msgid "Explicitness." msgstr "Ясность." #. type: Bullet: ' - ' -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md msgid "Consistency." msgstr "Согласованность." #. type: Plain text -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md #, no-wrap msgid "" " Yii will never try to over-design things mainly to follow some design patterns.\n" @@ -112,49 +112,49 @@ msgstr "" "- Одна из главных целей Yii – производительность.\n" #. type: Plain text -#: en/intro/what-is-yii.md +#: ../../guide/en/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 "Yii разрабатывается [сильной командой разработчиков](https://www.yiiframework.com/team/), финансируемой [фондом OpenCollective](https://opencollective.com/yiisoft), и большим сообществом, которое ей помогает. Авторы фреймворка следят за тенденциями веб-разработки и развитием других проектов. Наиболее подходящие возможности и лучшие практики регулярно внедряются во фреймворк в виде простых и элегантных интерфейсов." #. type: Title ## -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md #, no-wrap msgid "Yii versions" msgstr "Версии Yii" #. type: Plain text -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md msgid "Yii currently has three major versions available: 1.1, 2.0, and 3.0." msgstr "В настоящее время доступны три основные ветки: 1.1, 2.0 и 3.0." #. type: Bullet: '- ' -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md msgid "Version 1.1 is the old generation and is now in the feature freeze bugfix mode." msgstr "Ветка 1.1 является предыдущим поколением и находится в состоянии исправления ошибок и заморозки добавления новой функциональности." #. type: Bullet: '- ' -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md msgid "Version 2.0 is a current stable version in the feature freeze bugfix mode." msgstr "Ветка 2.0 — текущая стабильная версия. Находится в состоянии исправления ошибок и заморозки добавления новой функциональности." #. type: Bullet: '- ' -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md msgid "Version 3.0 is the current version in development. This guide is mainly about version 3." msgstr "Ветка 3.0 — текущая разрабатываемая версия. Данное руководство именно о версии 3.0." #. type: Title ## -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md #, no-wrap msgid "Requirements and prerequisites" msgstr "Требования к ПО и знаниям" #. type: Plain text -#: en/intro/what-is-yii.md -msgid "Yii3 requires PHP 8.2 or above, but some packages also older PHP such as PHP 7.4." -msgstr "Yii3 требует PHP 8.2 или выше, но некоторые пакеты также поддерживают PHP 7.4." +#: ../../guide/en/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 "Yii3 требует PHP 8.2 или выше, но некоторые пакеты работают со старыми версиями PHP, такими как PHP 7.4." #. type: Plain text -#: en/intro/what-is-yii.md +#: ../../guide/en/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 "" "Для разработки на Yii потребуется общее понимание объектно-ориентированного программирования (ООП), так как фреймворк\n" diff --git a/guide/po/runtime_cookies.md/ru/runtime_cookies.md.ru.po b/_translations/guide/po/ru/runtime_cookies.md.po similarity index 100% rename from guide/po/runtime_cookies.md/ru/runtime_cookies.md.ru.po rename to _translations/guide/po/ru/runtime_cookies.md.po diff --git a/guide/po/runtime_handling-errors.md/ru/runtime_handling-errors.md.ru.po b/_translations/guide/po/ru/runtime_handling-errors.md.po similarity index 100% rename from guide/po/runtime_handling-errors.md/ru/runtime_handling-errors.md.ru.po rename to _translations/guide/po/ru/runtime_handling-errors.md.po diff --git a/guide/po/runtime_logging.md/ru/runtime_logging.md.ru.po b/_translations/guide/po/ru/runtime_logging.md.po similarity index 100% rename from guide/po/runtime_logging.md/ru/runtime_logging.md.ru.po rename to _translations/guide/po/ru/runtime_logging.md.po diff --git a/guide/po/runtime_request.md/ru/runtime_request.md.ru.po b/_translations/guide/po/ru/runtime_request.md.po similarity index 100% rename from guide/po/runtime_request.md/ru/runtime_request.md.ru.po rename to _translations/guide/po/ru/runtime_request.md.po diff --git a/guide/po/runtime_response.md/ru/runtime_response.md.ru.po b/_translations/guide/po/ru/runtime_response.md.po similarity index 100% rename from guide/po/runtime_response.md/ru/runtime_response.md.ru.po rename to _translations/guide/po/ru/runtime_response.md.po diff --git a/guide/po/runtime_routing.md/ru/runtime_routing.md.ru.po b/_translations/guide/po/ru/runtime_routing.md.po similarity index 100% rename from guide/po/runtime_routing.md/ru/runtime_routing.md.ru.po rename to _translations/guide/po/ru/runtime_routing.md.po diff --git a/guide/po/runtime_sessions.md/ru/runtime_sessions.md.ru.po b/_translations/guide/po/ru/runtime_sessions.md.po similarity index 100% rename from guide/po/runtime_sessions.md/ru/runtime_sessions.md.ru.po rename to _translations/guide/po/ru/runtime_sessions.md.po diff --git a/guide/po/security_authentication.md/ru/security_authentication.md.ru.po b/_translations/guide/po/ru/security_authentication.md.po similarity index 81% rename from guide/po/security_authentication.md/ru/security_authentication.md.ru.po rename to _translations/guide/po/ru/security_authentication.md.po index 64920b21..81b67051 100644 --- a/guide/po/security_authentication.md/ru/security_authentication.md.ru.po +++ b/_translations/guide/po/ru/security_authentication.md.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2025-09-04 11:19+0500\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" "PO-Revision-Date: 2025-09-04 11:19+0500\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -17,50 +17,50 @@ 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 # -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md #, no-wrap msgid "Authentication" msgstr "" #. type: Plain text -#: en/security/authentication.md +#: ../../guide/en/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 -#: en/security/authentication.md +#: ../../guide/en/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: '* ' -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md msgid "Configure the `Yiisoft\\Yii\\Web\\User\\User` service;" msgstr "" #. type: Bullet: '* ' -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md msgid "Create a class implementing the `\\Yiisoft\\Auth\\IdentityInterface` interface;" msgstr "" #. type: Bullet: '* ' -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md msgid "Create a class implementing the `\\Yiisoft\\Auth\\IdentityRepositoryInterface` interface;" msgstr "" #. type: Title ## -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md #, fuzzy, no-wrap #| msgid "Configuring container " msgid "Configuring `Yiisoft\\Yii\\Web\\User\\User` " msgstr "Конфигурирование контейнера " #. type: Plain text -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md msgid "The `Yiisoft\\Yii\\Web\\User\\User` 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) -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md #, no-wrap msgid "" "use Yiisoft\\Session\\Session;\n" @@ -82,35 +82,35 @@ msgid "" " \n" " // User:\n" " IdentityRepositoryInterface::class => static function (ContainerInterface $container) {\n" -" // instead of Cycle-based repository, you can use any implementation\n" +" // instead of a Cycle-based repository, you can use any implementation\n" " return $container->get(\\Cycle\\ORM\\ORMInterface::class)->getRepository(\\App\\Entity\\User::class);\n" " },\n" "];\n" msgstr "" #. type: Title ## -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md #, no-wrap msgid "Implementing`\\Yiisoft\\Auth\\IdentityInterface` " msgstr "" #. type: Plain text -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md msgid "The identity class must implement the `\\Yiisoft\\Auth\\IdentityInterface` which has a single method:" msgstr "" #. type: Bullet: '* ' -#: en/security/authentication.md +#: ../../guide/en/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 -#: en/security/authentication.md -msgid "In the following example, an identity class implemented as a pure PHP object." +#: ../../guide/en/security/authentication.md +msgid "In the following example, an identity class is implemented as a pure PHP object." msgstr "" #. type: Fenced code block (php) -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md #, no-wrap msgid "" "" msgstr "" #. type: Plain text -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md msgid "The identity repository class must implement the `\\Yiisoft\\Auth\\IdentityRepositoryInterface` which has the following methods:" msgstr "" #. type: Bullet: '* ' -#: en/security/authentication.md +#: ../../guide/en/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: '* ' -#: en/security/authentication.md +#: ../../guide/en/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 -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md msgid "A dummy implementation may look like the following:" msgstr "" #. type: Fenced code block (php) -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md #, no-wrap msgid "" "namespace App\\User;\n" @@ -207,19 +207,19 @@ msgid "" msgstr "" #. type: Title ## -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md #, fuzzy, no-wrap #| msgid "Resolving aliases " msgid "Using `\\Yiisoft\\User\\User` " msgstr "Разрешение псевдонимов " #. type: Plain text -#: en/security/authentication.md -msgid "You can use `\\Yiisoft\\User\\User` service to obtain current user identity. As any service, it could be auto wired in either action handler constructor or method:" +#: ../../guide/en/security/authentication.md +msgid "You can use `\\Yiisoft\\User\\User` 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) -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md #, no-wrap msgid "" "use \\Psr\\Http\\Message\\ServerRequestInterface;\n" @@ -240,17 +240,17 @@ msgid "" msgstr "" #. type: Plain text -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md msgid "`isGuest()` determines if user is logged in or not. `getIdentity()` returns an instance of identity." msgstr "" #. type: Plain text -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md msgid "To log in a user, you may use the following code:" msgstr "" #. type: Fenced code block (php) -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md #, no-wrap msgid "" "$identity = $identityRepository->findByEmail($email);\n" @@ -260,17 +260,17 @@ msgid "" msgstr "" #. type: Plain text -#: en/security/authentication.md +#: ../../guide/en/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 -#: en/security/authentication.md -msgid "To logout a user, simply call" +#: ../../guide/en/security/authentication.md +msgid "To log out a user, call" msgstr "" #. type: Fenced code block (php) -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md #, no-wrap msgid "" "/* @var $user \\Yiisoft\\User\\User */\n" @@ -278,38 +278,38 @@ msgid "" msgstr "" #. type: Title ## -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md #, fuzzy, no-wrap #| msgid "References " msgid "Authentication Events " msgstr "Полезные ссылки " #. type: Plain text -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md msgid "The user service raises a few events during the login and logout processes." msgstr "" #. type: Bullet: '* ' -#: en/security/authentication.md +#: ../../guide/en/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: '* ' -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md msgid "`\\Yiisoft\\User\\Event\\AfterLogin`: raised after a successful login." msgstr "" #. type: Bullet: '* ' -#: en/security/authentication.md +#: ../../guide/en/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: '* ' -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md msgid "`\\Yiisoft\\User\\Event\\AfterLogout`: raised after a successful logout." msgstr "" #. type: Plain text -#: en/security/authentication.md +#: ../../guide/en/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/guide/po/security_authorization.md/ru/security_authorization.md.ru.po b/_translations/guide/po/ru/security_authorization.md.po similarity index 80% rename from guide/po/security_authorization.md/ru/security_authorization.md.ru.po rename to _translations/guide/po/ru/security_authorization.md.po index 8215694f..3f7f29f5 100644 --- a/guide/po/security_authorization.md/ru/security_authorization.md.ru.po +++ b/_translations/guide/po/ru/security_authorization.md.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2025-09-04 11:19+0500\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" "PO-Revision-Date: 2025-09-04 11:19+0500\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -17,30 +17,30 @@ 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 # -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "Authorization" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "Authorization is the process of verifying that a user has enough permission to do something." msgstr "" #. type: Title ## -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, fuzzy, no-wrap #| msgid "Injecting dependencies " msgid "Checking for permission " msgstr "Внедрение зависимостей " #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "You can check if a user has certain permissions by using `\\Yiisoft\\User\\User` service:" msgstr "" #. type: Fenced code block (php) -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "" "namespace App\\Blog\\Post;\n" @@ -77,84 +77,84 @@ msgid "" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "Behind the scenes, `Yiisoft\\Yii\\Web\\User\\User::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 ## -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "Role-based access control (RBAC) " msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/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 -#: en/security/authorization.md +#: ../../guide/en/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 -#: en/security/authorization.md +#: ../../guide/en/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 -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "To ease description next, there are some basic RBAC concepts first." msgstr "" #. type: Title ### -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, fuzzy, no-wrap #| msgid "DI container " msgid "Basic concepts " msgstr "Контейнер внедрения зависимостей " #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/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 -#: en/security/authorization.md -msgid "Associated with each role or permission, there may be a *rule*. A rule represents a piece of code that 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." +#: ../../guide/en/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 -#: en/security/authorization.md +#: ../../guide/en/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 ### -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, fuzzy, no-wrap #| msgid "Configuring container " msgid "Configuring RBAC " msgstr "Конфигурирование контейнера " #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "RBAC is available via `yiisoft/rbac` package, so you need to require it:" msgstr "" #. type: Fenced code block -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, fuzzy, no-wrap #| msgid "composer install yiisoft/security\n" msgid "composer require yiisoft/rbac\n" msgstr "composer install yiisoft/security\n" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/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) -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "" "use \\Psr\\Container\\ContainerInterface;\n" @@ -170,80 +170,80 @@ msgid "" msgstr "" #. type: Plain text -#: en/security/authorization.md -msgid "`\\Yiisoft\\Rbac\\Manager\\PhpManager` uses a PHP script files to store authorization data. The files are under `@rbac` alias. 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." +#: ../../guide/en/security/authorization.md +msgid "`\\Yiisoft\\Rbac\\Manager\\PhpManager` uses PHP script files to store authorization data. The files are under `@rbac` alias. 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 ### -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, fuzzy, no-wrap #| msgid "Defining aliases " msgid "Building authorization data " msgstr "Определение псевдонимов " #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "Building authorization data is all about the following tasks:" msgstr "" #. type: Bullet: '- ' -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "defining roles and permissions;" msgstr "" #. type: Bullet: '- ' -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "establishing relations between roles and permissions;" msgstr "" #. type: Bullet: '- ' -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "defining rules;" msgstr "" #. type: Bullet: '- ' -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "associating rules with roles and permissions;" msgstr "" #. type: Bullet: '- ' -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "assigning roles to users." msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/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 -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "Either way, in the end, you'll get the following RBAC hierarchy:" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "![Simple RBAC hierarchy](img/rbac-hierarchy-1.svg \"Simple RBAC hierarchy\")" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/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 ### -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "Using console command" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/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) -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "" "withDescription('Update post');\n" " $auth->add($updatePost);\n" "\n" -" // add \"author\" role and give this role the \"createPost\" permission\n" +" // add the \"author\" role and give this role the \"createPost\" permission\n" " $author = new Role('author');\n" " $auth->add($author);\n" " $auth->addChild($author, $createPost);\n" @@ -303,18 +303,18 @@ msgid "" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "You can execute the command above from the console the following way:" msgstr "" #. type: Fenced code block -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "./yii rbac:init\n" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/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" @@ -322,29 +322,29 @@ msgid "" msgstr "" #. type: Title #### -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "Using migrations" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "**TODO**: finish it when migrations are implemented.\n" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/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 -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "Create new migration using `./yii migrate:create init_rbac` then implement creating a hierarchy:" msgstr "" #. type: Fenced code block (php) -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "" "withDescription('Update post');\n" " $auth->add($updatePost);\n" "\n" -" // add \"author\" role and give this role the \"createPost\" permission\n" +" // add the \"author\" role and give this role the \"createPost\" permission\n" " $author = new Role('author');\n" " $auth->add($author);\n" " $auth->addChild($author, $createPost);\n" @@ -396,7 +396,7 @@ msgid "" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/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" @@ -404,34 +404,34 @@ msgid "" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "You could apply migration by using `./yii migrate`." msgstr "" #. type: Title ## -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "Assigning roles to users" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "TODO: update when signup implemented in demo / template.\n" msgstr "" #. type: Plain text -#: en/security/authorization.md -msgid "The author can create a post, admin can update post and do everything the author can." +#: ../../guide/en/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 -#: en/security/authorization.md -msgid "If your application allows user signup, you need to assign roles to these new users 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:" +#: ../../guide/en/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) -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "" "public function signup()\n" @@ -457,24 +457,24 @@ msgid "" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/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 `authManager`." msgstr "" #. type: Title ### -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, fuzzy, no-wrap #| msgid "Resolving aliases " msgid "Using rules " msgstr "Разрешение псевдонимов " #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/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) -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "" "namespace App\\User\\Rbac;\n" @@ -483,7 +483,7 @@ msgid "" "use \\Yiisoft\\Rbac\\Rule;\n" "\n" "/**\n" -" * Checks if authorID matches user passed via params.\n" +" * Checks if the authorID matches user passed via params.\n" " */\n" "final readonly class AuthorRule extends Rule\n" "{\n" @@ -501,12 +501,12 @@ msgid "" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/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) -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "" "/** @var \\Yiisoft\\Rbac\\ManagerInterface $auth */\n" @@ -529,29 +529,29 @@ msgid "" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "Now you've got the following hierarchy:" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "![RBAC hierarchy with a rule](img/rbac-hierarchy-2.svg \"RBAC hierarchy with a rule\")" msgstr "" #. type: Title ### -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, fuzzy, no-wrap #| msgid "References " msgid "Access check " msgstr "Полезные ссылки " #. type: Plain text -#: en/security/authorization.md -msgid "The check is done similar to how it was done in the first section of this guide:" +#: ../../guide/en/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) -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "" "namespace App\\Blog\\Post;\n" @@ -588,27 +588,27 @@ msgid "" msgstr "" #. type: Plain text -#: en/security/authorization.md -msgid "The difference is that now checking for user's own post is part of the RBAC." +#: ../../guide/en/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 -#: en/security/authorization.md +#: ../../guide/en/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 -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "![Access check](img/rbac-access-check-1.svg \"Access check\")" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/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) -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "" "if ($user->can('updatePost', ['post' => $post])) {\n" @@ -617,17 +617,17 @@ msgid "" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "Here is what happens if the current user is John:" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "![Access check](img/rbac-access-check-2.svg \"Access check\")" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "" "You're starting with the `updatePost` and going through `updateOwnPost`. To pass the access check, `AuthorRule`\n" @@ -637,28 +637,28 @@ msgid "" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "In the case of Jane, it's a bit simpler since she is an admin:" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "![Access check](img/rbac-access-check-3.svg \"Access check\")" msgstr "" #. type: Title ## -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "Implementing your own access checker" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/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) -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "" "namespace App\\User;\n" diff --git a/guide/po/security_best-practices.md/ru/security_best-practices.md.ru.po b/_translations/guide/po/ru/security_best-practices.md.po similarity index 100% rename from guide/po/security_best-practices.md/ru/security_best-practices.md.ru.po rename to _translations/guide/po/ru/security_best-practices.md.po diff --git a/guide/po/security_cryptography.md/ru/security_cryptography.md.ru.po b/_translations/guide/po/ru/security_cryptography.md.po similarity index 100% rename from guide/po/security_cryptography.md/ru/security_cryptography.md.ru.po rename to _translations/guide/po/ru/security_cryptography.md.po diff --git a/guide/po/security_overview.md/ru/security_overview.md.ru.po b/_translations/guide/po/ru/security_overview.md.po similarity index 100% rename from guide/po/security_overview.md/ru/security_overview.md.ru.po rename to _translations/guide/po/ru/security_overview.md.po diff --git a/guide/po/security_passwords.md/ru/security_passwords.md.ru.po b/_translations/guide/po/ru/security_passwords.md.po similarity index 100% rename from guide/po/security_passwords.md/ru/security_passwords.md.ru.po rename to _translations/guide/po/ru/security_passwords.md.po diff --git a/guide/po/security_trusted-request.md/ru/security_trusted-request.md.ru.po b/_translations/guide/po/ru/security_trusted-request.md.po similarity index 100% rename from guide/po/security_trusted-request.md/ru/security_trusted-request.md.ru.po rename to _translations/guide/po/ru/security_trusted-request.md.po diff --git a/guide/po/start_creating-project.md/ru/start_creating-project.md.ru.po b/_translations/guide/po/ru/start_creating-project.md.po similarity index 100% rename from guide/po/start_creating-project.md/ru/start_creating-project.md.ru.po rename to _translations/guide/po/ru/start_creating-project.md.po diff --git a/guide/po/start_databases.md/ru/start_databases.md.ru.po b/_translations/guide/po/ru/start_databases.md.po similarity index 100% rename from guide/po/start_databases.md/ru/start_databases.md.ru.po rename to _translations/guide/po/ru/start_databases.md.po diff --git a/guide/po/start_forms.md/ru/start_forms.md.ru.po b/_translations/guide/po/ru/start_forms.md.po similarity index 100% rename from guide/po/start_forms.md/ru/start_forms.md.ru.po rename to _translations/guide/po/ru/start_forms.md.po diff --git a/guide/po/start_gii.md/ru/start_gii.md.ru.po b/_translations/guide/po/ru/start_gii.md.po similarity index 100% rename from guide/po/start_gii.md/ru/start_gii.md.ru.po rename to _translations/guide/po/ru/start_gii.md.po diff --git a/guide/po/start_hello.md/ru/start_hello.md.ru.po b/_translations/guide/po/ru/start_hello.md.po similarity index 100% rename from guide/po/start_hello.md/ru/start_hello.md.ru.po rename to _translations/guide/po/ru/start_hello.md.po diff --git a/guide/po/start_looking-ahead.md/ru/start_looking-ahead.md.ru.po b/_translations/guide/po/ru/start_looking-ahead.md.po similarity index 100% rename from guide/po/start_looking-ahead.md/ru/start_looking-ahead.md.ru.po rename to _translations/guide/po/ru/start_looking-ahead.md.po diff --git a/guide/po/start_prerequisites.md/ru/start_prerequisites.md.ru.po b/_translations/guide/po/ru/start_prerequisites.md.po similarity index 100% rename from guide/po/start_prerequisites.md/ru/start_prerequisites.md.ru.po rename to _translations/guide/po/ru/start_prerequisites.md.po diff --git a/guide/po/start_workflow.md/ru/start_workflow.md.ru.po b/_translations/guide/po/ru/start_workflow.md.po similarity index 100% rename from guide/po/start_workflow.md/ru/start_workflow.md.ru.po rename to _translations/guide/po/ru/start_workflow.md.po diff --git a/guide/po/structure_action.md/ru/structure_action.md.ru.po b/_translations/guide/po/ru/structure_action.md.po similarity index 100% rename from guide/po/structure_action.md/ru/structure_action.md.ru.po rename to _translations/guide/po/ru/structure_action.md.po diff --git a/guide/po/structure_application.md/ru/structure_application.md.ru.po b/_translations/guide/po/ru/structure_application.md.po similarity index 100% rename from guide/po/structure_application.md/ru/structure_application.md.ru.po rename to _translations/guide/po/ru/structure_application.md.po diff --git a/guide/po/structure_domain.md/ru/structure_domain.md.ru.po b/_translations/guide/po/ru/structure_domain.md.po similarity index 100% rename from guide/po/structure_domain.md/ru/structure_domain.md.ru.po rename to _translations/guide/po/ru/structure_domain.md.po diff --git a/guide/po/structure_entry-script.md/ru/structure_entry-script.md.ru.po b/_translations/guide/po/ru/structure_entry-script.md.po similarity index 100% rename from guide/po/structure_entry-script.md/ru/structure_entry-script.md.ru.po rename to _translations/guide/po/ru/structure_entry-script.md.po diff --git a/guide/po/structure_handler.md/ru/structure_handler.md.ru.po b/_translations/guide/po/ru/structure_handler.md.po similarity index 100% rename from guide/po/structure_handler.md/ru/structure_handler.md.ru.po rename to _translations/guide/po/ru/structure_handler.md.po diff --git a/guide/po/structure_middleware.md/ru/structure_middleware.md.ru.po b/_translations/guide/po/ru/structure_middleware.md.po similarity index 75% rename from guide/po/structure_middleware.md/ru/structure_middleware.md.ru.po rename to _translations/guide/po/ru/structure_middleware.md.po index eea9be63..d642d97e 100644 --- a/guide/po/structure_middleware.md/ru/structure_middleware.md.ru.po +++ b/_translations/guide/po/ru/structure_middleware.md.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2025-09-04 11:19+0500\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" "PO-Revision-Date: 2025-09-04 11:19+0500\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -17,74 +17,74 @@ 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 # -#: en/structure/middleware.md +#: ../../guide/en/structure/middleware.md #, no-wrap msgid "Middleware" msgstr "" #. type: Plain text -#: en/structure/middleware.md +#: ../../guide/en/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 -#: en/structure/middleware.md +#: ../../guide/en/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: '- ' -#: en/structure/middleware.md +#: ../../guide/en/structure/middleware.md msgid "Pass the request to the next middleware performing some work before / after it." msgstr "" #. type: Bullet: '- ' -#: en/structure/middleware.md +#: ../../guide/en/structure/middleware.md msgid "Form the response and return it." msgstr "" #. type: Plain text -#: en/structure/middleware.md +#: ../../guide/en/structure/middleware.md msgid "Depending on middleware used, application behavior may vary significantly." msgstr "" #. type: Plain text -#: en/structure/middleware.md +#: ../../guide/en/structure/middleware.md msgid "![Middleware](img/middleware.svg)" msgstr "" #. type: Plain text -#: en/structure/middleware.md +#: ../../guide/en/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 -#: en/structure/middleware.md +#: ../../guide/en/structure/middleware.md msgid "![Middleware](img/middleware_alternative.svg)" msgstr "" #. type: Title ## -#: en/structure/middleware.md +#: ../../guide/en/structure/middleware.md #, no-wrap msgid "Using middleware" msgstr "" #. type: Plain text -#: en/structure/middleware.md -msgid "Any PSR-15 compatible middleware could be used with Yii and there are many. Say, you need to add basic authentication one of the application URLs. URL-dependent middleware is configured using router, so you need to change router factory." +#: ../../guide/en/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 -#: en/structure/middleware.md +#: ../../guide/en/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 -#: en/structure/middleware.md +#: ../../guide/en/structure/middleware.md msgid "Now register the middleware in DI container configuration `config/web.php`:" msgstr "" #. type: Fenced code block (php) -#: en/structure/middleware.md +#: ../../guide/en/structure/middleware.md #, no-wrap msgid "" "handle($request);\n" msgstr "" #. type: Plain text -#: en/structure/middleware.md +#: ../../guide/en/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) -#: en/structure/middleware.md +#: ../../guide/en/structure/middleware.md #, no-wrap msgid "" "$request = $request->withAttribute('answer', 42);\n" @@ -282,29 +282,29 @@ msgid "" msgstr "" #. type: Plain text -#: en/structure/middleware.md +#: ../../guide/en/structure/middleware.md msgid "To get it in the next middleware:" msgstr "" #. type: Fenced code block (php) -#: en/structure/middleware.md +#: ../../guide/en/structure/middleware.md #, no-wrap msgid "$answer = $request->getAttribute('answer');\n" msgstr "" #. type: Title ### -#: en/structure/middleware.md +#: ../../guide/en/structure/middleware.md #, no-wrap msgid "Capturing response to manipulate it" msgstr "" #. type: Plain text -#: en/structure/middleware.md -msgid "You may want to capture response to manipulate it. It could be useful for adding CORS headers, gzipping content etc." +#: ../../guide/en/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) -#: en/structure/middleware.md +#: ../../guide/en/structure/middleware.md #, no-wrap msgid "" "$response = $next->handle($request);\n" diff --git a/guide/po/structure_overview.md/ru/structure_overview.md.ru.po b/_translations/guide/po/ru/structure_overview.md.po similarity index 100% rename from guide/po/structure_overview.md/ru/structure_overview.md.ru.po rename to _translations/guide/po/ru/structure_overview.md.po diff --git a/guide/po/structure_package.md/ru/structure_package.md.ru.po b/_translations/guide/po/ru/structure_package.md.po similarity index 100% rename from guide/po/structure_package.md/ru/structure_package.md.ru.po rename to _translations/guide/po/ru/structure_package.md.po diff --git a/guide/po/structure_service.md/ru/structure_service.md.ru.po b/_translations/guide/po/ru/structure_service.md.po similarity index 100% rename from guide/po/structure_service.md/ru/structure_service.md.ru.po rename to _translations/guide/po/ru/structure_service.md.po diff --git a/guide/po/tutorial_console-applications.md/ru/tutorial_console-applications.md.ru.po b/_translations/guide/po/ru/tutorial_console-applications.md.po similarity index 100% rename from guide/po/tutorial_console-applications.md/ru/tutorial_console-applications.md.ru.po rename to _translations/guide/po/ru/tutorial_console-applications.md.po diff --git a/guide/po/tutorial_mailing.md/ru/tutorial_mailing.md.ru.po b/_translations/guide/po/ru/tutorial_mailing.md.po similarity index 100% rename from guide/po/tutorial_mailing.md/ru/tutorial_mailing.md.ru.po rename to _translations/guide/po/ru/tutorial_mailing.md.po diff --git a/guide/po/tutorial_performance-tuning.md/ru/tutorial_performance-tuning.md.ru.po b/_translations/guide/po/ru/tutorial_performance-tuning.md.po similarity index 70% rename from guide/po/tutorial_performance-tuning.md/ru/tutorial_performance-tuning.md.ru.po rename to _translations/guide/po/ru/tutorial_performance-tuning.md.po index b773f66f..72f510d9 100644 --- a/guide/po/tutorial_performance-tuning.md/ru/tutorial_performance-tuning.md.ru.po +++ b/_translations/guide/po/ru/tutorial_performance-tuning.md.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2025-09-04 11:19+0500\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" "PO-Revision-Date: 2025-09-04 11:19+0500\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -17,73 +17,115 @@ 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 # -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md #, no-wrap msgid "Performance tuning" msgstr "" #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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 ## -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md #, no-wrap msgid "Optimizing your PHP Environment " msgstr "" #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md msgid "A well-configured PHP environment is important. To get maximum performance:" msgstr "" #. type: Bullet: '- ' -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md msgid "Use the latest stable PHP version. Major releases of PHP may bring significant performance improvements." msgstr "" #. type: Bullet: '- ' -#: en/tutorial/performance-tuning.md -msgid "Enable bytecode caching with [Opcache](https://secure.php.net/opcache). Bytecode caching avoids the time spent in parsing and including PHP scripts for every incoming request." +#: ../../guide/en/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: '- ' -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md msgid "[Tune `realpath()` cache](https://github.com/samdark/realpath_cache_tuner)." msgstr "" #. type: Bullet: '- ' -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md msgid "Make sure [XDebug](https://xdebug.org/) isn't installed in the production environment." msgstr "" #. type: Bullet: '- ' -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md msgid "Try [PHP 7 preloading](https://wiki.php.net/rfc/preload)." msgstr "" #. type: Title ## -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md +#, fuzzy, no-wrap +#| msgid "Defining aliases " +msgid "Optimizing your code " +msgstr "Определение псевдонимов " + +#. type: Plain text +#: ../../guide/en/tutorial/performance-tuning.md +msgid "Beyond environment configuration, there are code-level optimizations that can improve your application's performance:" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/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: '- ' +#: ../../guide/en/tutorial/performance-tuning.md +msgid "[Speeding up array_merge()](https://www.exakat.io/speeding-up-array_merge/)" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/tutorial/performance-tuning.md +msgid "[Move that foreach() inside the method](https://www.exakat.io/move-that-foreach-inside-the-method/)" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/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: '- ' +#: ../../guide/en/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 +#: ../../guide/en/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 ## +#: ../../guide/en/tutorial/performance-tuning.md #, fuzzy, no-wrap #| msgid "Injecting dependencies " msgid "Using caching techniques " msgstr "Внедрение зависимостей " #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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 ## -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md #, fuzzy, no-wrap #| msgid "Configuring container " msgid "Optimizing session storage " msgstr "Конфигурирование контейнера " #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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" @@ -94,12 +136,12 @@ msgid "" msgstr "" #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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) -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md #, fuzzy, no-wrap #| msgid "" #| "return [\n" @@ -124,143 +166,143 @@ msgstr "" "];\n" #. type: Title ## -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md #, fuzzy, no-wrap #| msgid "Defining aliases " msgid "Optimizing databases " msgstr "Определение псевдонимов " #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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 -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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 -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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 -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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 ## -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md #, fuzzy, no-wrap #| msgid "Defining aliases " msgid "Optimizing composer autoloader " msgstr "Определение псевдонимов " #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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 -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md #, no-wrap msgid "composer dumpautoload -o\n" msgstr "" #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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 ## -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md #, fuzzy, no-wrap #| msgid "Resolving aliases " msgid "Processing data offline " msgstr "Разрешение псевдонимов " #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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 -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md msgid "There are two methods to process data offline: pull and push." msgstr "" #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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 -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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 ## -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md #, no-wrap msgid "Using preloading" msgstr "" #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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 -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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 -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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 ### -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md #, no-wrap msgid "Preloading benchmarks" msgstr "" #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md msgid "The application template benchmark includes configuring classes to injected dependencies in the bootstrap script." msgstr "" #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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) -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md #, no-wrap msgid "ab -n 1000 -c 10 -t 10\n" msgstr "" #. type: Plain text -#: en/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:" +#: ../../guide/en/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) -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md #, no-wrap msgid "composer install --optimize-autoloader --no-dev\n" msgstr "" #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md msgid "With preloading enabled, the entire composer class map (825 files) was used:" msgstr "" #. type: Fenced code block (php) -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md #, no-wrap msgid "" "$files = require 'vendor/composer/autoload_classmap.php';\n" @@ -271,13 +313,13 @@ msgid "" msgstr "" #. type: Title #### -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md #, no-wrap msgid "Test results" msgstr "" #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md #, no-wrap msgid "" "| Benchmark | Preloaded files | Opcache memory used | Per request memory used | Time per request | Requests per second |\n" @@ -287,40 +329,40 @@ msgid "" msgstr "" #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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 ## -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md #, fuzzy, no-wrap #| msgid "References " msgid "Performance profiling " msgstr "Полезные ссылки " #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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: Bullet: '- ' -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md msgid "[Yii debug toolbar and debugger](https://github.com/yiisoft/yii2-debug/blob/master/docs/guide/README.md)" msgstr "" #. type: Bullet: '- ' -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md msgid "[Blackfire](https://blackfire.io/)" msgstr "" #. type: Bullet: '- ' -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md #, fuzzy #| msgid "[PHP manual: security](https://www.php.net/manual/en/security.php)" msgid "[XHProf](https://secure.php.net/manual/en/book.xhprof.php)" msgstr "[Руководство по PHP: безопасность](https://www.php.net/manual/en/security.php)" #. type: Bullet: '- ' -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md msgid "[XDebug profiler](https://xdebug.org/docs/profiler)" msgstr "" diff --git a/guide/po/tutorial_using-with-event-loop.md/ru/tutorial_using-with-event-loop.md.ru.po b/_translations/guide/po/ru/tutorial_using-with-event-loop.md.po similarity index 77% rename from guide/po/tutorial_using-with-event-loop.md/ru/tutorial_using-with-event-loop.md.ru.po rename to _translations/guide/po/ru/tutorial_using-with-event-loop.md.po index d2aebd19..e4b92ba0 100644 --- a/guide/po/tutorial_using-with-event-loop.md/ru/tutorial_using-with-event-loop.md.ru.po +++ b/_translations/guide/po/ru/tutorial_using-with-event-loop.md.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2025-09-04 11:19+0500\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" "PO-Revision-Date: 2025-09-04 11:19+0500\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -17,13 +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: Title # -#: en/tutorial/using-with-event-loop.md +#: ../../guide/en/tutorial/using-with-event-loop.md #, no-wrap msgid "Using Yii with event loop" msgstr "" #. type: Plain text -#: en/tutorial/using-with-event-loop.md +#: ../../guide/en/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" @@ -34,28 +34,28 @@ msgid "" msgstr "" #. type: Plain text -#: en/tutorial/using-with-event-loop.md +#: ../../guide/en/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 -#: en/tutorial/using-with-event-loop.md +#: ../../guide/en/tutorial/using-with-event-loop.md msgid "There are multiple tools that could be used to achieve it. Notably, [FrankenPHP](https://frankenphp.dev/), [RoadRunner](https://roadrunner.dev/) and [Swoole](https://www.swoole.co.uk/)." msgstr "" #. type: Title ## -#: en/tutorial/using-with-event-loop.md +#: ../../guide/en/tutorial/using-with-event-loop.md #, no-wrap msgid "Event loop implications" msgstr "" #. type: Plain text -#: en/tutorial/using-with-event-loop.md +#: ../../guide/en/tutorial/using-with-event-loop.md msgid "Event loop worker basically looks like the following:" msgstr "" #. type: Fenced code block (php) -#: en/tutorial/using-with-event-loop.md +#: ../../guide/en/tutorial/using-with-event-loop.md #, no-wrap msgid "" "initializeContext();\n" @@ -66,44 +66,44 @@ msgid "" msgstr "" #. type: Plain text -#: en/tutorial/using-with-event-loop.md +#: ../../guide/en/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 -#: en/tutorial/using-with-event-loop.md +#: ../../guide/en/tutorial/using-with-event-loop.md msgid "That means that there's more to consider when developing applications." msgstr "" #. type: Title ### -#: en/tutorial/using-with-event-loop.md +#: ../../guide/en/tutorial/using-with-event-loop.md #, no-wrap msgid "Processing is blocking" msgstr "" #. type: Plain text -#: en/tutorial/using-with-event-loop.md +#: ../../guide/en/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 ### -#: en/tutorial/using-with-event-loop.md +#: ../../guide/en/tutorial/using-with-event-loop.md #, no-wrap msgid "Services and state" msgstr "" #. type: Plain text -#: en/tutorial/using-with-event-loop.md +#: ../../guide/en/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 -#: en/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 services state at the end of the request processing. In this case, a state resetter will help you:" +#: ../../guide/en/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) -#: en/tutorial/using-with-event-loop.md +#: ../../guide/en/tutorial/using-with-event-loop.md #, no-wrap msgid "" "initializeContext();\n" @@ -116,17 +116,17 @@ msgid "" msgstr "" #. type: Title ## -#: en/tutorial/using-with-event-loop.md +#: ../../guide/en/tutorial/using-with-event-loop.md #, no-wrap msgid "Integrations" msgstr "" #. type: Bullet: '- ' -#: en/tutorial/using-with-event-loop.md +#: ../../guide/en/tutorial/using-with-event-loop.md msgid "[RoadRunner](using-yii-with-roadrunner.md)" msgstr "" #. type: Bullet: '- ' -#: en/tutorial/using-with-event-loop.md +#: ../../guide/en/tutorial/using-with-event-loop.md msgid "[Swoole](using-yii-with-swoole.md)" msgstr "" diff --git a/guide/po/tutorial_using-yii-with-roadrunner.md/ru/tutorial_using-yii-with-roadrunner.md.ru.po b/_translations/guide/po/ru/tutorial_using-yii-with-roadrunner.md.po similarity index 100% rename from guide/po/tutorial_using-yii-with-roadrunner.md/ru/tutorial_using-yii-with-roadrunner.md.ru.po rename to _translations/guide/po/ru/tutorial_using-yii-with-roadrunner.md.po diff --git a/guide/po/tutorial_using-yii-with-swoole.md/ru/tutorial_using-yii-with-swoole.md.ru.po b/_translations/guide/po/ru/tutorial_using-yii-with-swoole.md.po similarity index 82% rename from guide/po/tutorial_using-yii-with-swoole.md/ru/tutorial_using-yii-with-swoole.md.ru.po rename to _translations/guide/po/ru/tutorial_using-yii-with-swoole.md.po index 733a911e..6f0c11ca 100644 --- a/guide/po/tutorial_using-yii-with-swoole.md/ru/tutorial_using-yii-with-swoole.md.ru.po +++ b/_translations/guide/po/ru/tutorial_using-yii-with-swoole.md.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2025-09-04 11:19+0500\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" "PO-Revision-Date: 2025-09-04 11:19+0500\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -17,33 +17,33 @@ 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 ## -#: en/tutorial/using-yii-with-roadrunner.md -#: en/tutorial/using-yii-with-swoole.md +#: ../../guide/en/tutorial/using-yii-with-roadrunner.md +#: ../../guide/en/tutorial/using-yii-with-swoole.md #, no-wrap msgid "Installation" msgstr "" #. type: Title ## -#: en/tutorial/using-yii-with-roadrunner.md -#: en/tutorial/using-yii-with-swoole.md +#: ../../guide/en/tutorial/using-yii-with-roadrunner.md +#: ../../guide/en/tutorial/using-yii-with-swoole.md #, no-wrap msgid "Starting a server" msgstr "" #. type: Plain text -#: en/tutorial/using-yii-with-roadrunner.md -#: en/tutorial/using-yii-with-swoole.md +#: ../../guide/en/tutorial/using-yii-with-roadrunner.md +#: ../../guide/en/tutorial/using-yii-with-swoole.md msgid "To start a server, execute the following command:" msgstr "" #. type: Title # -#: en/tutorial/using-yii-with-swoole.md +#: ../../guide/en/tutorial/using-yii-with-swoole.md #, no-wrap msgid "Using Yii with Swoole" msgstr "" #. type: Plain text -#: en/tutorial/using-yii-with-swoole.md +#: ../../guide/en/tutorial/using-yii-with-swoole.md #, no-wrap msgid "" "[Swoole](https://www.swoole.co.uk/) is a PHP network framework distributed as a PECL extension. It allows you built-in async,\n" @@ -51,45 +51,45 @@ msgid "" msgstr "" #. type: Plain text -#: en/tutorial/using-yii-with-swoole.md -msgid "In the context of Yii, it allows running request handlers 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 to re-initialize a framework for each request that improves performance significantly." +#: ../../guide/en/tutorial/using-yii-with-swoole.md +msgid "In the context of Yii, it allows running request handlers 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 -#: en/tutorial/using-yii-with-swoole.md +#: ../../guide/en/tutorial/using-yii-with-swoole.md msgid "Swoole works on Linux and macOS and can be installed via pecl:" msgstr "" #. type: Fenced code block (bash) -#: en/tutorial/using-yii-with-swoole.md +#: ../../guide/en/tutorial/using-yii-with-swoole.md #, no-wrap msgid "pecl install swoole\n" msgstr "" #. type: Title ## -#: en/tutorial/using-yii-with-swoole.md +#: ../../guide/en/tutorial/using-yii-with-swoole.md #, no-wrap msgid "Putting up a server" msgstr "" #. type: Plain text -#: en/tutorial/using-yii-with-swoole.md +#: ../../guide/en/tutorial/using-yii-with-swoole.md msgid "Since Swoole doesn't have built-in PSR-7 support, you need a package fixing so:" msgstr "" #. type: Fenced code block (php) -#: en/tutorial/using-yii-with-swoole.md +#: ../../guide/en/tutorial/using-yii-with-swoole.md #, no-wrap msgid "composer require ilexn/swoole-convent-psr7\n" msgstr "" #. type: Plain text -#: en/tutorial/using-yii-with-swoole.md +#: ../../guide/en/tutorial/using-yii-with-swoole.md msgid "Create an entry script, `server.php`:" msgstr "" #. type: Fenced code block (php) -#: en/tutorial/using-yii-with-swoole.md +#: ../../guide/en/tutorial/using-yii-with-swoole.md #, no-wrap msgid "" "=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" #. type: Title ## -#: en/concept/configuration.md en/tutorial/using-yii-with-roadrunner.md -#: en/views/view-injections.md +#: ../../guide/en/concept/configuration.md +#: ../../guide/en/tutorial/using-yii-with-roadrunner.md +#: ../../guide/en/views/view-injections.md #, fuzzy, no-wrap msgid "Configuration" msgstr "конфигурация может быть:" #. type: Title # -#: en/views/view-injections.md +#: ../../guide/en/views/view-injections.md #, fuzzy, no-wrap #| msgid "Avoiding SQL injections" msgid "View injections" msgstr "Как избежать SQL-инъекций" #. type: Plain text -#: en/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. Implementing this interface allows developers to manage the data that will be available across various views, ensuring flexibility and reusability of code." +#: ../../guide/en/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 -#: en/views/view-injections.md +#: ../../guide/en/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) +#: ../../guide/en/views/view-injections.md +#, fuzzy, no-wrap +#| msgid "composer install yiisoft/security\n" +msgid "composer require yiisoft/yii-view-renderer\n" +msgstr "composer install yiisoft/security\n" + +#. type: Plain text +#: ../../guide/en/views/view-injections.md msgid "In config `params.php`:" msgstr "" #. type: Fenced code block (php) -#: en/views/view-injections.md +#: ../../guide/en/views/view-injections.md #, no-wrap msgid "" "...\n" @@ -55,18 +68,18 @@ msgid "" msgstr "" #. type: Title ## -#: en/views/view-injections.md +#: ../../guide/en/views/view-injections.md #, no-wrap msgid "New injections" msgstr "" #. type: Plain text -#: en/views/view-injections.md +#: ../../guide/en/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) -#: en/views/view-injections.md +#: ../../guide/en/views/view-injections.md #, no-wrap msgid "" "class MyCustomParametersInjection implements Yiisoft\\Yii\\View\\Renderer\\CommonParametersInjectionInterface\n" @@ -90,12 +103,12 @@ msgid "" msgstr "" #. type: Plain text -#: en/views/view-injections.md +#: ../../guide/en/views/view-injections.md msgid "Add your new Injection to `params.php`:" msgstr "" #. type: Fenced code block (php) -#: en/views/view-injections.md +#: ../../guide/en/views/view-injections.md #, no-wrap msgid "" "'yiisoft/yii-view' => [\n" @@ -107,23 +120,23 @@ msgid "" msgstr "" #. type: Title ## -#: en/views/view-injections.md +#: ../../guide/en/views/view-injections.md #, no-wrap msgid "Using Separate Injections for Different Layouts" msgstr "" #. type: Plain text -#: en/views/view-injections.md +#: ../../guide/en/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 -#: en/views/view-injections.md +#: ../../guide/en/views/view-injections.md msgid "Create your custom ViewInjection for a specific layout:" msgstr "" #. type: Fenced code block (php) -#: en/views/view-injections.md +#: ../../guide/en/views/view-injections.md #, fuzzy, no-wrap #| msgid "" #| "final class MyService implements MyServiceInterface\n" @@ -164,12 +177,12 @@ msgstr "" " }\n" #. type: Plain text -#: en/views/view-injections.md +#: ../../guide/en/views/view-injections.md msgid "Add your new injection to `params.php` under specific layout name. In the following example, it is `@layout/cart`:" msgstr "" #. type: Fenced code block (php) -#: en/views/view-injections.md +#: ../../guide/en/views/view-injections.md #, no-wrap msgid "" "'yiisoft/yii-view' => [\n" @@ -189,3 +202,12 @@ msgid "" " ],\n" " ],\n" msgstr "" + +#. type: Plain text +#: ../../guide/en/views/view-injections.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> [← Template engines](template-engines.md) |\n" +"> [Scripts, styles and metatags →](script-style-meta.md)\n" +msgstr "" diff --git a/_translations/guide/po4a.cfg b/_translations/guide/po4a.cfg new file mode 100644 index 00000000..e15dc7a9 --- /dev/null +++ b/_translations/guide/po4a.cfg @@ -0,0 +1,69 @@ +[po4a_langs] ru id es + + +[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" +[po4a_alias:markdown] text opt:"--option markdown" opt:"--option keyvalue" opt:"--option yfm_keys=title,description,menu_title" opt:"--addendum-charset=UTF-8" opt:"--localized-charset=UTF-8" opt:"--master-charset=UTF-8" opt:"--keep=5" + + +[type: markdown] ../../guide/en/README.md $lang:../../guide/$lang/README.md +[type: markdown] ../../guide/en/glossary.md $lang:../../guide/$lang/glossary.md + +[type: markdown] ../../guide/en/caching/data.md $lang:../../guide/$lang/caching/data.md pot=caching_data.md +[type: markdown] ../../guide/en/caching/overview.md $lang:../../guide/$lang/caching/overview.md pot=caching_overview.md + +[type: markdown] ../../guide/en/concept/aliases.md $lang:../../guide/$lang/concept/aliases.md pot=concept_aliases.md +[type: markdown] ../../guide/en/concept/autoloading.md $lang:../../guide/$lang/concept/autoloading.md pot=concept_autoloading.md +[type: markdown] ../../guide/en/concept/configuration.md $lang:../../guide/$lang/concept/configuration.md pot=concept_configuration.md +[type: markdown] ../../guide/en/concept/di-container.md $lang:../../guide/$lang/concept/di-container.md pot=concept_di-container.md +[type: markdown] ../../guide/en/concept/events.md $lang:../../guide/$lang/concept/events.md pot=concept_events.md +[type: markdown] ../../guide/en/concept/immutability.md $lang:../../guide/$lang/concept/immutability.md pot=concept_immutability.md + +[type: markdown] ../../guide/en/databases/db-migrations.md $lang:../../guide/$lang/databases/db-migrations.md pot=databases_db-migrations.md + +[type: markdown] ../../guide/en/intro/upgrade-from-v2.md $lang:../../guide/$lang/intro/upgrade-from-v2.md pot=intro_upgrade-from-v2.md +[type: markdown] ../../guide/en/intro/what-is-yii.md $lang:../../guide/$lang/intro/what-is-yii.md pot=intro_what-is-yii.md + +[type: markdown] ../../guide/en/runtime/cookies.md $lang:../../guide/$lang/runtime/cookies.md pot=runtime_cookies.md +[type: markdown] ../../guide/en/runtime/handling-errors.md $lang:../../guide/$lang/runtime/handling-errors.md pot=runtime_handling-errors.md +[type: markdown] ../../guide/en/runtime/logging.md $lang:../../guide/$lang/runtime/logging.md pot=runtime_logging.md +[type: markdown] ../../guide/en/runtime/request.md $lang:../../guide/$lang/runtime/request.md pot=runtime_request.md +[type: markdown] ../../guide/en/runtime/response.md $lang:../../guide/$lang/runtime/response.md pot=runtime_response.md +[type: markdown] ../../guide/en/runtime/routing.md $lang:../../guide/$lang/runtime/routing.md pot=runtime_routing.md +[type: markdown] ../../guide/en/runtime/sessions.md $lang:../../guide/$lang/runtime/sessions.md pot=runtime_sessions.md + +[type: markdown] ../../guide/en/security/authentication.md $lang:../../guide/$lang/security/authentication.md pot=security_authentication.md +[type: markdown] ../../guide/en/security/authorization.md $lang:../../guide/$lang/security/authorization.md pot=security_authorization.md +[type: markdown] ../../guide/en/security/best-practices.md $lang:../../guide/$lang/security/best-practices.md pot=security_best-practices.md +[type: markdown] ../../guide/en/security/cryptography.md $lang:../../guide/$lang/security/cryptography.md pot=security_cryptography.md +[type: markdown] ../../guide/en/security/overview.md $lang:../../guide/$lang/security/overview.md pot=security_overview.md +[type: markdown] ../../guide/en/security/passwords.md $lang:../../guide/$lang/security/passwords.md pot=security_passwords.md +[type: markdown] ../../guide/en/security/trusted-request.md $lang:../../guide/$lang/security/trusted-request.md pot=security_trusted-request.md + +[type: markdown] ../../guide/en/start/creating-project.md $lang:../../guide/$lang/start/creating-project.md pot=start_creating-project.md +[type: markdown] ../../guide/en/start/databases.md $lang:../../guide/$lang/start/databases.md pot=start_databases.md +[type: markdown] ../../guide/en/start/forms.md $lang:../../guide/$lang/start/forms.md pot=start_forms.md +[type: markdown] ../../guide/en/start/gii.md $lang:../../guide/$lang/start/gii.md pot=start_gii.md +[type: markdown] ../../guide/en/start/hello.md $lang:../../guide/$lang/start/hello.md pot=start_hello.md +[type: markdown] ../../guide/en/start/looking-ahead.md $lang:../../guide/$lang/start/looking-ahead.md pot=start_looking-ahead.md +[type: markdown] ../../guide/en/start/prerequisites.md $lang:../../guide/$lang/start/prerequisites.md pot=start_prerequisites.md +[type: markdown] ../../guide/en/start/workflow.md $lang:../../guide/$lang/start/workflow.md pot=start_workflow.md + +[type: markdown] ../../guide/en/structure/action.md $lang:../../guide/$lang/structure/action.md pot=structure_action.md +[type: markdown] ../../guide/en/structure/application.md $lang:../../guide/$lang/structure/application.md pot=structure_application.md +[type: markdown] ../../guide/en/structure/domain.md $lang:../../guide/$lang/structure/domain.md pot=structure_domain.md +[type: markdown] ../../guide/en/structure/entry-script.md $lang:../../guide/$lang/structure/entry-script.md pot=structure_entry-script.md +[type: markdown] ../../guide/en/structure/handler.md $lang:../../guide/$lang/structure/handler.md pot=structure_handler.md +[type: markdown] ../../guide/en/structure/middleware.md $lang:../../guide/$lang/structure/middleware.md pot=structure_middleware.md +[type: markdown] ../../guide/en/structure/overview.md $lang:../../guide/$lang/structure/overview.md pot=structure_overview.md +[type: markdown] ../../guide/en/structure/package.md $lang:../../guide/$lang/structure/package.md pot=structure_package.md +[type: markdown] ../../guide/en/structure/service.md $lang:../../guide/$lang/structure/service.md pot=structure_service.md + +[type: markdown] ../../guide/en/tutorial/console-applications.md $lang:../../guide/$lang/tutorial/console-applications.md pot=tutorial_console-applications.md +[type: markdown] ../../guide/en/tutorial/mailing.md $lang:../../guide/$lang/tutorial/mailing.md pot=tutorial_mailing.md +[type: markdown] ../../guide/en/tutorial/performance-tuning.md $lang:../../guide/$lang/tutorial/performance-tuning.md pot=tutorial_performance-tuning.md +[type: markdown] ../../guide/en/tutorial/using-with-event-loop.md $lang:../../guide/$lang/tutorial/using-with-event-loop.md pot=tutorial_using-with-event-loop.md +[type: markdown] ../../guide/en/tutorial/using-yii-with-roadrunner.md $lang:../../guide/$lang/tutorial/using-yii-with-roadrunner.md pot=tutorial_using-yii-with-roadrunner.md +[type: markdown] ../../guide/en/tutorial/using-yii-with-swoole.md $lang:../../guide/$lang/tutorial/using-yii-with-swoole.md pot=tutorial_using-yii-with-swoole.md + +[type: markdown] ../../guide/en/views/view-injections.md $lang:../../guide/$lang/views/view-injections.md pot=views_view-injections.md diff --git a/guide/po/README.md/README.md.pot b/_translations/guide/pot/README.md.pot similarity index 75% rename from guide/po/README.md/README.md.pot rename to _translations/guide/pot/README.md.pot index fa90bc02..afee215b 100644 --- a/guide/po/README.md/README.md.pot +++ b/_translations/guide/pot/README.md.pot @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2025-09-04 10:36+0500\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,643 +17,638 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" #. type: Title # -#: en/README.md +#: ../../guide/en/README.md #, no-wrap msgid "The definitive guide to Yii 3.0" msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "" "We release this guide under the [Terms of Yii Documentation](https://www." "yiiframework.com/license#docs)." msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "Introduction +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[About Yii](intro/what-is-yii.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Upgrading from version 2.0](intro/upgrade-from-v2.md) +" msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "Getting started -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[What do you need to know?](start/prerequisites.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Creating a project](start/creating-project.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Running applications](start/workflow.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Saying hello](start/hello.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Working with forms](start/forms.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Working with databases](start/databases.md) !" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Generating code with Gii](start/gii.md) -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Looking ahead](start/looking-ahead.md) +" msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "Application structure +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Application structure overview](structure/overview.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Entry scripts](structure/entry-script.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Application](structure/application.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Service components](structure/service.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Actions](structure/action.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Domain](structure/domain.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Middleware](structure/middleware.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Packages](structure/package.md) +" msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "Key concepts +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Class autoloading](concept/autoloading.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Dependency injection container](concept/di-container.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Configuration](concept/configuration.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Aliases](concept/aliases.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Events](concept/events.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Immutability](concept/immutability.md) +" msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "Handling requests +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Routing and URL generation](runtime/routing.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Request](runtime/request.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Response](runtime/response.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Sessions](runtime/sessions.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Cookies](runtime/cookies.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Handling errors](runtime/handling-errors.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Logging](runtime/logging.md) +" msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "Views -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Views](views/view.md) -" msgstr "" #. type: Bullet: '* ' -#: en/README.md -msgid "[Widgets](views/widget.md) -" -msgstr "" - -#. type: Bullet: '* ' -#: en/README.md -msgid "[Assets](views/asset.md) -" +#: ../../guide/en/README.md +msgid "[Template engines](views/template-engines.md) -" msgstr "" #. type: Bullet: '* ' -#: en/README.md -msgid "[Working with client scripts](views/client-scripts.md) -" +#: ../../guide/en/README.md +msgid "[View injections](views/view-injections.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md -msgid "[Theming](views/theming.md) -" +#: ../../guide/en/README.md +msgid "[Scripts, styles and metatags](views/script-style-meta.md)" msgstr "" #. type: Bullet: '* ' -#: en/README.md -msgid "[Template engines](views/template-engines.md) -" +#: ../../guide/en/README.md +msgid "[Assets](views/asset.md) -" msgstr "" #. type: Bullet: '* ' -#: en/README.md -msgid "[View injections](views/view-injections.md) +" +#: ../../guide/en/README.md +msgid "[Widgets](views/widget.md) -" msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "Working with databases +-" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "" "[Database access objects](db-dao.md): Connecting to a database, basic " "queries, transactions, and schema manipulation" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "" "[Query builder](db-query-builder.md): Querying the database using a simple " "abstraction layer" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "" "[Active record](db-active-record.md): The Active Record ORM, retrieving and " "manipulating records, and defining relations" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Migrations](databases/db-migrations.md): +" msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "Getting data from users -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Creating forms](input/forms.md) -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "" "[Validating input](https://github.com/yiisoft/validator/blob/master/docs/" "guide/en/README.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Uploading files](input/file-upload.md) -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Collecting tabular input](input/tabular-input.md) -" msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "Displaying data -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Data formatting](output/formatting.md) -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Pagination](output/pagination.md) -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Sorting](output/sorting.md) -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Data providers](output/data-providers.md) -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Data widgets](output/data-widgets.md) -" msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "Security +-" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Security overview](security/overview.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Authentication](security/authentication.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Authorization](security/authorization.md) +-" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Working with passwords](security/passwords.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Cryptography](security/cryptography.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Best practices](security/best-practices.md) +" msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "Caching +-" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Caching overview](caching/overview.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Data caching](caching/data.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Fragment caching](caching/fragment.md) -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Page caching](caching/page.md) -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[HTTP caching](caching/http.md) -" msgstr "" #. type: Title - -#: en/README.md +#: ../../guide/en/README.md #, no-wrap msgid "REST APIs -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Quick start](rest/quick-start.md)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Resources](rest/resources.md)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Controllers](rest/controllers.md)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Routing](rest/routing.md)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Authentication](rest/authentication.md)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Rate limiting](rest/rate-limiting.md)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Versioning](rest/versioning.md)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Error handling](rest/error-handling.md)" msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "Development tools -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "Debug toolbar and debugger" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "Generating code using Gii" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "Generating API documentation" msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "Testing -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Testing overview](testing/overview.md)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Testing environment setup](testing/environment-setup.md)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Unit tests](testing/unit.md)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Functional tests](testing/functional.md)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Acceptance tests](testing/acceptance.md)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Fixtures](testing/fixtures.md)" msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "Special topics -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Building application from scratch](tutorial/start-from-scratch.md) -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Console applications](tutorial/console-applications.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Docker](tutorial/docker.md) -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Internationalization](tutorial/i18n.md) -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Mailing](tutorial/mailing.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Performance tuning](tutorial/performance-tuning.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Using Yii with event loop](tutorial/using-with-event-loop.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Using Yii with RoadRunner](tutorial/using-yii-with-roadrunner.md) +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Using Yii with Swoole](tutorial/using-yii-with-swoole.md) +" msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "Widgets -" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[GridView](https://www.yiiframework.com/doc-2.0/yii-grid-gridview.html)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "" "[ListView](https://www.yiiframework.com/doc-2.0/yii-widgets-listview.html)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "" "[DetailView](https://www.yiiframework.com/doc-2.0/yii-widgets-detailview." "html)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "" "[ActiveForm](https://www.yiiframework.com/doc-2.0/guide-input-forms." "html#activerecord-based-forms-activeform)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Menu](https://www.yiiframework.com/doc-2.0/yii-widgets-menu.html)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "" "[LinkPager](https://www.yiiframework.com/doc-2.0/yii-widgets-linkpager.html)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "" "[LinkSorter](https://www.yiiframework.com/doc-2.0/yii-widgets-linksorter." "html)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "" "[Bootstrap widgets](https://www.yiiframework.com/extension/yiisoft/yii2-" "bootstrap/doc/guide)" msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "Helpers +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Arrays](https://github.com/yiisoft/arrays/)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Files](https://github.com/yiisoft/files/)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Html](https://github.com/yiisoft/html/)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Json](https://github.com/yiisoft/json)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Network utilities](https://github.com/yiisoft/network-utilities/)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[VarDumper](https://github.com/yiisoft/var-dumper)" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Strings](https://github.com/yiisoft/strings)" msgstr "" #. type: Plain text -#: en/README.md +#: ../../guide/en/README.md msgid "Extras +" msgstr "" #. type: Bullet: '* ' -#: en/README.md +#: ../../guide/en/README.md msgid "[Glossary](glossary.md)" msgstr "" diff --git a/guide/po/caching_data.md/caching_data.md.pot b/_translations/guide/pot/caching_data.md.pot similarity index 82% rename from guide/po/caching_data.md/caching_data.md.pot rename to _translations/guide/pot/caching_data.md.pot index e835e327..5b8f8591 100644 --- a/guide/po/caching_data.md/caching_data.md.pot +++ b/_translations/guide/pot/caching_data.md.pot @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2025-09-04 11:19+0500\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,13 +17,13 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" #. type: Title # -#: en/caching/data.md +#: ../../guide/en/caching/data.md #, no-wrap msgid "Data caching" msgstr "" #. type: Plain text -#: en/caching/data.md +#: ../../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 " @@ -31,27 +31,27 @@ msgid "" msgstr "" #. type: Plain text -#: en/caching/data.md +#: ../../guide/en/caching/data.md msgid "" "To use cache, install [yiisoft/cache](https://github.com/yiisoft/cache) " "package:" msgstr "" #. type: Fenced code block (shell) -#: en/caching/data.md +#: ../../guide/en/caching/data.md #, no-wrap msgid "composer require yiisoft/cache\n" msgstr "" #. type: Plain text -#: en/caching/data.md +#: ../../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) -#: en/caching/data.md +#: ../../guide/en/caching/data.md #, no-wrap msgid "" "public function getTopProducts(\\Yiisoft\\Cache\\CacheInterface $cache): array\n" @@ -60,7 +60,7 @@ msgid "" " \n" " // Try retrieving $data from cache.\n" " $data = $cache->getOrSet($key, function (\\Psr\\SimpleCache\\CacheInterface $cache) use ($count) {\n" -" // Can't find $data in cache, calculate it from scratch.\n" +" // Can't find $data in a cache, calculate it from scratch.\n" " return getTopProductsFromDatabase($count);\n" " }, 3600);\n" " \n" @@ -69,7 +69,7 @@ msgid "" msgstr "" #. type: Plain text -#: en/caching/data.md +#: ../../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 " @@ -77,20 +77,20 @@ msgid "" msgstr "" #. type: Plain text -#: en/caching/data.md +#: ../../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 ## -#: en/caching/data.md +#: ../../guide/en/caching/data.md #, no-wrap msgid "Cache handlers" msgstr "" #. type: Plain text -#: en/caching/data.md +#: ../../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 " @@ -98,12 +98,12 @@ msgid "" msgstr "" #. type: Plain text -#: en/caching/data.md +#: ../../guide/en/caching/data.md msgid "Yii provides the following handlers:" msgstr "" #. type: Bullet: '- ' -#: en/caching/data.md +#: ../../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 " @@ -115,14 +115,14 @@ msgid "" msgstr "" #. type: Bullet: '- ' -#: en/caching/data.md +#: ../../guide/en/caching/data.md msgid "" "`ArrayCache` — provides caching for the current request only by storing the " "values in an array." msgstr "" #. type: Bullet: '- ' -#: en/caching/data.md +#: ../../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 " @@ -131,14 +131,14 @@ msgid "" msgstr "" #. type: Bullet: '- ' -#: en/caching/data.md +#: ../../guide/en/caching/data.md msgid "" "[Database](https://github.com/yiisoft/cache-db) — uses a database table to " "store cached data." msgstr "" #. type: Bullet: '- ' -#: en/caching/data.md +#: ../../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, " @@ -146,31 +146,32 @@ msgid "" msgstr "" #. type: Bullet: '- ' -#: en/caching/data.md +#: ../../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 " -"distributed application (e.g., with several servers, load balancers, etc.)" +"You can consider this option as the fastest one when dealing with cache in a " +"distributed application" msgstr "" -#. type: Bullet: '- ' -#: en/caching/data.md +#. type: Plain text +#: ../../guide/en/caching/data.md +#, no-wrap msgid "" -"[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." +" (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 -#: en/caching/data.md +#: ../../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 -#: en/caching/data.md +#: ../../guide/en/caching/data.md #, no-wrap msgid "" "> [!TIP]\n" @@ -180,7 +181,7 @@ msgid "" msgstr "" #. type: Plain text -#: en/caching/data.md +#: ../../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 " @@ -188,7 +189,7 @@ msgid "" msgstr "" #. type: Plain text -#: en/caching/data.md +#: ../../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 " @@ -196,13 +197,13 @@ msgid "" msgstr "" #. type: Title ### -#: en/caching/data.md +#: ../../guide/en/caching/data.md #, no-wrap msgid "Cache keys" msgstr "" #. type: Plain text -#: en/caching/data.md +#: ../../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 " @@ -210,21 +211,21 @@ msgid "" msgstr "" #. type: Plain text -#: en/caching/data.md +#: ../../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 -#: en/caching/data.md +#: ../../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 -#: en/caching/data.md +#: ../../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 " @@ -232,7 +233,7 @@ msgid "" msgstr "" #. type: Fenced code block (php) -#: en/caching/data.md +#: ../../guide/en/caching/data.md #, no-wrap msgid "" "$arrayCacheWithPrefix = new \\Yiisoft\\Cache\\PrefixedCache(new \\Yiisoft\\Cache\\ArrayCache(), 'myapp_');\n" @@ -240,13 +241,13 @@ msgid "" msgstr "" #. type: Title ### -#: en/caching/data.md +#: ../../guide/en/caching/data.md #, no-wrap msgid "Cache expiration" msgstr "" #. type: Plain text -#: en/caching/data.md +#: ../../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 " @@ -255,7 +256,7 @@ msgid "" msgstr "" #. type: Fenced code block (php) -#: en/caching/data.md +#: ../../guide/en/caching/data.md #, no-wrap msgid "" "$ttl = 3600;\n" @@ -265,7 +266,7 @@ msgid "" msgstr "" #. type: Plain text -#: en/caching/data.md +#: ../../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 " @@ -274,35 +275,35 @@ msgid "" msgstr "" #. type: Plain text -#: en/caching/data.md -msgid "You may set default TTL for the cache:" +#: ../../guide/en/caching/data.md +msgid "You may set the default TTL for the cache:" msgstr "" #. type: Fenced code block (php) -#: en/caching/data.md +#: ../../guide/en/caching/data.md #, no-wrap msgid "$cache = new \\Yiisoft\\Cache\\Cache($arrayCache, 60 * 60); // 1 hour\n" msgstr "" #. type: Plain text -#: en/caching/data.md +#: ../../guide/en/caching/data.md msgid "Additionally, you can invalidate a cache key explicitly:" msgstr "" #. type: Fenced code block (php) -#: en/caching/data.md +#: ../../guide/en/caching/data.md #, no-wrap msgid "$cache->remove($key);\n" msgstr "" #. type: Title ### -#: en/caching/data.md +#: ../../guide/en/caching/data.md #, no-wrap msgid "Invalidation dependencies" msgstr "" #. type: Plain text -#: en/caching/data.md +#: ../../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, " @@ -313,7 +314,7 @@ msgid "" msgstr "" #. type: Plain text -#: en/caching/data.md +#: ../../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 " @@ -321,7 +322,7 @@ msgid "" msgstr "" #. type: Fenced code block (php) -#: en/caching/data.md +#: ../../guide/en/caching/data.md #, no-wrap msgid "" "/**\n" @@ -340,33 +341,33 @@ msgid "" msgstr "" #. type: Plain text -#: en/caching/data.md +#: ../../guide/en/caching/data.md msgid "Below is a summary of the available cache dependencies:" msgstr "" #. type: Bullet: '- ' -#: en/caching/data.md +#: ../../guide/en/caching/data.md msgid "" "`\\Yiisoft\\Cache\\Dependency\\ValueDependency`: invalidates the cache when " "specified value changes." msgstr "" #. type: Bullet: '- ' -#: en/caching/data.md +#: ../../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: '- ' -#: en/caching/data.md +#: ../../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: '- ' -#: en/caching/data.md +#: ../../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 " @@ -374,7 +375,7 @@ msgid "" msgstr "" #. type: Plain text -#: en/caching/data.md +#: ../../guide/en/caching/data.md msgid "" "You may combine many dependencies using " "`\\Yiisoft\\Cache\\Dependency\\AnyDependency` or " @@ -382,20 +383,20 @@ msgid "" msgstr "" #. type: Plain text -#: en/caching/data.md +#: ../../guide/en/caching/data.md msgid "" "To implement your own dependency, extend from " "`\\Yiisoft\\Cache\\Dependency\\Dependency`." msgstr "" #. type: Title ### -#: en/caching/data.md +#: ../../guide/en/caching/data.md #, no-wrap msgid "Cache stampede prevention" msgstr "" #. type: Plain text -#: en/caching/data.md +#: ../../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 " @@ -404,18 +405,18 @@ msgid "" msgstr "" #. type: Plain text -#: en/caching/data.md +#: ../../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." +"usually enough. The higher the value, the earlier cache will be re-created." msgstr "" #. type: Fenced code block (php) -#: en/caching/data.md +#: ../../guide/en/caching/data.md #, no-wrap msgid "" "/**\n" diff --git a/guide/po/caching_overview.md/caching_overview.md.pot b/_translations/guide/pot/caching_overview.md.pot similarity index 100% rename from guide/po/caching_overview.md/caching_overview.md.pot rename to _translations/guide/pot/caching_overview.md.pot diff --git a/guide/po/concept_aliases.md/concept_aliases.md.pot b/_translations/guide/pot/concept_aliases.md.pot similarity index 100% rename from guide/po/concept_aliases.md/concept_aliases.md.pot rename to _translations/guide/pot/concept_aliases.md.pot diff --git a/guide/po/concept_autoloading.md/concept_autoloading.md.pot b/_translations/guide/pot/concept_autoloading.md.pot similarity index 100% rename from guide/po/concept_autoloading.md/concept_autoloading.md.pot rename to _translations/guide/pot/concept_autoloading.md.pot diff --git a/guide/po/concept_configuration.md/concept_configuration.md.pot b/_translations/guide/pot/concept_configuration.md.pot similarity index 100% rename from guide/po/concept_configuration.md/concept_configuration.md.pot rename to _translations/guide/pot/concept_configuration.md.pot diff --git a/guide/po/concept_di-container.md/concept_di-container.md.pot b/_translations/guide/pot/concept_di-container.md.pot similarity index 83% rename from guide/po/concept_di-container.md/concept_di-container.md.pot rename to _translations/guide/pot/concept_di-container.md.pot index ad2b00f4..400c38a3 100644 --- a/guide/po/concept_di-container.md/concept_di-container.md.pot +++ b/_translations/guide/pot/concept_di-container.md.pot @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2025-09-05 12:06+0000\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,30 +17,30 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" #. type: Title # -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md #, no-wrap msgid "Dependency injection and container" msgstr "" #. type: Title ## -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md #, no-wrap msgid "Dependency injection " msgstr "" #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "" "There are two ways of re-using things in OOP: inheritance and composition." msgstr "" #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "Inheritance is simple:" msgstr "" #. type: Fenced code block (php) -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md #, no-wrap msgid "" "class Cache\n" @@ -65,19 +65,19 @@ msgid "" msgstr "" #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "" "The issue here is that these two are becoming unnecessarily coupled or inter-" -"dependent making them more fragile." +"dependent, making them more fragile." msgstr "" #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "Another way to handle this is composition:" msgstr "" #. type: Fenced code block (php) -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md #, no-wrap msgid "" "interface CacheInterface\n" @@ -113,7 +113,7 @@ msgid "" msgstr "" #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "" "We've avoided unnecessary inheritance and used interface to reduce coupling. " "You can replace cache implementation without changing `CachedWidget` so it's " @@ -121,7 +121,7 @@ msgid "" msgstr "" #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "" "The `CacheInterface` here is a dependency: an object another object depends " "on. The process of putting an instance of dependency into an object " @@ -130,37 +130,37 @@ msgid "" msgstr "" #. type: Bullet: '- ' -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "Constructor injection. Best for mandatory dependencies." msgstr "" #. type: Bullet: '- ' -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "Method injection. Best for optional dependencies." msgstr "" #. type: Bullet: '- ' -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "" "Property injection. Better to be avoided in PHP except maybe data transfer " "objects." msgstr "" #. type: Title ### -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md #, no-wrap msgid "Why use private properties " msgstr "" #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "" "In the composition example above, note that the `$cache` property is " "declared as `private`." msgstr "" #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/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 " @@ -168,26 +168,26 @@ msgid "" msgstr "" #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "This design choice provides several benefits:" msgstr "" #. type: Bullet: '- ' -#: en/concept/di-container.md +#: ../../guide/en/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: '- ' -#: en/concept/di-container.md +#: ../../guide/en/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: '- ' -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "" "**Immutability**: Private properties enable immutable object patterns where " "setter `with*()` methods return new instances rather than modifying the " @@ -195,20 +195,20 @@ msgid "" msgstr "" #. type: Bullet: '- ' -#: en/concept/di-container.md +#: ../../guide/en/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 ## -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md #, no-wrap msgid "DI container " msgstr "" #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/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, " @@ -217,7 +217,7 @@ msgid "" msgstr "" #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/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 " @@ -227,29 +227,29 @@ msgid "" msgstr "" #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/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: '- ' -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "Define how to instantiate such an API wrapper." msgstr "" #. type: Bullet: '- ' -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "Instantiate it when required and only once per request." msgstr "" #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "That's what dependency containers are for." msgstr "" #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "" "A dependency injection (DI) container is an object that knows how to " "instantiate and configure objects and all their dependent objects. [Martin " @@ -259,7 +259,7 @@ msgid "" msgstr "" #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/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/" @@ -267,13 +267,13 @@ msgid "" msgstr "" #. type: Title ### -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md #, no-wrap msgid "Configuring container " msgstr "" #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/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 " @@ -281,7 +281,7 @@ msgid "" msgstr "" #. type: Fenced code block (php) -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md #, no-wrap msgid "" "final class MyService implements MyServiceInterface\n" @@ -298,12 +298,12 @@ msgid "" msgstr "" #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "configuration could be:" msgstr "" #. type: Fenced code block (php) -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md #, no-wrap msgid "" "return [\n" @@ -316,12 +316,12 @@ msgid "" msgstr "" #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "That's equal to the following:" msgstr "" #. type: Fenced code block (php) -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md #, no-wrap msgid "" "$myService = new MyService(42);\n" @@ -329,12 +329,12 @@ msgid "" msgstr "" #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "There are extra methods of declaring dependencies:" msgstr "" #. type: Fenced code block (php) -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md #, no-wrap msgid "" "return [\n" @@ -363,13 +363,13 @@ msgid "" msgstr "" #. type: Title ### -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md #, no-wrap msgid "Injecting dependencies " msgstr "" #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/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, " @@ -379,13 +379,13 @@ msgid "" msgstr "" #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "" "This is primarily done in constructor and handing method of action handlers:" msgstr "" #. type: Fenced code block (php) -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md #, no-wrap msgid "" "use \\Yiisoft\\Cache\\CacheInterface;\n" @@ -413,7 +413,7 @@ msgid "" msgstr "" #. type: Plain text -#: en/concept/di-container.md +#: ../../guide/en/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 " @@ -426,13 +426,13 @@ msgid "" msgstr "" #. type: Title ## -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md #, no-wrap msgid "References " msgstr "" #. type: Bullet: '- ' -#: en/concept/di-container.md +#: ../../guide/en/concept/di-container.md msgid "" "[Inversion of Control Containers and the Dependency Injection pattern by " "Martin Fowler](https://martinfowler.com/articles/injection.html)" diff --git a/guide/po/concept_events.md/concept_events.md.pot b/_translations/guide/pot/concept_events.md.pot similarity index 100% rename from guide/po/concept_events.md/concept_events.md.pot rename to _translations/guide/pot/concept_events.md.pot diff --git a/guide/po/concept_immutability.md/concept_immutability.md.pot b/_translations/guide/pot/concept_immutability.md.pot similarity index 88% rename from guide/po/concept_immutability.md/concept_immutability.md.pot rename to _translations/guide/pot/concept_immutability.md.pot index 5c38218f..28caa6c8 100644 --- a/guide/po/concept_immutability.md/concept_immutability.md.pot +++ b/_translations/guide/pot/concept_immutability.md.pot @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2025-09-04 11:19+0500\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,13 +17,13 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" #. type: Title # -#: en/concept/immutability.md +#: ../../guide/en/concept/immutability.md #, no-wrap msgid "Immutability" msgstr "" #. type: Plain text -#: en/concept/immutability.md +#: ../../guide/en/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 " @@ -33,13 +33,13 @@ msgid "" msgstr "" #. type: Title ## -#: en/concept/immutability.md +#: ../../guide/en/concept/immutability.md #, no-wrap msgid "Mutable pitfalls (what we avoid)" msgstr "" #. type: Fenced code block (php) -#: en/concept/immutability.md +#: ../../guide/en/concept/immutability.md #, no-wrap msgid "" "// A shared base query built once and reused:\n" @@ -54,13 +54,13 @@ msgid "" msgstr "" #. type: Title ## -#: en/concept/immutability.md +#: ../../guide/en/concept/immutability.md #, no-wrap msgid "Creating an immutable object in PHP" msgstr "" #. type: Plain text -#: en/concept/immutability.md +#: ../../guide/en/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*` " @@ -68,7 +68,7 @@ msgid "" msgstr "" #. type: Fenced code block (php) -#: en/concept/immutability.md +#: ../../guide/en/concept/immutability.md #, no-wrap msgid "" "final class Money\n" @@ -146,21 +146,21 @@ msgid "" msgstr "" #. type: Bullet: '- ' -#: en/concept/immutability.md +#: ../../guide/en/concept/immutability.md msgid "" "We mark the class `final` to prevent subclass mutations; alternatively, " "design for extension carefully." msgstr "" #. type: Bullet: '- ' -#: en/concept/immutability.md +#: ../../guide/en/concept/immutability.md msgid "" "Validate in the constructor and `with*` methods so every instance is always " "valid." msgstr "" #. type: Plain text -#: en/concept/immutability.md +#: ../../guide/en/concept/immutability.md #, no-wrap msgid "" "> [!TIP]\n" @@ -169,13 +169,13 @@ msgid "" msgstr "" #. type: Title ## -#: en/concept/immutability.md +#: ../../guide/en/concept/immutability.md #, no-wrap -msgid "Using clone (and why it is cheap)" +msgid "Using clone (and why it is inexpensive)" msgstr "" #. type: Plain text -#: en/concept/immutability.md +#: ../../guide/en/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 " @@ -184,14 +184,14 @@ msgid "" msgstr "" #. type: Plain text -#: en/concept/immutability.md +#: ../../guide/en/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) -#: en/concept/immutability.md +#: ../../guide/en/concept/immutability.md #, no-wrap msgid "" "final class Order\n" @@ -221,27 +221,27 @@ msgid "" msgstr "" #. type: Title ## -#: en/concept/immutability.md +#: ../../guide/en/concept/immutability.md #, no-wrap msgid "Usage style" msgstr "" #. type: Bullet: '- ' -#: en/concept/immutability.md +#: ../../guide/en/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: '- ' -#: en/concept/immutability.md +#: ../../guide/en/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 -#: en/concept/immutability.md +#: ../../guide/en/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." diff --git a/guide/po/databases_db-migrations.md/databases_db-migrations.md.pot b/_translations/guide/pot/databases_db-migrations.md.pot similarity index 78% rename from guide/po/databases_db-migrations.md/databases_db-migrations.md.pot rename to _translations/guide/pot/databases_db-migrations.md.pot index 1a0ab593..525c791f 100644 --- a/guide/po/databases_db-migrations.md/databases_db-migrations.md.pot +++ b/_translations/guide/pot/databases_db-migrations.md.pot @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2025-09-04 11:19+0500\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,39 +17,39 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" #. type: Title # -#: en/databases/db-migrations.md +#: ../../guide/en/databases/db-migrations.md #, no-wrap msgid "Migrations" msgstr "" #. type: Plain text -#: en/databases/db-migrations.md +#: ../../guide/en/databases/db-migrations.md msgid "" "To use migrations, install [yiisoft/db-migration](https://github.com/yiisoft/" "db-migration/) package:" msgstr "" #. type: Fenced code block (shell) -#: en/databases/db-migrations.md +#: ../../guide/en/databases/db-migrations.md #, no-wrap msgid "composer require yiisoft/db-migration\n" msgstr "" #. type: Title ### -#: en/databases/db-migrations.md +#: ../../guide/en/databases/db-migrations.md #, no-wrap msgid "Example usage" msgstr "" #. type: Plain text -#: en/databases/db-migrations.md +#: ../../guide/en/databases/db-migrations.md msgid "" -"First, configure DI container. Create `config/common/db.php` with the " +"First, configure a DI container. Create `config/common/db.php` with the " "following content:" msgstr "" #. type: Fenced code block (php) -#: en/databases/db-migrations.md +#: ../../guide/en/databases/db-migrations.md #, no-wrap msgid "" ", YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: en_US\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Title # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "A" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "alias" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "asset" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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." +msgstr "" + +#. type: Title # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "C" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "configuration" +msgstr "" + +#. type: Plain text +#: ../../guide/en/glossary.md +msgid "" +"The 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 # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "D" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "DI" +msgstr "" + +#. type: Plain text +#: ../../guide/en/glossary.md +msgid "" +"Dependency Injection is a programming technique where an object injects a " +"dependent object. [\"DI\"](concept/di-container.md)" +msgstr "" + +#. type: Title # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "I" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "installation" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "M" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "middleware" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "module" +msgstr "" + +#. type: Plain text +#: ../../guide/en/glossary.md +msgid "" +"The module is a sub-application that groups some code based on a use-case. " +"It's typically used within the main application and may contain URL handlers " +"or console commands." +msgstr "" + +#. type: Title # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "N" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "namespace" +msgstr "" + +#. type: Plain text +#: ../../guide/en/glossary.md +msgid "" +"Namespace refers to a [PHP language feature](https://www.php.net/manual/en/" +"language.namespaces.php)." +msgstr "" + +#. type: Title # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "P" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "package" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 package manager." +msgstr "" + +#. type: Title # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "R" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "rule" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "Q" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "queue" +msgstr "" + +#. type: Plain text +#: ../../guide/en/glossary.md +msgid "" +"A queue is similar to a stack. Queue follows First-In-First-Out methodology." +msgstr "" + +#. type: Title # +#: ../../guide/en/glossary.md +#, no-wrap +msgid "V" +msgstr "" + +#. type: Title ## +#: ../../guide/en/glossary.md +#, no-wrap +msgid "vendor" +msgstr "" + +#. type: Plain text +#: ../../guide/en/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 "" diff --git a/guide/po/intro_upgrade-from-v2.md/intro_upgrade-from-v2.md.pot b/_translations/guide/pot/intro_upgrade-from-v2.md.pot similarity index 100% rename from guide/po/intro_upgrade-from-v2.md/intro_upgrade-from-v2.md.pot rename to _translations/guide/pot/intro_upgrade-from-v2.md.pot diff --git a/guide/po/intro_what-is-yii.md/intro_what-is-yii.md.pot b/_translations/guide/pot/intro_what-is-yii.md.pot similarity index 81% rename from guide/po/intro_what-is-yii.md/intro_what-is-yii.md.pot rename to _translations/guide/pot/intro_what-is-yii.md.pot index 8e5d0560..ef4740e4 100644 --- a/guide/po/intro_what-is-yii.md/intro_what-is-yii.md.pot +++ b/_translations/guide/pot/intro_what-is-yii.md.pot @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2025-09-04 07:51+0500\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,13 +17,13 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" #. type: Title # -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md #, no-wrap msgid "What is Yii" msgstr "" #. type: Plain text -#: en/intro/what-is-yii.md +#: ../../guide/en/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 " @@ -32,13 +32,13 @@ msgid "" msgstr "" #. type: Title ## -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md #, no-wrap msgid "What's Yii best for" msgstr "" #. type: Plain text -#: en/intro/what-is-yii.md +#: ../../guide/en/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 " @@ -48,57 +48,57 @@ msgid "" msgstr "" #. type: Title ## -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md #, no-wrap msgid "How does Yii compare with other frameworks?" msgstr "" #. type: Plain text -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md msgid "" "If you're already familiar with another framework, you may appreciate " "knowing how Yii compares:" msgstr "" #. type: Bullet: '- ' -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md msgid "" "Yii takes the [philosophy of being practical and helpful](https://github.com/" "yiisoft/docs/blob/master/001-yii-values.md) achieving:" msgstr "" #. type: Bullet: ' - ' -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md msgid "Performance in both development and execution." msgstr "" #. type: Bullet: ' - ' -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md msgid "Convenient customizable defaults." msgstr "" #. type: Bullet: ' - ' -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md msgid "Practice-orientation." msgstr "" #. type: Bullet: ' - ' -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md msgid "Simplicity." msgstr "" #. type: Bullet: ' - ' -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md msgid "Explicitness." msgstr "" #. type: Bullet: ' - ' -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md msgid "Consistency." msgstr "" #. type: Plain text -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md #, no-wrap msgid "" " Yii will never try to over-design things mainly to follow some design patterns.\n" @@ -112,7 +112,7 @@ msgid "" msgstr "" #. type: Plain text -#: en/intro/what-is-yii.md +#: ../../guide/en/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://" @@ -125,51 +125,51 @@ msgid "" msgstr "" #. type: Title ## -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md #, no-wrap msgid "Yii versions" msgstr "" #. type: Plain text -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md msgid "Yii currently has three major versions available: 1.1, 2.0, and 3.0." msgstr "" #. type: Bullet: '- ' -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md msgid "" "Version 1.1 is the old generation and is now in the feature freeze bugfix " "mode." msgstr "" #. type: Bullet: '- ' -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md msgid "" "Version 2.0 is a current stable version in the feature freeze bugfix mode." msgstr "" #. type: Bullet: '- ' -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md msgid "" "Version 3.0 is the current version in development. This guide is mainly " "about version 3." msgstr "" #. type: Title ## -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md #, no-wrap msgid "Requirements and prerequisites" msgstr "" #. type: Plain text -#: en/intro/what-is-yii.md +#: ../../guide/en/intro/what-is-yii.md msgid "" -"Yii3 requires PHP 8.2 or above, but some packages also older PHP such as PHP " -"7.4." +"Yii3 requires PHP 8.2 or above, but some packages work with older PHP, such " +"as PHP 7.4." msgstr "" #. type: Plain text -#: en/intro/what-is-yii.md +#: ../../guide/en/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 " diff --git a/guide/po/runtime_cookies.md/runtime_cookies.md.pot b/_translations/guide/pot/runtime_cookies.md.pot similarity index 100% rename from guide/po/runtime_cookies.md/runtime_cookies.md.pot rename to _translations/guide/pot/runtime_cookies.md.pot diff --git a/guide/po/runtime_handling-errors.md/runtime_handling-errors.md.pot b/_translations/guide/pot/runtime_handling-errors.md.pot similarity index 100% rename from guide/po/runtime_handling-errors.md/runtime_handling-errors.md.pot rename to _translations/guide/pot/runtime_handling-errors.md.pot diff --git a/guide/po/runtime_logging.md/runtime_logging.md.pot b/_translations/guide/pot/runtime_logging.md.pot similarity index 100% rename from guide/po/runtime_logging.md/runtime_logging.md.pot rename to _translations/guide/pot/runtime_logging.md.pot diff --git a/guide/po/runtime_request.md/runtime_request.md.pot b/_translations/guide/pot/runtime_request.md.pot similarity index 100% rename from guide/po/runtime_request.md/runtime_request.md.pot rename to _translations/guide/pot/runtime_request.md.pot diff --git a/guide/po/runtime_response.md/runtime_response.md.pot b/_translations/guide/pot/runtime_response.md.pot similarity index 100% rename from guide/po/runtime_response.md/runtime_response.md.pot rename to _translations/guide/pot/runtime_response.md.pot diff --git a/guide/po/runtime_routing.md/runtime_routing.md.pot b/_translations/guide/pot/runtime_routing.md.pot similarity index 100% rename from guide/po/runtime_routing.md/runtime_routing.md.pot rename to _translations/guide/pot/runtime_routing.md.pot diff --git a/guide/po/runtime_sessions.md/runtime_sessions.md.pot b/_translations/guide/pot/runtime_sessions.md.pot similarity index 100% rename from guide/po/runtime_sessions.md/runtime_sessions.md.pot rename to _translations/guide/pot/runtime_sessions.md.pot diff --git a/guide/po/security_authentication.md/security_authentication.md.pot b/_translations/guide/pot/security_authentication.md.pot similarity index 80% rename from guide/po/security_authentication.md/security_authentication.md.pot rename to _translations/guide/pot/security_authentication.md.pot index c7d17197..950b677c 100644 --- a/guide/po/security_authentication.md/security_authentication.md.pot +++ b/_translations/guide/pot/security_authentication.md.pot @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2025-09-04 11:19+0500\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,13 +17,13 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" #. type: Title # -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md #, no-wrap msgid "Authentication" msgstr "" #. type: Plain text -#: en/security/authentication.md +#: ../../guide/en/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 " @@ -33,7 +33,7 @@ msgid "" msgstr "" #. type: Plain text -#: en/security/authentication.md +#: ../../guide/en/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 " @@ -41,32 +41,32 @@ msgid "" msgstr "" #. type: Bullet: '* ' -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md msgid "Configure the `Yiisoft\\Yii\\Web\\User\\User` service;" msgstr "" #. type: Bullet: '* ' -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md msgid "" "Create a class implementing the `\\Yiisoft\\Auth\\IdentityInterface` " "interface;" msgstr "" #. type: Bullet: '* ' -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md msgid "" "Create a class implementing the " "`\\Yiisoft\\Auth\\IdentityRepositoryInterface` interface;" msgstr "" #. type: Title ## -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md #, no-wrap msgid "Configuring `Yiisoft\\Yii\\Web\\User\\User` " msgstr "" #. type: Plain text -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md msgid "" "The `Yiisoft\\Yii\\Web\\User\\User` application service manages the user " "authentication status. It depends on " @@ -76,7 +76,7 @@ msgid "" msgstr "" #. type: Fenced code block (php) -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md #, no-wrap msgid "" "use Yiisoft\\Session\\Session;\n" @@ -98,40 +98,41 @@ msgid "" " \n" " // User:\n" " IdentityRepositoryInterface::class => static function (ContainerInterface $container) {\n" -" // instead of Cycle-based repository, you can use any implementation\n" +" // instead of a Cycle-based repository, you can use any implementation\n" " return $container->get(\\Cycle\\ORM\\ORMInterface::class)->getRepository(\\App\\Entity\\User::class);\n" " },\n" "];\n" msgstr "" #. type: Title ## -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md #, no-wrap msgid "Implementing`\\Yiisoft\\Auth\\IdentityInterface` " msgstr "" #. type: Plain text -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md msgid "" "The identity class must implement the `\\Yiisoft\\Auth\\IdentityInterface` " "which has a single method:" msgstr "" #. type: Bullet: '* ' -#: en/security/authentication.md +#: ../../guide/en/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 -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md msgid "" -"In the following example, an identity class implemented as a pure PHP object." +"In the following example, an identity class is implemented as a pure PHP " +"object." msgstr "" #. type: Fenced code block (php) -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md #, no-wrap msgid "" "" msgstr "" #. type: Plain text -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md msgid "" "The identity repository class must implement the " "`\\Yiisoft\\Auth\\IdentityRepositoryInterface` which has the following " @@ -169,7 +170,7 @@ msgid "" msgstr "" #. type: Bullet: '* ' -#: en/security/authentication.md +#: ../../guide/en/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 " @@ -177,7 +178,7 @@ msgid "" msgstr "" #. type: Bullet: '* ' -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md msgid "" "`findIdentityByToken(string $token, string $type): ?IdentityInterface`: it " "looks for an instance of the identity class using the specified access " @@ -186,12 +187,12 @@ msgid "" msgstr "" #. type: Plain text -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md msgid "A dummy implementation may look like the following:" msgstr "" #. type: Fenced code block (php) -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md #, no-wrap msgid "" "namespace App\\User;\n" @@ -238,21 +239,21 @@ msgid "" msgstr "" #. type: Title ## -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md #, no-wrap msgid "Using `\\Yiisoft\\User\\User` " msgstr "" #. type: Plain text -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md msgid "" -"You can use `\\Yiisoft\\User\\User` service to obtain current user " -"identity. As any service, it could be auto wired in either action handler " -"constructor or method:" +"You can use `\\Yiisoft\\User\\User` 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) -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md #, no-wrap msgid "" "use \\Psr\\Http\\Message\\ServerRequestInterface;\n" @@ -273,19 +274,19 @@ msgid "" msgstr "" #. type: Plain text -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md msgid "" "`isGuest()` determines if user is logged in or not. `getIdentity()` returns " "an instance of identity." msgstr "" #. type: Plain text -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md msgid "To log in a user, you may use the following code:" msgstr "" #. type: Fenced code block (php) -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md #, no-wrap msgid "" "$identity = $identityRepository->findByEmail($email);\n" @@ -295,19 +296,19 @@ msgid "" msgstr "" #. type: Plain text -#: en/security/authentication.md +#: ../../guide/en/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 -#: en/security/authentication.md -msgid "To logout a user, simply call" +#: ../../guide/en/security/authentication.md +msgid "To log out a user, call" msgstr "" #. type: Fenced code block (php) -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md #, no-wrap msgid "" "/* @var $user \\Yiisoft\\User\\User */\n" @@ -315,19 +316,19 @@ msgid "" msgstr "" #. type: Title ## -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md #, no-wrap msgid "Authentication Events " msgstr "" #. type: Plain text -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md msgid "" "The user service raises a few events during the login and logout processes." msgstr "" #. type: Bullet: '* ' -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md msgid "" "`\\Yiisoft\\User\\Event\\BeforeLogin`: raised at the beginning of " "`login()`. If the event handler calls `invalidate()` on an event object, " @@ -335,12 +336,12 @@ msgid "" msgstr "" #. type: Bullet: '* ' -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md msgid "`\\Yiisoft\\User\\Event\\AfterLogin`: raised after a successful login." msgstr "" #. type: Bullet: '* ' -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md msgid "" "`\\Yiisoft\\User\\Event\\BeforeLogout`: raised at the beginning of " "`logout()`. If the event handler calls `invalidate()` on an event object, " @@ -348,13 +349,13 @@ msgid "" msgstr "" #. type: Bullet: '* ' -#: en/security/authentication.md +#: ../../guide/en/security/authentication.md msgid "" "`\\Yiisoft\\User\\Event\\AfterLogout`: raised after a successful logout." msgstr "" #. type: Plain text -#: en/security/authentication.md +#: ../../guide/en/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 " diff --git a/guide/po/security_authorization.md/security_authorization.md.pot b/_translations/guide/pot/security_authorization.md.pot similarity index 81% rename from guide/po/security_authorization.md/security_authorization.md.pot rename to _translations/guide/pot/security_authorization.md.pot index d14b9484..7eb5269d 100644 --- a/guide/po/security_authorization.md/security_authorization.md.pot +++ b/_translations/guide/pot/security_authorization.md.pot @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2025-09-04 11:19+0500\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,33 +17,33 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" #. type: Title # -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "Authorization" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "" "Authorization is the process of verifying that a user has enough permission " "to do something." msgstr "" #. type: Title ## -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "Checking for permission " msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "" "You can check if a user has certain permissions by using " "`\\Yiisoft\\User\\User` service:" msgstr "" #. type: Fenced code block (php) -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "" "namespace App\\Blog\\Post;\n" @@ -80,7 +80,7 @@ msgid "" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "" "Behind the scenes, `Yiisoft\\Yii\\Web\\User\\User::can()` method calls " "`\\Yiisoft\\Access\\AccessCheckerInterface::userHasPermission()` so you " @@ -89,13 +89,13 @@ msgid "" msgstr "" #. type: Title ## -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "Role-based access control (RBAC) " msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/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/" @@ -104,7 +104,7 @@ msgid "" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/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/" @@ -113,7 +113,7 @@ msgid "" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/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 " @@ -123,18 +123,18 @@ msgid "" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "To ease description next, there are some basic RBAC concepts first." msgstr "" #. type: Title ### -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "Basic concepts " msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/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 " @@ -143,18 +143,18 @@ msgid "" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "" "Associated with each role or permission, there may be a *rule*. A rule " -"represents a piece of code that 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." +"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 -#: en/security/authorization.md +#: ../../guide/en/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 " @@ -164,25 +164,25 @@ msgid "" msgstr "" #. type: Title ### -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "Configuring RBAC " msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "" "RBAC is available via `yiisoft/rbac` package, so you need to require it:" msgstr "" #. type: Fenced code block -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "composer require yiisoft/rbac\n" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/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 " @@ -190,7 +190,7 @@ msgid "" msgstr "" #. type: Fenced code block (php) -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "" "use \\Psr\\Container\\ContainerInterface;\n" @@ -206,52 +206,52 @@ msgid "" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "" -"`\\Yiisoft\\Rbac\\Manager\\PhpManager` uses a PHP script files to store " +"`\\Yiisoft\\Rbac\\Manager\\PhpManager` uses PHP script files to store " "authorization data. The files are under `@rbac` alias. 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 ### -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "Building authorization data " msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "Building authorization data is all about the following tasks:" msgstr "" #. type: Bullet: '- ' -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "defining roles and permissions;" msgstr "" #. type: Bullet: '- ' -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "establishing relations between roles and permissions;" msgstr "" #. type: Bullet: '- ' -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "defining rules;" msgstr "" #. type: Bullet: '- ' -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "associating rules with roles and permissions;" msgstr "" #. type: Bullet: '- ' -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "assigning roles to users." msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/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 " @@ -262,18 +262,18 @@ msgid "" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "Either way, in the end, you'll get the following RBAC hierarchy:" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "" "![Simple RBAC hierarchy](img/rbac-hierarchy-1.svg \"Simple RBAC hierarchy\")" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/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 " @@ -281,13 +281,13 @@ msgid "" msgstr "" #. type: Title ### -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "Using console command" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/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-" @@ -296,7 +296,7 @@ msgid "" msgstr "" #. type: Fenced code block (php) -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "" "withDescription('Update post');\n" " $auth->add($updatePost);\n" "\n" -" // add \"author\" role and give this role the \"createPost\" permission\n" +" // add the \"author\" role and give this role the \"createPost\" permission\n" " $author = new Role('author');\n" " $auth->add($author);\n" " $auth->addChild($author, $createPost);\n" @@ -356,18 +356,18 @@ msgid "" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "You can execute the command above from the console the following way:" msgstr "" #. type: Fenced code block -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "./yii rbac:init\n" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/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" @@ -375,33 +375,33 @@ msgid "" msgstr "" #. type: Title #### -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "Using migrations" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "**TODO**: finish it when migrations are implemented.\n" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/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 -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "" "Create new migration using `./yii migrate:create init_rbac` then implement " "creating a hierarchy:" msgstr "" #. type: Fenced code block (php) -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "" "withDescription('Update post');\n" " $auth->add($updatePost);\n" "\n" -" // add \"author\" role and give this role the \"createPost\" permission\n" +" // add the \"author\" role and give this role the \"createPost\" permission\n" " $author = new Role('author');\n" " $auth->add($author);\n" " $auth->addChild($author, $createPost);\n" @@ -453,7 +453,7 @@ msgid "" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/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" @@ -461,40 +461,40 @@ msgid "" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "You could apply migration by using `./yii migrate`." msgstr "" #. type: Title ## -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "Assigning roles to users" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "TODO: update when signup implemented in demo / template.\n" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "" -"The author can create a post, admin can update post and do everything the " -"author can." +"The author can create a post, admin can update the post and do everything " +"the author can." msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "" "If your application allows user signup, you need to assign roles to these " -"new users once. For example, in order for all signed-up users to become " -"authors in your advanced project template you need to change " +"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) -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "" "public function signup()\n" @@ -520,7 +520,7 @@ msgid "" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/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 " @@ -528,13 +528,13 @@ msgid "" msgstr "" #. type: Title ### -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "Using rules " msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/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 " @@ -544,7 +544,7 @@ msgid "" msgstr "" #. type: Fenced code block (php) -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "" "namespace App\\User\\Rbac;\n" @@ -553,7 +553,7 @@ msgid "" "use \\Yiisoft\\Rbac\\Rule;\n" "\n" "/**\n" -" * Checks if authorID matches user passed via params.\n" +" * Checks if the authorID matches user passed via params.\n" " */\n" "final readonly class AuthorRule extends Rule\n" "{\n" @@ -571,14 +571,14 @@ msgid "" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/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) -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "" "/** @var \\Yiisoft\\Rbac\\ManagerInterface $auth */\n" @@ -601,32 +601,32 @@ msgid "" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "Now you've got the following hierarchy:" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "" "![RBAC hierarchy with a rule](img/rbac-hierarchy-2.svg \"RBAC hierarchy with " "a rule\")" msgstr "" #. type: Title ### -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "Access check " msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "" -"The check is done similar to how it was done in the first section of this " +"The check is done similarly to how it was done in the first section of this " "guide:" msgstr "" #. type: Fenced code block (php) -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "" "namespace App\\Blog\\Post;\n" @@ -663,32 +663,33 @@ msgid "" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "" -"The difference is that now checking for user's own post is part of the RBAC." +"The difference is that now checking for a user's own post is part of the " +"RBAC." msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/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 -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "![Access check](img/rbac-access-check-1.svg \"Access check\")" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/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) -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "" "if ($user->can('updatePost', ['post' => $post])) {\n" @@ -697,17 +698,17 @@ msgid "" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "Here is what happens if the current user is John:" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "![Access check](img/rbac-access-check-2.svg \"Access check\")" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "" "You're starting with the `updatePost` and going through `updateOwnPost`. To pass the access check, `AuthorRule`\n" @@ -717,30 +718,30 @@ msgid "" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "In the case of Jane, it's a bit simpler since she is an admin:" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md msgid "![Access check](img/rbac-access-check-3.svg \"Access check\")" msgstr "" #. type: Title ## -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "Implementing your own access checker" msgstr "" #. type: Plain text -#: en/security/authorization.md +#: ../../guide/en/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) -#: en/security/authorization.md +#: ../../guide/en/security/authorization.md #, no-wrap msgid "" "namespace App\\User;\n" diff --git a/guide/po/security_best-practices.md/security_best-practices.md.pot b/_translations/guide/pot/security_best-practices.md.pot similarity index 100% rename from guide/po/security_best-practices.md/security_best-practices.md.pot rename to _translations/guide/pot/security_best-practices.md.pot diff --git a/guide/po/security_cryptography.md/security_cryptography.md.pot b/_translations/guide/pot/security_cryptography.md.pot similarity index 100% rename from guide/po/security_cryptography.md/security_cryptography.md.pot rename to _translations/guide/pot/security_cryptography.md.pot diff --git a/guide/po/security_overview.md/security_overview.md.pot b/_translations/guide/pot/security_overview.md.pot similarity index 100% rename from guide/po/security_overview.md/security_overview.md.pot rename to _translations/guide/pot/security_overview.md.pot diff --git a/guide/po/security_passwords.md/security_passwords.md.pot b/_translations/guide/pot/security_passwords.md.pot similarity index 100% rename from guide/po/security_passwords.md/security_passwords.md.pot rename to _translations/guide/pot/security_passwords.md.pot diff --git a/guide/po/security_trusted-request.md/security_trusted-request.md.pot b/_translations/guide/pot/security_trusted-request.md.pot similarity index 100% rename from guide/po/security_trusted-request.md/security_trusted-request.md.pot rename to _translations/guide/pot/security_trusted-request.md.pot diff --git a/guide/po/start_creating-project.md/start_creating-project.md.pot b/_translations/guide/pot/start_creating-project.md.pot similarity index 100% rename from guide/po/start_creating-project.md/start_creating-project.md.pot rename to _translations/guide/pot/start_creating-project.md.pot diff --git a/guide/po/start_databases.md/start_databases.md.pot b/_translations/guide/pot/start_databases.md.pot similarity index 100% rename from guide/po/start_databases.md/start_databases.md.pot rename to _translations/guide/pot/start_databases.md.pot diff --git a/guide/po/start_forms.md/start_forms.md.pot b/_translations/guide/pot/start_forms.md.pot similarity index 100% rename from guide/po/start_forms.md/start_forms.md.pot rename to _translations/guide/pot/start_forms.md.pot diff --git a/guide/po/start_gii.md/start_gii.md.pot b/_translations/guide/pot/start_gii.md.pot similarity index 100% rename from guide/po/start_gii.md/start_gii.md.pot rename to _translations/guide/pot/start_gii.md.pot diff --git a/guide/po/start_hello.md/start_hello.md.pot b/_translations/guide/pot/start_hello.md.pot similarity index 100% rename from guide/po/start_hello.md/start_hello.md.pot rename to _translations/guide/pot/start_hello.md.pot diff --git a/guide/po/start_looking-ahead.md/start_looking-ahead.md.pot b/_translations/guide/pot/start_looking-ahead.md.pot similarity index 100% rename from guide/po/start_looking-ahead.md/start_looking-ahead.md.pot rename to _translations/guide/pot/start_looking-ahead.md.pot diff --git a/guide/po/start_prerequisites.md/start_prerequisites.md.pot b/_translations/guide/pot/start_prerequisites.md.pot similarity index 100% rename from guide/po/start_prerequisites.md/start_prerequisites.md.pot rename to _translations/guide/pot/start_prerequisites.md.pot diff --git a/guide/po/start_workflow.md/start_workflow.md.pot b/_translations/guide/pot/start_workflow.md.pot similarity index 100% rename from guide/po/start_workflow.md/start_workflow.md.pot rename to _translations/guide/pot/start_workflow.md.pot diff --git a/guide/po/structure_action.md/structure_action.md.pot b/_translations/guide/pot/structure_action.md.pot similarity index 100% rename from guide/po/structure_action.md/structure_action.md.pot rename to _translations/guide/pot/structure_action.md.pot diff --git a/guide/po/structure_application.md/structure_application.md.pot b/_translations/guide/pot/structure_application.md.pot similarity index 100% rename from guide/po/structure_application.md/structure_application.md.pot rename to _translations/guide/pot/structure_application.md.pot diff --git a/guide/po/structure_domain.md/structure_domain.md.pot b/_translations/guide/pot/structure_domain.md.pot similarity index 100% rename from guide/po/structure_domain.md/structure_domain.md.pot rename to _translations/guide/pot/structure_domain.md.pot diff --git a/guide/po/structure_entry-script.md/structure_entry-script.md.pot b/_translations/guide/pot/structure_entry-script.md.pot similarity index 100% rename from guide/po/structure_entry-script.md/structure_entry-script.md.pot rename to _translations/guide/pot/structure_entry-script.md.pot diff --git a/guide/po/structure_handler.md/structure_handler.md.pot b/_translations/guide/pot/structure_handler.md.pot similarity index 100% rename from guide/po/structure_handler.md/structure_handler.md.pot rename to _translations/guide/pot/structure_handler.md.pot diff --git a/guide/po/structure_middleware.md/structure_middleware.md.pot b/_translations/guide/pot/structure_middleware.md.pot similarity index 74% rename from guide/po/structure_middleware.md/structure_middleware.md.pot rename to _translations/guide/pot/structure_middleware.md.pot index 41b83349..9b2c2459 100644 --- a/guide/po/structure_middleware.md/structure_middleware.md.pot +++ b/_translations/guide/pot/structure_middleware.md.pot @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2025-09-04 11:19+0500\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,13 +17,13 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" #. type: Title # -#: en/structure/middleware.md +#: ../../guide/en/structure/middleware.md #, no-wrap msgid "Middleware" msgstr "" #. type: Plain text -#: en/structure/middleware.md +#: ../../guide/en/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 " @@ -31,7 +31,7 @@ msgid "" msgstr "" #. type: Plain text -#: en/structure/middleware.md +#: ../../guide/en/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 " @@ -40,57 +40,57 @@ msgid "" msgstr "" #. type: Bullet: '- ' -#: en/structure/middleware.md +#: ../../guide/en/structure/middleware.md msgid "" "Pass the request to the next middleware performing some work before / after " "it." msgstr "" #. type: Bullet: '- ' -#: en/structure/middleware.md +#: ../../guide/en/structure/middleware.md msgid "Form the response and return it." msgstr "" #. type: Plain text -#: en/structure/middleware.md +#: ../../guide/en/structure/middleware.md msgid "" "Depending on middleware used, application behavior may vary significantly." msgstr "" #. type: Plain text -#: en/structure/middleware.md +#: ../../guide/en/structure/middleware.md msgid "![Middleware](img/middleware.svg)" msgstr "" #. type: Plain text -#: en/structure/middleware.md +#: ../../guide/en/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 -#: en/structure/middleware.md +#: ../../guide/en/structure/middleware.md msgid "![Middleware](img/middleware_alternative.svg)" msgstr "" #. type: Title ## -#: en/structure/middleware.md +#: ../../guide/en/structure/middleware.md #, no-wrap msgid "Using middleware" msgstr "" #. type: Plain text -#: en/structure/middleware.md +#: ../../guide/en/structure/middleware.md msgid "" -"Any PSR-15 compatible middleware could be used with Yii and there are many. " -"Say, you need to add basic authentication one of the application URLs. URL-" -"dependent middleware is configured using router, so you need to change " -"router factory." +"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 -#: en/structure/middleware.md +#: ../../guide/en/structure/middleware.md msgid "" "Authentication middleware is implemented by `middlewares/http-" "authentication` package so execute `composer require middlewares/http-" @@ -98,13 +98,13 @@ msgid "" msgstr "" #. type: Plain text -#: en/structure/middleware.md +#: ../../guide/en/structure/middleware.md msgid "" "Now register the middleware in DI container configuration `config/web.php`:" msgstr "" #. type: Fenced code block (php) -#: en/structure/middleware.md +#: ../../guide/en/structure/middleware.md #, no-wrap msgid "" "handle($request);\n" msgstr "" #. type: Plain text -#: en/structure/middleware.md +#: ../../guide/en/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) -#: en/structure/middleware.md +#: ../../guide/en/structure/middleware.md #, no-wrap msgid "" "$request = $request->withAttribute('answer', 42);\n" @@ -315,31 +315,31 @@ msgid "" msgstr "" #. type: Plain text -#: en/structure/middleware.md +#: ../../guide/en/structure/middleware.md msgid "To get it in the next middleware:" msgstr "" #. type: Fenced code block (php) -#: en/structure/middleware.md +#: ../../guide/en/structure/middleware.md #, no-wrap msgid "$answer = $request->getAttribute('answer');\n" msgstr "" #. type: Title ### -#: en/structure/middleware.md +#: ../../guide/en/structure/middleware.md #, no-wrap msgid "Capturing response to manipulate it" msgstr "" #. type: Plain text -#: en/structure/middleware.md +#: ../../guide/en/structure/middleware.md msgid "" -"You may want to capture response to manipulate it. It could be useful for " -"adding CORS headers, gzipping content etc." +"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) -#: en/structure/middleware.md +#: ../../guide/en/structure/middleware.md #, no-wrap msgid "" "$response = $next->handle($request);\n" diff --git a/guide/po/structure_overview.md/structure_overview.md.pot b/_translations/guide/pot/structure_overview.md.pot similarity index 100% rename from guide/po/structure_overview.md/structure_overview.md.pot rename to _translations/guide/pot/structure_overview.md.pot diff --git a/guide/po/structure_package.md/structure_package.md.pot b/_translations/guide/pot/structure_package.md.pot similarity index 100% rename from guide/po/structure_package.md/structure_package.md.pot rename to _translations/guide/pot/structure_package.md.pot diff --git a/guide/po/structure_service.md/structure_service.md.pot b/_translations/guide/pot/structure_service.md.pot similarity index 100% rename from guide/po/structure_service.md/structure_service.md.pot rename to _translations/guide/pot/structure_service.md.pot diff --git a/guide/po/tutorial_console-applications.md/tutorial_console-applications.md.pot b/_translations/guide/pot/tutorial_console-applications.md.pot similarity index 100% rename from guide/po/tutorial_console-applications.md/tutorial_console-applications.md.pot rename to _translations/guide/pot/tutorial_console-applications.md.pot diff --git a/guide/po/tutorial_mailing.md/tutorial_mailing.md.pot b/_translations/guide/pot/tutorial_mailing.md.pot similarity index 100% rename from guide/po/tutorial_mailing.md/tutorial_mailing.md.pot rename to _translations/guide/pot/tutorial_mailing.md.pot diff --git a/guide/po/tutorial_performance-tuning.md/tutorial_performance-tuning.md.pot b/_translations/guide/pot/tutorial_performance-tuning.md.pot similarity index 68% rename from guide/po/tutorial_performance-tuning.md/tutorial_performance-tuning.md.pot rename to _translations/guide/pot/tutorial_performance-tuning.md.pot index 5e27f538..9902e57e 100644 --- a/guide/po/tutorial_performance-tuning.md/tutorial_performance-tuning.md.pot +++ b/_translations/guide/pot/tutorial_performance-tuning.md.pot @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2025-09-04 11:19+0500\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,13 +17,13 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" #. type: Title # -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md #, no-wrap msgid "Performance tuning" msgstr "" #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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 " @@ -33,58 +33,123 @@ msgid "" msgstr "" #. type: Title ## -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md #, no-wrap msgid "Optimizing your PHP Environment " msgstr "" #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md msgid "" "A well-configured PHP environment is important. To get maximum performance:" msgstr "" #. type: Bullet: '- ' -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md msgid "" "Use the latest stable PHP version. Major releases of PHP may bring " "significant performance improvements." msgstr "" #. type: Bullet: '- ' -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md msgid "" "Enable bytecode caching with [Opcache](https://secure.php.net/opcache). " -"Bytecode caching avoids the time spent in parsing and including PHP scripts " +"Bytecode caching avoids the time spent on parsing and including PHP scripts " "for every incoming request." msgstr "" #. type: Bullet: '- ' -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md msgid "" "[Tune `realpath()` cache](https://github.com/samdark/realpath_cache_tuner)." msgstr "" #. type: Bullet: '- ' -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md msgid "" "Make sure [XDebug](https://xdebug.org/) isn't installed in the production " "environment." msgstr "" #. type: Bullet: '- ' -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md msgid "Try [PHP 7 preloading](https://wiki.php.net/rfc/preload)." msgstr "" #. type: Title ## -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md +#, no-wrap +msgid "Optimizing your code " +msgstr "" + +#. type: Plain text +#: ../../guide/en/tutorial/performance-tuning.md +msgid "" +"Beyond environment configuration, there are code-level optimizations that " +"can improve your application's performance:" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/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: '- ' +#: ../../guide/en/tutorial/performance-tuning.md +msgid "" +"[Speeding up array_merge()](https://www.exakat.io/speeding-up-array_merge/)" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/tutorial/performance-tuning.md +msgid "" +"[Move that foreach() inside the method](https://www.exakat.io/move-that-" +"foreach-inside-the-method/)" +msgstr "" + +#. type: Bullet: '- ' +#: ../../guide/en/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: '- ' +#: ../../guide/en/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 +#: ../../guide/en/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 ## +#: ../../guide/en/tutorial/performance-tuning.md #, no-wrap msgid "Using caching techniques " msgstr "" #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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 " @@ -95,13 +160,13 @@ msgid "" msgstr "" #. type: Title ## -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md #, no-wrap msgid "Optimizing session storage " msgstr "" #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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" @@ -112,7 +177,7 @@ msgid "" msgstr "" #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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-" @@ -122,7 +187,7 @@ msgid "" msgstr "" #. type: Fenced code block (php) -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md #, no-wrap msgid "" "\\Yiisoft\\Session\\SessionInterface::class => [\n" @@ -132,13 +197,13 @@ msgid "" msgstr "" #. type: Title ## -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md #, no-wrap msgid "Optimizing databases " msgstr "" #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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]" @@ -149,7 +214,7 @@ msgid "" msgstr "" #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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 " @@ -159,14 +224,14 @@ msgid "" msgstr "" #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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 -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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 " @@ -174,26 +239,26 @@ msgid "" msgstr "" #. type: Title ## -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md #, no-wrap msgid "Optimizing composer autoloader " msgstr "" #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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 -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md #, no-wrap msgid "composer dumpautoload -o\n" msgstr "" #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md msgid "" "Additionally, you may consider using [authoritative class maps](https://" "getcomposer.org/doc/articles/autoloader-optimization.md#optimization-level-2-" @@ -204,13 +269,13 @@ msgid "" msgstr "" #. type: Title ## -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md #, no-wrap msgid "Processing data offline " msgstr "" #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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 " @@ -218,12 +283,12 @@ msgid "" msgstr "" #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md msgid "There are two methods to process data offline: pull and push." msgstr "" #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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 " @@ -236,7 +301,7 @@ msgid "" msgstr "" #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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 " @@ -245,13 +310,13 @@ msgid "" msgstr "" #. type: Title ## -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md #, no-wrap msgid "Using preloading" msgstr "" #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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://" @@ -260,7 +325,7 @@ msgid "" msgstr "" #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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 " @@ -268,7 +333,7 @@ msgid "" msgstr "" #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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 " @@ -276,53 +341,53 @@ msgid "" msgstr "" #. type: Title ### -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md #, no-wrap msgid "Preloading benchmarks" msgstr "" #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md msgid "" "The application template benchmark includes configuring classes to injected " "dependencies in the bootstrap script." msgstr "" #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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) -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md #, no-wrap msgid "ab -n 1000 -c 10 -t 10\n" msgstr "" #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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 " +"[Composer](https://getcomposer.org) was used, and development dependencies " "weren't used:" msgstr "" #. type: Fenced code block (shell) -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md #, no-wrap msgid "composer install --optimize-autoloader --no-dev\n" msgstr "" #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md msgid "" "With preloading enabled, the entire composer class map (825 files) was used:" msgstr "" #. type: Fenced code block (php) -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md #, no-wrap msgid "" "$files = require 'vendor/composer/autoload_classmap.php';\n" @@ -333,13 +398,13 @@ msgid "" msgstr "" #. type: Title #### -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md #, no-wrap msgid "Test results" msgstr "" #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md #, no-wrap msgid "" "| Benchmark | Preloaded files | Opcache memory used | Per request memory used | Time per request | Requests per second |\n" @@ -349,7 +414,7 @@ msgid "" msgstr "" #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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 " @@ -358,13 +423,13 @@ msgid "" msgstr "" #. type: Title ## -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md #, no-wrap msgid "Performance profiling " msgstr "" #. type: Plain text -#: en/tutorial/performance-tuning.md +#: ../../guide/en/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 " @@ -372,23 +437,23 @@ msgid "" msgstr "" #. type: Bullet: '- ' -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md msgid "" "[Yii debug toolbar and debugger](https://github.com/yiisoft/yii2-debug/blob/" "master/docs/guide/README.md)" msgstr "" #. type: Bullet: '- ' -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md msgid "[Blackfire](https://blackfire.io/)" msgstr "" #. type: Bullet: '- ' -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md msgid "[XHProf](https://secure.php.net/manual/en/book.xhprof.php)" msgstr "" #. type: Bullet: '- ' -#: en/tutorial/performance-tuning.md +#: ../../guide/en/tutorial/performance-tuning.md msgid "[XDebug profiler](https://xdebug.org/docs/profiler)" msgstr "" diff --git a/guide/po/tutorial_using-with-event-loop.md/tutorial_using-with-event-loop.md.pot b/_translations/guide/pot/tutorial_using-with-event-loop.md.pot similarity index 77% rename from guide/po/tutorial_using-with-event-loop.md/tutorial_using-with-event-loop.md.pot rename to _translations/guide/pot/tutorial_using-with-event-loop.md.pot index 2b6bddc8..c15aac9e 100644 --- a/guide/po/tutorial_using-with-event-loop.md/tutorial_using-with-event-loop.md.pot +++ b/_translations/guide/pot/tutorial_using-with-event-loop.md.pot @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2025-09-04 11:19+0500\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,13 +17,13 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" #. type: Title # -#: en/tutorial/using-with-event-loop.md +#: ../../guide/en/tutorial/using-with-event-loop.md #, no-wrap msgid "Using Yii with event loop" msgstr "" #. type: Plain text -#: en/tutorial/using-with-event-loop.md +#: ../../guide/en/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" @@ -34,7 +34,7 @@ msgid "" msgstr "" #. type: Plain text -#: en/tutorial/using-with-event-loop.md +#: ../../guide/en/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 " @@ -42,7 +42,7 @@ msgid "" msgstr "" #. type: Plain text -#: en/tutorial/using-with-event-loop.md +#: ../../guide/en/tutorial/using-with-event-loop.md msgid "" "There are multiple tools that could be used to achieve it. Notably, " "[FrankenPHP](https://frankenphp.dev/), [RoadRunner](https://roadrunner.dev/) " @@ -50,18 +50,18 @@ msgid "" msgstr "" #. type: Title ## -#: en/tutorial/using-with-event-loop.md +#: ../../guide/en/tutorial/using-with-event-loop.md #, no-wrap msgid "Event loop implications" msgstr "" #. type: Plain text -#: en/tutorial/using-with-event-loop.md +#: ../../guide/en/tutorial/using-with-event-loop.md msgid "Event loop worker basically looks like the following:" msgstr "" #. type: Fenced code block (php) -#: en/tutorial/using-with-event-loop.md +#: ../../guide/en/tutorial/using-with-event-loop.md #, no-wrap msgid "" "initializeContext();\n" @@ -72,25 +72,25 @@ msgid "" msgstr "" #. type: Plain text -#: en/tutorial/using-with-event-loop.md +#: ../../guide/en/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 -#: en/tutorial/using-with-event-loop.md +#: ../../guide/en/tutorial/using-with-event-loop.md msgid "That means that there's more to consider when developing applications." msgstr "" #. type: Title ### -#: en/tutorial/using-with-event-loop.md +#: ../../guide/en/tutorial/using-with-event-loop.md #, no-wrap msgid "Processing is blocking" msgstr "" #. type: Plain text -#: en/tutorial/using-with-event-loop.md +#: ../../guide/en/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 " @@ -98,13 +98,13 @@ msgid "" msgstr "" #. type: Title ### -#: en/tutorial/using-with-event-loop.md +#: ../../guide/en/tutorial/using-with-event-loop.md #, no-wrap msgid "Services and state" msgstr "" #. type: Plain text -#: en/tutorial/using-with-event-loop.md +#: ../../guide/en/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 " @@ -113,16 +113,16 @@ msgid "" msgstr "" #. type: Plain text -#: en/tutorial/using-with-event-loop.md +#: ../../guide/en/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 services state at the end of the request processing. " -"In this case, a state resetter will help you:" +"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) -#: en/tutorial/using-with-event-loop.md +#: ../../guide/en/tutorial/using-with-event-loop.md #, no-wrap msgid "" "initializeContext();\n" @@ -135,17 +135,17 @@ msgid "" msgstr "" #. type: Title ## -#: en/tutorial/using-with-event-loop.md +#: ../../guide/en/tutorial/using-with-event-loop.md #, no-wrap msgid "Integrations" msgstr "" #. type: Bullet: '- ' -#: en/tutorial/using-with-event-loop.md +#: ../../guide/en/tutorial/using-with-event-loop.md msgid "[RoadRunner](using-yii-with-roadrunner.md)" msgstr "" #. type: Bullet: '- ' -#: en/tutorial/using-with-event-loop.md +#: ../../guide/en/tutorial/using-with-event-loop.md msgid "[Swoole](using-yii-with-swoole.md)" msgstr "" diff --git a/guide/po/tutorial_using-yii-with-roadrunner.md/tutorial_using-yii-with-roadrunner.md.pot b/_translations/guide/pot/tutorial_using-yii-with-roadrunner.md.pot similarity index 100% rename from guide/po/tutorial_using-yii-with-roadrunner.md/tutorial_using-yii-with-roadrunner.md.pot rename to _translations/guide/pot/tutorial_using-yii-with-roadrunner.md.pot diff --git a/guide/po/tutorial_using-yii-with-swoole.md/tutorial_using-yii-with-swoole.md.pot b/_translations/guide/pot/tutorial_using-yii-with-swoole.md.pot similarity index 82% rename from guide/po/tutorial_using-yii-with-swoole.md/tutorial_using-yii-with-swoole.md.pot rename to _translations/guide/pot/tutorial_using-yii-with-swoole.md.pot index 1b2a4269..98d9b667 100644 --- a/guide/po/tutorial_using-yii-with-swoole.md/tutorial_using-yii-with-swoole.md.pot +++ b/_translations/guide/pot/tutorial_using-yii-with-swoole.md.pot @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2025-09-04 11:19+0500\n" +"POT-Creation-Date: 2025-09-11 10:15+0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,33 +17,33 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: en/tutorial/using-yii-with-roadrunner.md -#: en/tutorial/using-yii-with-swoole.md +#: ../../guide/en/tutorial/using-yii-with-roadrunner.md +#: ../../guide/en/tutorial/using-yii-with-swoole.md #, no-wrap msgid "Installation" msgstr "" #. type: Title ## -#: en/tutorial/using-yii-with-roadrunner.md -#: en/tutorial/using-yii-with-swoole.md +#: ../../guide/en/tutorial/using-yii-with-roadrunner.md +#: ../../guide/en/tutorial/using-yii-with-swoole.md #, no-wrap msgid "Starting a server" msgstr "" #. type: Plain text -#: en/tutorial/using-yii-with-roadrunner.md -#: en/tutorial/using-yii-with-swoole.md +#: ../../guide/en/tutorial/using-yii-with-roadrunner.md +#: ../../guide/en/tutorial/using-yii-with-swoole.md msgid "To start a server, execute the following command:" msgstr "" #. type: Title # -#: en/tutorial/using-yii-with-swoole.md +#: ../../guide/en/tutorial/using-yii-with-swoole.md #, no-wrap msgid "Using Yii with Swoole" msgstr "" #. type: Plain text -#: en/tutorial/using-yii-with-swoole.md +#: ../../guide/en/tutorial/using-yii-with-swoole.md #, no-wrap msgid "" "[Swoole](https://www.swoole.co.uk/) is a PHP network framework distributed as a PECL extension. It allows you built-in async,\n" @@ -51,51 +51,51 @@ msgid "" msgstr "" #. type: Plain text -#: en/tutorial/using-yii-with-swoole.md +#: ../../guide/en/tutorial/using-yii-with-swoole.md msgid "" "In the context of Yii, it allows running request handlers 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 to re-initialize a " +"[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 -#: en/tutorial/using-yii-with-swoole.md +#: ../../guide/en/tutorial/using-yii-with-swoole.md msgid "Swoole works on Linux and macOS and can be installed via pecl:" msgstr "" #. type: Fenced code block (bash) -#: en/tutorial/using-yii-with-swoole.md +#: ../../guide/en/tutorial/using-yii-with-swoole.md #, no-wrap msgid "pecl install swoole\n" msgstr "" #. type: Title ## -#: en/tutorial/using-yii-with-swoole.md +#: ../../guide/en/tutorial/using-yii-with-swoole.md #, no-wrap msgid "Putting up a server" msgstr "" #. type: Plain text -#: en/tutorial/using-yii-with-swoole.md +#: ../../guide/en/tutorial/using-yii-with-swoole.md msgid "" "Since Swoole doesn't have built-in PSR-7 support, you need a package fixing " "so:" msgstr "" #. type: Fenced code block (php) -#: en/tutorial/using-yii-with-swoole.md +#: ../../guide/en/tutorial/using-yii-with-swoole.md #, no-wrap msgid "composer require ilexn/swoole-convent-psr7\n" msgstr "" #. type: Plain text -#: en/tutorial/using-yii-with-swoole.md +#: ../../guide/en/tutorial/using-yii-with-swoole.md msgid "Create an entry script, `server.php`:" msgstr "" #. type: Fenced code block (php) -#: en/tutorial/using-yii-with-swoole.md +#: ../../guide/en/tutorial/using-yii-with-swoole.md #, no-wrap msgid "" "\n" "Language-Team: LANGUAGE \n" @@ -17,34 +17,48 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" #. type: Title ## -#: en/concept/configuration.md en/tutorial/using-yii-with-roadrunner.md -#: en/views/view-injections.md +#: ../../guide/en/concept/configuration.md +#: ../../guide/en/tutorial/using-yii-with-roadrunner.md +#: ../../guide/en/views/view-injections.md #, no-wrap msgid "Configuration" msgstr "" #. type: Title # -#: en/views/view-injections.md +#: ../../guide/en/views/view-injections.md #, no-wrap msgid "View injections" msgstr "" #. type: Plain text -#: en/views/view-injections.md +#: ../../guide/en/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. Implementing this " -"interface allows developers to manage the data that will be available across " -"various views, ensuring flexibility and reusability of code." +"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 -#: en/views/view-injections.md +#: ../../guide/en/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) +#: ../../guide/en/views/view-injections.md +#, no-wrap +msgid "composer require yiisoft/yii-view-renderer\n" +msgstr "" + +#. type: Plain text +#: ../../guide/en/views/view-injections.md msgid "In config `params.php`:" msgstr "" #. type: Fenced code block (php) -#: en/views/view-injections.md +#: ../../guide/en/views/view-injections.md #, no-wrap msgid "" "...\n" @@ -58,13 +72,13 @@ msgid "" msgstr "" #. type: Title ## -#: en/views/view-injections.md +#: ../../guide/en/views/view-injections.md #, no-wrap msgid "New injections" msgstr "" #. type: Plain text -#: en/views/view-injections.md +#: ../../guide/en/views/view-injections.md msgid "" "Start by defining a class that will implement the " "`Yiisoft\\Yii\\View\\Renderer\\CommonParametersInjectionInterface`. This " @@ -73,7 +87,7 @@ msgid "" msgstr "" #. type: Fenced code block (php) -#: en/views/view-injections.md +#: ../../guide/en/views/view-injections.md #, no-wrap msgid "" "class MyCustomParametersInjection implements Yiisoft\\Yii\\View\\Renderer\\CommonParametersInjectionInterface\n" @@ -97,12 +111,12 @@ msgid "" msgstr "" #. type: Plain text -#: en/views/view-injections.md +#: ../../guide/en/views/view-injections.md msgid "Add your new Injection to `params.php`:" msgstr "" #. type: Fenced code block (php) -#: en/views/view-injections.md +#: ../../guide/en/views/view-injections.md #, no-wrap msgid "" "'yiisoft/yii-view' => [\n" @@ -114,13 +128,13 @@ msgid "" msgstr "" #. type: Title ## -#: en/views/view-injections.md +#: ../../guide/en/views/view-injections.md #, no-wrap msgid "Using Separate Injections for Different Layouts" msgstr "" #. type: Plain text -#: en/views/view-injections.md +#: ../../guide/en/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 " @@ -129,12 +143,12 @@ msgid "" msgstr "" #. type: Plain text -#: en/views/view-injections.md +#: ../../guide/en/views/view-injections.md msgid "Create your custom ViewInjection for a specific layout:" msgstr "" #. type: Fenced code block (php) -#: en/views/view-injections.md +#: ../../guide/en/views/view-injections.md #, no-wrap msgid "" "readonly final class CartViewInjection implements CommonParametersInjectionInterface\n" @@ -153,14 +167,14 @@ msgid "" msgstr "" #. type: Plain text -#: en/views/view-injections.md +#: ../../guide/en/views/view-injections.md msgid "" "Add your new injection to `params.php` under specific layout name. In the " "following example, it is `@layout/cart`:" msgstr "" #. type: Fenced code block (php) -#: en/views/view-injections.md +#: ../../guide/en/views/view-injections.md #, no-wrap msgid "" "'yiisoft/yii-view' => [\n" @@ -180,3 +194,12 @@ msgid "" " ],\n" " ],\n" msgstr "" + +#. type: Plain text +#: ../../guide/en/views/view-injections.md +#, no-wrap +msgid "" +"> [!NOTE]\n" +"> [← Template engines](template-engines.md) |\n" +"> [Scripts, styles and metatags →](script-style-meta.md)\n" +msgstr "" diff --git a/guide/es/README.md b/guide/es/README.md index f4eba50c..18a19dfc 100644 --- a/guide/es/README.md +++ b/guide/es/README.md @@ -1,6 +1,7 @@ # La Guía Definitiva de Yii 3.0 -Esta guía se publica bajo los [Términos de documentación de Yii](https://www.yiiframework.com/doc/terms/). +Esta guía se publica bajo los [Términos de documentación de +Yii](https://www.yiiframework.com/license#docs)). Introducción ------------ @@ -13,7 +14,7 @@ Primeros Pasos --------------- * [Qué Necesitas Saber](start/prerequisites.md) -* [Instalación de Yii](start/installation.md) +* [Creating a project](start/creating-project.md) + * [Ejecutando Aplicaciones](start/workflow.md) * [Hola Mundo](start/hello.md) * [Trabajar con Formularios](start/forms.md) @@ -25,7 +26,8 @@ Primeros Pasos Estructura De Una Aplicación --------------------- -* [Información General de Estructura de Una Aplicación](structure/overview.md) +* [Información General de Estructura de Una + Aplicación](structure/overview.md) * [Scripts de Entrada](structure/entry-script.md) * [Applicación](structure/application.md) * [Componentes de Servicios](structure/service.md) @@ -42,18 +44,16 @@ Conceptos Clave * [Configuración](concept/configuration.md) * [Alias](concept/aliases.md) * [Eventos](concept/events.md) +* [Immutability](concept/immutability.md) + Gestión de las Peticiones ----------------- -* [Información General de Gestión de las Peticiones](runtime/overview.md) -* [Bootstrapping](runtime/bootstrapping.md) * [Enrutamiento y Creación de las URL](runtime/routing.md) * [Peticiones (Requests)](runtime/request.md) * [Respuestas (Responses)](runtime/response.md) * [Sesiones (Sessions)](runtime/sessions.md) * [Cookies](runtime/cookies.md) -* [Mensajes Flash](runtime/flash-messages.md) * [Manejo de Errores](runtime/handling-errors.md) * [Registros (logs)](runtime/logging.md) @@ -61,28 +61,32 @@ Vistas ----- * [Vistas](views/view.md) -* [Widgets](views/widget.md) -* [Assets](views/asset.md) -* [Trabajando con Scripts de Cliente](views/client-scripts.md) -* [Temas](views/theming.md) * [Motores de Plantillas](views/template-engines.md) - +* [View injections](views/view-injections.md) + +* [Scripts, styles and metatags](views/script-style-meta.md) +* [Assets](views/asset.md) +* [Widgets](views/widget.md) Trabajar con Bases de Datos ---------------------- -* [Objeto de Acceso a Datos](db-dao.md): Conexión a una base de datos, consultas básicas, transacciones y manipulación de esquemas -* [Constructor de Consultas](db-query-builder.md): Consulta de la base de datos utilizando una capa simple de abstracción -* [Active Record](db-active-record.md): ORM Active Record, recuperación y manipulación de registros y definición de relaciones -* [Migraciones](db-migrations.md): Control de versiones de bases de datos en el entorno de desarrollo en equipo +* [Objeto de Acceso a Datos](db-dao.md): Conexión a una base de datos, + consultas básicas, transacciones y manipulación de esquemas +* [Constructor de Consultas](db-query-builder.md): Consulta de la base de + datos utilizando una capa simple de abstracción +* [Active Record](db-active-record.md): ORM Active Record, recuperación y + manipulación de registros y definición de relaciones +* [Migraciones](db-migrations.md) Obtener Datos de los Usuarios ----------------------- * [Crear Formularios](input/forms.md) -* [Validar Datos](input/validation.md) +* [Validar + Datos](https://github.com/yiisoft/validator/blob/master/docs/guide/en/README.md) * [Carga de Archivos](input/file-upload.md) -* [Obtener Datos de Formularios Tabulados (Tabular Input)](input/tabular-input.md) +* [Obtener Datos de Formularios Tabulados (Tabular + Input)](input/tabular-input.md) Visualizar Datos @@ -94,12 +98,12 @@ Visualizar Datos * [Proveedores de Datos](output/data-providers.md) * [Widgets de Datos](output/data-widgets.md) -Seguridad- +Seguridad -------- * [Información General de Seguridad](security/overview.md) * [Autenticación](security/authentication.md) -* [Autorización](security/authorization.md)- +* [Autorización](security/authorization.md) * [Trabajar con Contraseñas](security/passwords.md) * [Criptografía](security/cryptography.md) * [Buenas Prácticas](security/best-practices.md) @@ -115,8 +119,8 @@ Caché * [Caché HTTP](caching/http.md) -Servicios Web RESTful --------------------- +REST APIs - +----------- * [Inicio Rápido](rest/quick-start.md) * [Recursos](rest/resources.md) @@ -130,9 +134,9 @@ Servicios Web RESTful Herramientas de Desarrollo ----------------- -* [Depurador y Barra de Herramientas de Depuración](https://www.yiiframework.com/extension/yiisoft/yii2-debug/doc/guide) -* [Generación de Código con Gii](https://www.yiiframework.com/extension/yiisoft/yii2-gii/doc/guide) -* [Generación de Documentación de API](https://www.yiiframework.com/extension/yiisoft/yii2-apidoc) +* Depurador y Barra de Herramientas de Depuración +* Generación de Código con Gii +* Generación de Documentación de API Pruebas (Testing) @@ -157,6 +161,7 @@ Temas Especiales * [Ajustes de Rendimiento](tutorial/performance-tuning.md) * [Utilizar Yii con Bucle de Eventos](tutorial/using-with-event-loop.md) * [Utilizar Yii con RoadRunner](tutorial/using-yii-with-roadrunner.md) +* [Using Yii with Swoole](tutorial/using-yii-with-swoole.md) + Widgets ------- @@ -168,13 +173,22 @@ Widgets * [Menu](https://www.yiiframework.com/doc-2.0/yii-widgets-menu.html) * [LinkPager](https://www.yiiframework.com/doc-2.0/yii-widgets-linkpager.html) * [LinkSorter](https://www.yiiframework.com/doc-2.0/yii-widgets-linksorter.html) -* [Bootstrap Widgets](https://www.yiiframework.com/extension/yiisoft/yii2-bootstrap/doc/guide) +* [Bootstrap + widgets](https://www.yiiframework.com/extension/yiisoft/yii2-bootstrap/doc/guide) Clases Auxiliares ------- -* [Información General de Clases Auxiliares](helper-overview.md) -* [ArrayHelper](helper/array.md) -* [Html](helper-html.md) -* [Url](helper-url.md) +* [Arrays](https://github.com/yiisoft/arrays/) +* [Files](https://github.com/yiisoft/files/) +* [Html](https://github.com/yiisoft/html/) +* [Json](https://github.com/yiisoft/json) +* [Network utilities](https://github.com/yiisoft/network-utilities/) +* [VarDumper](https://github.com/yiisoft/var-dumper) +* [Strings](https://github.com/yiisoft/strings) + +Extras + +------ + +* [Glossary](glossary.md) diff --git a/guide/es/concept/aliases.md b/guide/es/concept/aliases.md index 9ba1664e..309a62a3 100644 --- a/guide/es/concept/aliases.md +++ b/guide/es/concept/aliases.md @@ -1,10 +1,15 @@ # Alias -Los alias son utilizados para representar rutas o URLs de manera que no tengas que escribir explícitamente rutas absolutas o URLs en tu -proyecto. Un alias debe comenzar con el signo `@` para ser diferenciado de una ruta normal de archivo y de URLs. Los alias definidos +Los alias son utilizados para representar rutas o URLs de manera que no +tengas que escribir explícitamente rutas absolutas o URLs en tu +proyecto. Un alias debe comenzar con el signo `@` para ser diferenciado de +una ruta normal de archivo y de URLs. Los alias definidos sin el `@` del principio, serán prefijados con el signo `@`. -Yii incluye varios alias predefinidos en `config/params.php`. Por ejemplo, el alias `@src` representa la ruta de instalación de la aplicación en la carpeta `src`; `@web` representa la URL base para la aplicación Web ejecutándose. +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. ## Definir Alias @@ -27,18 +32,23 @@ return [ ]; ``` -> Nota: Una ruta de archivo o URL en alias *no* se refiere necesariamente a un archivo o recurso existente. +> [!Nota] +> Una ruta de archivo o URL en alias *no* se refiere necesariamente a un archivo o recurso existente. -Dado un alias, puedes derivar un nuevo alias anexando una barra diagonal `/` seguida por uno o varios segmentos de la ruta. -Por ejemplo, `@foo` es un alias de raíz, mientras que `@foo/bar/file.php` es un alias derivado. +Dado un alias, puedes derivar un nuevo alias anexando una barra diagonal `/` +seguida por uno o varios segmentos de la ruta. +Por ejemplo, `@foo` es un alias de raíz, mientras que `@foo/bar/file.php` es +un alias derivado. -Puedes definir un alias usando otro alias (ya sea un alias de raíz o derivado): +Puedes definir un alias usando otro alias (ya sea un alias de raíz o +derivado): ```php '@foobar' => '@foo/bar', ``` -El parámetro `aliases` inicializa el servicio `Aliases` desde el [paquete `yiisoft/aliases`](https://github.com/yiisoft/aliases). +El parámetro `aliases` inicializa el servicio `Aliases` desde el [paquete +`yiisoft/aliases`](https://github.com/yiisoft/aliases). Puedes agregar alias adicionales en tiempo de ejecución usando el servicio: ```php @@ -50,9 +60,32 @@ public function actionIndex(Aliases $aliases) } ``` +## 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']) + ), +]; +``` + ## Resolución de Alias -Puedes utilizar el servicio `Aliases` para resolver un alias o un alias derivado a la ruta de archivo o URL que representa: +Puedes utilizar el servicio `Aliases` para resolver un alias o un alias +derivado a la ruta de archivo o URL que representa: ```php use \Yiisoft\Aliases\Aliases; @@ -60,21 +93,23 @@ use \Yiisoft\Aliases\Aliases; public function actionIndex(Aliases $aliases) { $foo = $aliases->get('@foo'); // /path/to/foo - $bar = $aliases->get('@bar'); // http://www.example.com + $bar = $aliases->get('@bar'); // https://www.example.com $file = $aliases->get('@foo/bar/file.php'); // /path/to/foo/bar/file.php } ``` -La ruta de archivo/URL representado por un alias derivado está determinado por la sustitución de la parte de su alias raíz con su correspondiente ruta/Url en el alias derivado. +La ruta de archivo/URL representado por un alias derivado está determinado +por la sustitución de la parte de su alias raíz con su correspondiente +ruta/Url en el alias derivado. -> Nota: El método `get()` no comprueba si la ruta/URL resultante hacer referencia a un archivo o recurso existente. +> [!NOTE] +> El método `get()` no comprueba si la ruta/URL resultante hacer referencia a un archivo o 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: Un alias de raíz puede contener carácteres `/`. -El método `get()` es lo suficientemente inteligente para saber qué parte de un alias es un alias de raíz y por lo tanto determinar correctamente la correspondiente ruta de archivo o URL. Por ejemplo: +El método `get()` es lo suficientemente inteligente para saber qué parte de +un alias es un alias de raíz y por lo tanto determinar correctamente la +correspondiente ruta de archivo o URL. Por ejemplo: ```php use \Yiisoft\Aliases\Aliases; @@ -89,26 +124,27 @@ public function actionIndex(Aliases $aliases) } ``` -Si `@foo/bar` no está definido como un alias de raíz, la última declaración mostraría `/path/to/foo/bar/file.php`. +Si `@foo/bar` no está definido como un alias de raíz, la última declaración +mostraría `/path/to/foo/bar/file.php`. ## Alias Predefinidos -Yii predefine un conjunto de alias para aliviar la necesidad de hacer referencia a rutas de archivo o URLs que son utilizadas regularmente: +[Yii application](https://github.com/yiisoft/app) predefines a set of +aliases to reference commonly used file paths and URLs: - `@root`, la ruta base de la aplicación que se está ejecutando actualmente. +- `@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`, la carpeta `vendor` de Composer. -- `@public`, el directorio raíz Web de la aplicación Web se está ejecutando actualmente. -- `@runtime`, la ruta de ejecución de la aplicación en ejecución. Por defecto`@root/runtime`. -- `@web`, la URL base de la aplicación web se ejecuta actualmente. - -## Alias en extensiones - -Un alias se define automáticamente por cada [extensión](structure-extensions.md) que ha sido instalada a través de Composer. -El alias es nombrado tras el `namespace` de raíz de la extensión instalada tal y como está declarada en su archivo `composer.json`, -y representa el directorio raíz de la extensión. Por ejemplo, si instalas la extensión `yiisoft/yii2-jui`, tendrás -automáticamente definido el alias `@yii/jui` durante la etapa [bootstrapping](runtime-bootstrapping.md) de la aplicación: - -```php -Yii::setAlias('@yii/jui', 'VendorPath/yiisoft/yii2-jui'); -``` \ No newline at end of file +- `@public` - application's publicly accessible directory that with + `index.php`. +- `@runtime`, la ruta de ejecución de la aplicación en ejecución. Por + defecto`@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/guide/es/concept/autoloading.md b/guide/es/concept/autoloading.md index ee7ad62d..0bfb9735 100644 --- a/guide/es/concept/autoloading.md +++ b/guide/es/concept/autoloading.md @@ -1,12 +1,18 @@ # Autocarga de Clases (Autoloading) -Dado que Yii utiliza [Composer](https://getcomposer.org) para administar paquetes, las clases de esos paquetes son automaticamente -cargados sin la necesidad de ser incluidos utilizando `require` para cada uno de ellos. Cuando los paquetes son instalados, -un [autocargador compatible con PSR-0](https://www.php-fig.org/psr/psr-4/) es generado. Para usarlo, -se debe invocar el autocargador `/vendor/autoload.php` con `require_once` en el script de entrada `index.php`. +Dado que Yii utiliza [Composer](https://getcomposer.org) para administar +paquetes, las clases de esos paquetes son automaticamente +cargados sin la necesidad de ser incluidos utilizando `require` para cada +uno de ellos. Cuando los paquetes son instalados, +un [autocargador compatible con PSR-0](https://www.php-fig.org/psr/psr-4/) +es generado. Para usarlo, +se debe invocar el autocargador `/vendor/autoload.php` con `require_once` en +el script de entrada `index.php`. -El autocargador no se utiliza solamente para los paquetes que se instalan, tambien se utiliza para su aplicación que también es un paquete. -Para cargar clases desde cierto espacio de nombres (namespaces), lo siguiente debe ser añadido a `composer.json`: +El autocargador no se utiliza solamente para los paquetes que se instalan, +tambien se utiliza para su aplicación que también es un paquete. +Para cargar clases desde cierto espacio de nombres (namespaces), lo +siguiente debe ser añadido a `composer.json`: ```json { @@ -18,11 +24,18 @@ Para cargar clases desde cierto espacio de nombres (namespaces), lo siguiente de } ``` -Donde `App\\` es el espacio de nombre raiz (namespace), y `src/` es la carpeta donde se ubican las clases. Se pueden añadir distintos namespaces y carpetas si es necesario. -Una vez listo, ejecuta `composer dump-autoload` y las clases de los espacios de nombres serán cargados automaticamente. +Donde `App\\` es el espacio de nombre raiz (namespace), y `src/` es la +carpeta donde se ubican las clases. Se pueden añadir distintos namespaces y +carpetas si es necesario. +Una vez listo, ejecuta `composer dump-autoload` y las clases de los espacios +de nombres serán cargados 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`. ## Referencias - [PSR-4: Autoloader](https://www.php-fig.org/psr/psr-4/). -- [Guía de Composer sobre autocarga](https://getcomposer.org/doc/01-basic-usage.md#autoloading). +- [Guía de Composer sobre + autocarga](https://getcomposer.org/doc/01-basic-usage.md#autoloading). diff --git a/guide/es/concept/configuration.md b/guide/es/concept/configuration.md deleted file mode 100644 index 5d8d0c7e..00000000 --- a/guide/es/concept/configuration.md +++ /dev/null @@ -1,12 +0,0 @@ -# Configuración - -Las aplicaciones de Yii 3 son configuradas con un contenedor de Injección de Dependencias (Dependency Injection container). Hay múltiples formas de hacer eso. -Primero nos enfocaremos en los conceptos usados en el proyecto plantilla, y luego daremos formas adicionales para configurar el framework. - -## Composer Config Plugin - -En el proyecto plantilla se utiliza [hiqdev/composer-config-plugin](https://github.com/hiqdev/composer-config-plugin). -Lo que hace el plugin es recolectar todas las configuraciones definidas en la sección `config-plugin` de todas las dependencias en `composer.json`, -y luego las une en una sola. - -## Contenedor de Injección de Dependencias \ No newline at end of file diff --git a/guide/es/concept/di-container.md b/guide/es/concept/di-container.md deleted file mode 100644 index b0831f24..00000000 --- a/guide/es/concept/di-container.md +++ /dev/null @@ -1,211 +0,0 @@ -# Dependency injection and container - -## Depdendency injection - -There are two ways of re-using things in OOP: inheritance and composition. - -Inheritance is simple: - -```php -class Cache -{ - public function getCachedValue($key) - { - // .. - } -} - -class CachedWidget extends Cache -{ - public function render() - { - $output = parent::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 it is composition: - -```php -interface CacheInterface -{ - public function getCachedValue($key); -} - -class Cache implements CacheInterface -{ - public function getCachedValue($key) - { - // .. - } -} - -class CachedWidget -{ - private $cache; - - public function __construct(CacheInterface $cache) - { - $this->cache = $cache; - } - - public function render() - { - $output = $this->cache->getCachedValue('cachedWidget'); - if ($output !== null) { - return $output; - } - // ... - } -} -``` - -In the above we've avoided unnecessary inheritance and used interface to reduce coupling. You can replace cache -implementation without changing `CachedWidget` so it is becoming more stable. - -The process of getting an instance of `CacheInterface` into `CachedWidget` is called dependency injection. -There are multiple 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. - - -## DI container - -Injecting basic dependencies is simple and easy. You're choosing a place where you don't care about dependencies, -which is usually 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 aren't many dependencies overall and when there are no nested dependencies. When there are -many and each dependency has dependencies itself, instantiating the whole hierarchy becomes tedious process, which -requires lots of code and may lead to hard to debug mistakes. - -Additionally, lots of dependencies, such as certain third party API wrapper, are the same for any class using it. -So it makes sense to: - -- Define how to instantiate such API wrapper once. -- Instantiate it 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 their dependent objects. [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. - -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. - -### Configuring container - -Because dependencies are needed when new objects are being created, their registration should be done -as early as possible. If you are application developer it could be done right in the application configuration, -`config/web.php`. For the following service: - -```php -class MyService implements MyServiceInterface -{ - public function __construct(int $amount) - { - } - - public function setDiscount(int $discount) - { - - } -} -``` - -configuration could be: - -```php -return [ - MyServiceInterface::class => [ - '__class' => MyService::class, - '__construct()' => [42], - 'setDiscount()' => [10], - ], -]; -``` - -Which is equivalent to the following: - -```php -$myService = new MyService(42); -$myService->setDiscount(10); -``` - -There are additional methods of declaring dependencies: - -```php -return [ - // declare class for an interface, resolve dependencies automatically - EngineInterface::class => EngineMarkOne::class, - - // array definition (same as above) - 'full_definition' => [ - '__class' => EngineMarkOne::class, - '__construct()' => [42], - 'propertyName' => 'value', - 'setX()' => [42], - ], - - // closure - 'closure' => function(ContainerInterface $container) { - return new MyClass($container->get('db')); - }, - - // static call - 'static_call' => [MyFactory::class, 'create'], - - // instance of an object - 'object' => new MyClass(), -]; -``` - -### Injecting dependencies - -Directly referencing container in a class is a bad idea since the code becomes non-generic, coupled to container interface -and, what's worse, dependencies are becoming hidden. Because of that, Yii inverts the control by automatically injecting -objects from container in some constructors and methods based on method argument types. - -This is primarily done in constructor and handing method of action handlers: - -```php -class MyController -{ - private $cache; - - public function __construct(\Yiisoft\Cache\Cache $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 action handler is instantiated and called using [yiisoft/injector](https://github.com/yiisoft/injector), it -would check constructor and method argument types, get dependencies of these types from container and pass them as -arguments. That is usually called auto-wiring. It happens for sub-dependencies as well i.e., if dependency is not provided -explicitly, container would check if it has such a dependency first. As a developer it is enough to declare a dependency -you need, and it would be got from container automatically. - - -## References - -- [Inversion of Control Containers and the Dependency Injection pattern by Martin Fowler](https://martinfowler.com/articles/injection.html) diff --git a/guide/es/concept/events.md b/guide/es/concept/events.md index 63a35a32..ec63bc25 100644 --- a/guide/es/concept/events.md +++ b/guide/es/concept/events.md @@ -1,25 +1,34 @@ # Eventos -Los eventos permiten ejecutar código personalizado en ciertos puntos de ejecución sin modificar el código existente. -A un evento se le puede acoplar un código especial llamado gestor (handler), de manera que una vez que el evento se dispare (triggered), +Los eventos permiten ejecutar código personalizado en ciertos puntos de +ejecución sin modificar el código existente. +A un evento se le puede acoplar un código especial llamado gestor (handler), +de manera que una vez que el evento se dispare (triggered), el código se ejecuta de manera automática. -Por ejemplo, cuando un usuario se registra debes enviarle un correo electrónico de bienvenida. Puedes realizar esto directamente en `RegistroService`, -pero luego adicionalmente debes redimensionar la imagen del avatar del usuario, y tendrás que modificar nuevamente `RegistroService`. -En otras palabras, a `RegistroService` se le acoplan el codigo de enviar un correo de bienvenida y redimensionar la imagen del avatar. - +Por ejemplo, cuando un usuario se registra debes enviarle un correo +electrónico de bienvenida. Puedes realizar esto directamente en +`RegistroService`, +pero luego adicionalmente debes redimensionar la imagen del avatar del +usuario, y tendrás que modificar nuevamente `RegistroService`. +En otras palabras, a `RegistroService` se le acoplan el codigo de enviar un +correo de bienvenida y redimensionar la imagen del avatar. + Para evitar todo eso, en vez de decir explicitamente qué hacer despues de un registro, podemos levantar el evento `UsuarioRegistrado` y luego finalizar el proceso de registro. El código que envía el correo y el código que redimensiona la imagen de avatar se adjuntan al evento y por lo tanto serán ejecutados cuando el evento se dispara. Si alguna vez se necesita hacer más cosas en el proceso de registro, puedes añadir distintos gestores de eventos sin necesidad de modificar `RegistroService`. - -Para levantar eventos y acoplar gestores a esos eventos, Yii tiene un servicio especial llamado despachador de eventos. -Se encuentra disponible en el [paquete yiisoft/event-dispatcher](https://github.com/yiisoft/event-dispatcher). + +Para levantar eventos y acoplar gestores a esos eventos, Yii tiene un +servicio especial llamado despachador de eventos. +Se encuentra disponible en el [paquete +yiisoft/event-dispatcher](https://github.com/yiisoft/event-dispatcher). ## Gestores de Eventos -Un gestor de eventos es una [llamada de retorno PHP (PHP callback)](https://secure.php.net/manual/es/language.types.callable.php) que se ejecuta cuando se -lanza el evento al que corresponde. +An event handler is [PHP +callable](https://www.php.net/manual/en/language.types.callable.php) that +gets executed when the event it's attached to is triggered. La firma de un gestor de eventos es: @@ -50,14 +59,18 @@ class WelcomeEmailSender } ``` -El método `attach()` acepta funciones de retorno (callbacks). Dependiendo del argumento de la función de retorno +El método `attach()` acepta funciones de retorno (callbacks). Dependiendo +del argumento de la función de retorno se determina el tipo de evento. ## Orden de Gestores de Eventos -Se puede acoplar uno o más gestores a un único evento. Cuando se lanza un evento, se ejecutarán los gestores adjuntos -en el orden que se hayan añadido al evento. En el caso que un evento implemente `Psr\EventDispatcher\StoppableEventInterface`, -el gestor de eventos puede detener la ejecución del resto de los gestores que le siguen si `isPropagationStopped()` devuelve `true`. +Se puede acoplar uno o más gestores a un único evento. Cuando se lanza un +evento, se ejecutarán los gestores adjuntos +en el orden que se hayan añadido al evento. En el caso que un evento +implemente `Psr\EventDispatcher\StoppableEventInterface`, +el gestor de eventos puede detener la ejecución del resto de los gestores +que le siguen si `isPropagationStopped()` devuelve `true`. En general, lo mejor es no depender del orden de los gestores de eventos. @@ -68,18 +81,17 @@ Los eventos se lanzan de la siguiente forma: ```php use Psr\EventDispatcher\EventDispatcherInterface; -class SignupService +final readonly class SignupService { - private EventDispatcherInterface $eventDispatcher; - - public function __construct(EventDispatcherInterface $eventDispatcher) + public function __construct( + private EventDispatcherInterface $eventDispatcher + ) { - $this->eventDispatcher = $eventDispatcher; } public function signup(SignupForm $form) { - // manejar el registro + // handle signup $event = new UserSignedUp($form); $this->eventDispatcher->dispatch($event); @@ -87,30 +99,26 @@ class SignupService } ``` -Primero, estamos creando un evento entregandole datos que pueden ser útiles para los gestores. Luego, se lanza el evento. +Primero, estamos creando un evento entregandole datos que pueden ser útiles +para los gestores. Luego, se lanza el evento. La clase del evento en sí se podría ver como esto: ```php -final class UserSignedUp +final readonly class UserSignedUp { - private SignupForm $form; - - public function __construct(SignupForm $form) - { - $this->form = $form; - } - - public function getSignupForm(): SignupForm + public function __construct( + public SignupForm $form + ) { - return $this->form; } } ``` ## Jerarquía de Eventos -Los eventos no tienen nombre o wildcard matching por una razón. Los nombres de clases de los eventos y la jerarquía de clases/interfaces +Los eventos no tienen nombre o wildcard matching por una razón. Los nombres +de clases de los eventos y la jerarquía de clases/interfaces y composición se puede utilizar para obtener mayor flexibilidad: ```php @@ -118,22 +126,24 @@ interface DocumentEvent { } -class BeforeDocumentProcessed implements DocumentEvent +final readonly class BeforeDocumentProcessed implements DocumentEvent { } -class AfterDocumentProcessed implements DocumentEvent +final readonly class AfterDocumentProcessed implements DocumentEvent { } ``` -Para que la interface de arriba escuche todos los eventos relacionados con documentos, se puede realizar de la siguiente forma: +Para que la interface de arriba escuche todos los eventos relacionados con +documentos, se puede realizar de la siguiente forma: + ```php $provider->attach(function (DocumentEvent $event) { // log events here }); -``` +``` ## Desacoplar Gestores de Eventos @@ -144,3 +154,7 @@ Para desacoplar un gestor de eventos puedes llamar al método `detach()`: $provider->detach(DocmentEvent::class); ``` +## Configuring application events + +You usually assign event handlers via application config. See +["Configuration"](configuration.md) for details. diff --git a/guide/es/intro/upgrade-from-v2.md b/guide/es/intro/upgrade-from-v2.md deleted file mode 100644 index c51e658d..00000000 --- a/guide/es/intro/upgrade-from-v2.md +++ /dev/null @@ -1,66 +0,0 @@ -# Upgrading from Version 2.0 - -> If you haven't used Yii 2 you can safely skip this section and get directly to "[getting started](../start/installation.md)" -> section. - -While sharing some common ideas and values Yii 3 is conceptually different from Yii 2. There is no easy upgrade -path so first [check maintenance policy and end of life dates for Yii 2](https://www.yiiframework.com/release-cycle) -and consider starting new projects on Yii 3 while keeping existing ones on Yii 2. - -## PHP requirements - -Yii 3 requires PHP 7.4 or above. As a result, there are language features used that were not used in Yii 2: - -- [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) -- [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) - -## Preliminary refactoring - -It is a good idea to refactor your Yii 2 project prior to porting it to Yii 3. That would both make porting easier -and benefit the project in question while it's not moved to Yii 3 yet. - -### Use DI instead of service locator - -Since Yii 3 is forcing you to inject dependencies properly, it is a good idea to prepare and switch from using -service locator (`Yii::$app->`) to [DI container](https://www.yiiframework.com/doc/guide/2.0/en/concept-di-container). - -If usage of DI container is problematic for whatever reason, consider moving all calls to `Yii::$app->` to controller -actions and widgets and passing dependencies manually from controller to what needs them. - -See [Dependency injection and container](../concept/di-container.md) for explanation of the concept. - -### Introduce repositories for getting data - -Since Active Record is not the only way to work with database in Yii 3, consider introducing repositories that would -hide details of getting data and gather them in a single place you can later re-do: - -```php -class PostRepository -{ - public function getArchive() - { - // ... - } - - public function getTop10ForFrontPage() - { - // ... - } - -} -``` - -### Separate domain layer from infrastructure - -In case you have rich complicated domain, it is a good idea to separate it from infrastructure provided by framework i.e. -all the business logic has to go to framework-independent classes. - -### Move more into components - -Yii 3 services are conceptually similar to Yii 2 components so it's a good idea to move reusable parts of your application -into components. diff --git a/guide/es/intro/what-is-yii.md b/guide/es/intro/what-is-yii.md deleted file mode 100644 index 168f76b1..00000000 --- a/guide/es/intro/what-is-yii.md +++ /dev/null @@ -1,68 +0,0 @@ -What is Yii -=========== - -Yii is a high performance, component-based PHP framework for rapidly developing modern Web applications. -The name Yii (pronounced `Yee` or `[ji:]`) means "simple and evolutionary" in Chinese. It can also -be thought of as an acronym for **Yes It Is**! - - -What is Yii Best for? ---------------------- - -Yii is a generic Web programming framework, meaning that it can be used for developing all kinds -of Web applications using PHP. Because of its component-based architecture and sophisticated caching -support, it is especially suitable for developing large-scale applications such as portals, forums, content -management systems (CMS), e-commerce projects, RESTful Web services, and so on. - - -How does Yii Compare with Other Frameworks? -------------------------------------------- - -If you're already familiar with another framework, you may appreciate knowing how Yii compares: - -- Yii takes the [philosophy of being practical and helpful](https://github.com/yiisoft/docs/blob/master/001-yii-values.md) achieving: - - Performance in both development and execution. - - Convenient customizable defaults. - - Practice-orientation. - - Simplicity. - - Explicitness. - - Consistency. - - Yii will never try to over-design things mainly for the purpose of strictly following - some design pattern. -- Yii extensively uses PSR interfaces with ability to reuse what PHP community created and even - replace core implementations if needed. -- Yii is both a set of libraries and a full-stack framework providing many proven and ready-to-use features: - caching, logging, template engine, data abstraction, development tools, code generation; and more. -- Yii is extremely extensible. You can customize or replace nearly every piece of the core's code. You can also - take advantage of Yii's solid extension architecture to use or develop redistributable extensions. -- High performance is always a primary goal of Yii. - -Yii is not a one-man show, it is backed up by a [strong core developer team](https://www.yiiframework.com/team/), 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 regularly incorporated into the core framework and exposed -via simple and elegant interfaces. - - -Yii Versions ------------- - -Yii currently has three major versions available: 1.1, 2.0 and 3.0. - -Version 1.1 is the old generation and is now in security fixes only mode. - -Version 2.0 is current stable version that is in the feature freeze bugfix mode. - -Version 3.0 is the current version in development. This guide is mainly about version 3. - - -Requirements and Prerequisites ------------------------------- - -Yii 3.0 requires PHP 7.4 or above and runs best with the latest version of PHP 7. - -Using Yii requires basic knowledge of object-oriented programming (OOP), as Yii is a pure OOP-based framework. -Yii 3.0 also makes use of the latest features of PHP, such as type declarations and generators. Understanding these -concepts will help you more easily pick up Yii 3.0. - diff --git a/guide/es/runtime/cookies.md b/guide/es/runtime/cookies.md deleted file mode 100644 index b65a6e9f..00000000 --- a/guide/es/runtime/cookies.md +++ /dev/null @@ -1,48 +0,0 @@ -# Cookies - -Cookies allow persisting data between requests by sending it to the client browser using HTTP headers. -The data is sent back to server in each request headers thus cookies are handy to store small amounts of data -such as tokens or flags. - -## Reading cookies - -Cookie values could be obtained from server request that is 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; - // ... -} -``` - -## Sending cookies - -Since sending cookies is, in fact, sending a header but since forming the header isn't trivial, there is `\Yiisoft\Yii\Web\Cookie` class -to help with it: - -```php -$cookie = (new \Yiisoft\Yii\Web\Cookie('cookieName', 'value')) - ->path('/') - ->domain('yiiframework.com') - ->httpOnly(true) - ->secure(true) - ->sameSite(\Yiisoft\Yii\Web\Cookie::SAME_SITE_STRICT) - ->validFor(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. - -## Cookies security - -Each cookie should be properly configured in order to be secure. In the above code 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 cookie sending for all methods. diff --git a/guide/es/runtime/handling-errors.md b/guide/es/runtime/handling-errors.md deleted file mode 100644 index 87b3a2aa..00000000 --- a/guide/es/runtime/handling-errors.md +++ /dev/null @@ -1,135 +0,0 @@ -# Handling errors - -Yii web includes a built-in [[\Yiisoft\Yii\Web\ErrorHandler\ErrorHandler|error handler]] which makes error handling -a much more pleasant experience than before. In particular, the Yii error handler does the following to improve error handling: - -* All non-fatal PHP errors (e.g. warnings, notices) are converted into catchable exceptions. -* Exceptions and fatal PHP errors, even out of memory ones, are displayed with detailed call stack information -and source code lines in verbose mode. -* Supports different error response formats. - -## Using error handler - -The error handler consists of two parts. One part is `Yiisoft\Yii\Web\ErrorHandler\ErrorCatcher` middleware that, -when registered, catches exceptions that appear during middleware stack execution and passes them to the handler. -Another part is the error handler itself that is catching fatal errors, exceptions occurring outside of the middleware stack, -converts warnings and notices to exceptions and more. - -The error handler is registered by an application and its configuration by default comes from the container. -You may configure it in the application configuration, `config/web.php` like the following: - -```php -use \Yiisoft\Yii\Web\ErrorHandler\ErrorHandler; -use \Yiisoft\Yii\Web\ErrorHandler\ThrowableRendererInterface; -use \Psr\Log\LoggerInterface; -use \Yiisoft\Yii\Web\ErrorHandler\HtmlRenderer; -use Psr\Container\ContainerInterface; - -return [ - - ErrorHandler::class => function (ContainerInterface $container) { - $logger = $container->get(LoggerInterface::class); - $defaultRenderer = $container->get(ThrowableRendererInterface::class); - $errorHandler = new ErrorHandler($logger, $defaultRenderer); - return $errorHandler; - - // or the following for production environments - // return $errorHandler->withoutExposedDetails(); - }, - HtmlRenderer::class => function (ContainerInterface $container) { - return (new HtmlRenderer()) - ->withMaxSourceLines(20); - }, -]; -``` - -With the above configuration, the number of source code lines to be displayed in exception at HTML pages will be up to 20. - -As aforementioned, the error handler turns all non-fatal PHP errors into catchable exceptions. This means you can -use the following code to deal with PHP errors: - -```php -try { - 10/0; -} catch (\Exception $e) { - Yii::warning("Division by zero."); -} - -// execution continues... -``` - -## Friendly exceptions - -Yii error renderer supports [friendly exceptions](https://github.com/yiisoft/friendly-exception) that allows you to -make error handling even more pleasant experience for your team. The idea is to provide a readable name and possible -solutions to the problem: - -```php -use Yiisoft\FriendlyException\FriendlyExceptionInterface; - -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 such exception is thrown, error renderer would display the name and the solution if verbose mode is turned on. - -## Customizing error display - -TODO - -### Using error actions - -TODO - - -### Customizing error response format - -The error catcher chooses how to render an exception based on accept HTTP header. If it is `text/html` or any unknown -content type, it will use the error or exception view to display errors. For other mime types, the error handler will -choose different rendering that is registered within the error catcher. By default, JSON, XML and plain text are supported. - -You may customize the error response format by providing your own instance of `Yiisoft\Yii\Web\ErrorHandler\ThrowableRendererInterface` -when registering error catcher middleware. That is typically done in `MiddlewareDispatcherFactory` of your application: - -```php -namespace App\Factory; - -use Psr\Container\ContainerInterface; -use Yiisoft\Router\Middleware\Router; -use Yiisoft\Yii\Web\ErrorHandler\ErrorCatcher; -use Yiisoft\Yii\Web\Middleware\SubFolder; -use Yiisoft\Yii\Web\MiddlewareDispatcher; -use Yiisoft\Yii\Web\Session\SessionMiddleware; - -final class MiddlewareDispatcherFactory -{ - public function __invoke(ContainerInterface $container) - { - $session = $container->get(SessionMiddleware::class); - $router = $container->get(Router::class); - - $errorCatcher = $container->get(ErrorCatcher::class); - $errorCatcher->withAddedRenderer('application/myformat', new MyFormatErrorRenderer()); - - $subFolder = $container->get(SubFolder::class); - - return (new MiddlewareDispatcher($container)) - ->addMiddleware($router) - ->addMiddleware($subFolder) - ->addMiddleware($session) - ->addMiddleware($errorCatcher); - } -} -``` diff --git a/guide/es/runtime/logging.md b/guide/es/runtime/logging.md deleted file mode 100644 index 9b8fdd85..00000000 --- a/guide/es/runtime/logging.md +++ /dev/null @@ -1,290 +0,0 @@ -# Logging - -Yii relies on [PSR-3 interfaces](https://www.php-fig.org/psr/psr-3/) for logging so any PSR-3 compatible logging library -could be configured to do the actual job. - -Yii provides its own logger that is highly customizable and extensible. Using it, you can easily 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](../tool/debugger.md)). - -In this section, we will mainly describe the first two steps. - -## Log Messages - -In order to record log messages you need an instance of PSR-3 logger. A class that writes log messages should receive -it as dependency: - -```php -class MyService -{ - private $logger; - - public function __construct(\Psr\Log\LoggerInterface $logger) - { - $this->logger = $logger; - } -} -``` - -Recording log messages 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 do not require immediate action but should typically be logged and monitored. -- `warning` - Exceptional occurrences that are not errors. Example: Use of deprecated APIs, poor use of an API, - undesirable things that are not 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. First is a message. Second is context array that typically contains structured data that -doesn't fit message well but still does provide important information. In case exception is provided as context, it should -be passed in "exception" key. Another special key is "category". Categories are handy to better organize and filter -log messages. - -```php -class MyService -{ - private $logger; - - public function __construct(\Psr\Log\LoggerInterface $logger) - { - $this->logger = $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 is 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 does not 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 an [[Yiisoft\Log\Target\Email\EmailTarget|email target]] exports -the log messages to specified email addresses. - -You can register multiple 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\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()`. - -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 whitelisting the categories by the `setCategories()` method, you may also -blacklist certain categories by the `setExcept()` method. If the category of a message -is found or matches one of the patterns in this property, it will NOT be processed by the target. - -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: - -``` -2014-10-04 18:10:15 [::1][][-][trace][yii\base\Module::getModule] Loading module: debug -``` - -By default, log messages will be formatted as follows by the [[\Yiisoft\Log\Target::formatMessage()]]: - -``` -Timestamp [IP address][User ID][Session ID][Severity Level][Category] Message Text -``` - -You may customize this format by calling `setPrefix()` method, which takes a PHP callable -returning a customized message prefix. For example, the following code 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 -$userId = ... - -$fileTarget = new \Yiisoft\Log\Target\File\FileTarget('/path/to/app.log'); -$fileTarget->setPrefix(function (string $message) use ($userId) { - return "[$userID]"; -}); -``` - -Besides message prefixes, log targets also append some context information to each batch of log messages. -By default, the values of these global PHP variables are included: `$_GET`, `$_POST`, `$_FILES`, `$_COOKIE`, -`$_SESSION` and `$_SERVER`. You may adjust this behavior by calling target `setLogVars()` method -with the names of the global variables that you want to include by the log target. 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->setLogVars(['_SERVER']); -``` - -You may configure `logVars` to be an empty array to totally disable the inclusion of context information. -Or if you want to implement your own way of providing context information, you may override the -`getContextMessage()` method. - -### Message Trace Level - -During development, it is often desirable to see where each log message is coming from. This can be achieved by -calling the [[\Yiisoft\Log\Logger::setTraceLevel|setTraceLevel]] method like the following: - -```php -$logger = new \Yiisoft\Log\Logger($targets); -$logger->setTraceLevel(3); -``` - -The above application configuration sets trace level to be 3 so each log message will be appended with at most 3 -levels of the call stack at which the log message is recorded. - -> [!IMPORTANT] -> Getting call stack information is not 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 the [[\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 do not get exported -immediately. Instead, the message exporting only occurs when a log target accumulates 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::setEnabled()|setEnabled()]] method. -You may do so via the log target configuration or by the following PHP statement in your code: - -```php -$logger->getTarget('file')->setEnabled(false); -``` - -The above code requires you to name a target as `file`: - -```php -$logger = new \Yiisoft\Log\Logger(['file' => $fileTarget]); -``` - -You also may pass a 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 very simple. You mainly need to implement the [[\Yii\Log\Target::export()]] method -sending the content of the [[\Yii\Log\Target::messages]] array to a designated medium. You may call the -[[\Yii\Log\Target::formatMessage()]] method to format each message. For more details, you may refer to any of the -log target classes included in the Yii release. - -> [!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]]. diff --git a/guide/es/runtime/request.md b/guide/es/runtime/request.md deleted file mode 100644 index d7254374..00000000 --- a/guide/es/runtime/request.md +++ /dev/null @@ -1,181 +0,0 @@ -# Request - -HTTP request contains 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!" -} -``` - -In the above method is `POST`, URI is `/contact`. Additional headers are specifying host, preferred language -and encoding. The body could be anything. In this case it is 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 request object: - -```php -$method = $request->getMethod(); -``` - -Usually it is 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 - -An URI has: - -- Scheme (`http`, `https`) -- Host (`yiiframework.com`) -- Port (`80`, `443`) -- Path (`/posts/1`) -- Query string (`page=1&sort=+id`) -- Fragment (`#anchor`) - -An object of `UriInterface` could be obtained from request like the following: - -```php -$uri = $request->getUri(); -``` - -Then various details could be obtained 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 obtain a single header: - -```php -$values = $request->getHeader('Accept-Encoding'); -``` - - -Alternatively value could be obtained as a comma-separated string instead of an array. That is especially handy if -header contains a single value: - -```php -if ($request->getHeaderLine('X-Requested-With') === 'XMLHttpRequest') { - // this is AJAX request -} -``` - -To check if a header present in the request: - -```php -if ($request->hasHeader('Accept-Encoding')) { - // ... -} -``` - -## Body - -There are two method to obtain body contents. First is getting body as is without parsing: - -```php -$body = $request->getBody(); -``` - -The `$body` would be an instance of `Psr\Http\Message\StreamInterface`. - -Alternatively, parsed body could be obtained: - -```php -$bodyParameters = $request->getParsedBody(); -``` - -Parsing depends on PSR-7 implementation and may require a 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 were 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'); - } -} -``` - -## Attributes - -Application middleware may set custom request attributes using `withAttribute()` method. These attributes could be -obtained with `getAttribute()`. For example, router is setting matched route parameters as same-named attributes. diff --git a/guide/es/runtime/response.md b/guide/es/runtime/response.md deleted file mode 100644 index 5ec141d3..00000000 --- a/guide/es/runtime/response.md +++ /dev/null @@ -1,115 +0,0 @@ -# Response - -HTTP response contains 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 applicaiton to represent response. - -The object should be constructed and returned as a result of execution of controller actions or other middleware. -Usually the middleware has response factory injected into its constructor. - -```php -use Psr\Http\Message\ResponseFactoryInterface; -use Psr\Http\Message\ResponseInterface; -use Psr\Http\Message\ServerRequestInterface; - -class PostAction -{ - private ResponseFactoryInterface $responseFactory; - - public function __construct(ResponseFactoryInterface $responseFactory) - { - $this->responseFactory = $responseFactory; - } - - public function view(ServerRequestInterface $request): ResponseInterface - { - $response = $this->responseFactory->createResponse(); - $response->getBody()->write('Hello!'); - return $response; - } -} -``` - -## Status code - -Setting status code is done 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. - -## Headers - -Headers could be set like this: - -```php -$response = $response->withHeader('Content-type', 'application/json'); -``` - -If there is a need to append a header value to 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`. - -Writing to it could be done 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'); -``` - -### Responding with JSON - -```php -use Yiisoft\Json\Json; - -$data = [ - 'account' => 'samdark', - 'value' => 42 -]; - -$response->getBody()->write(Json::encode($data)); -return $response - ->withStatus(200) - ->withHeader('Content-Type', 'application/json'); -``` diff --git a/guide/es/runtime/sessions.md b/guide/es/runtime/sessions.md deleted file mode 100644 index d5e5f6c4..00000000 --- a/guide/es/runtime/sessions.md +++ /dev/null @@ -1,84 +0,0 @@ -# Sessions - -Sessions allow persisting data between requests without passing them to the client and back. Yii has a special component -to work with session data. - -## Configuring middleware - -In order for session to work properly, ensure that `\Yiisoft\Yii\Web\Session\SessionMiddleware` is registed in application -middleware stack before request router. - -## Opening and closing session - -```php -public function actionProfile(\Yiisoft\Yii\Web\Session\SessionInterface $session) -{ - // start 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 session: - -```php -public function actionProfile(\Yiisoft\Yii\Web\Session\SessionInterface $session) -{ - // discard changes and close session - $session->discard(); - - // destroy 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\Yii\Web\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 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(); -} -``` - -## Custom session storage - -When using `Yiisoft\Yii\Web\Session\Session` as session component, you can provide your own storage implementation: - -```php -$handler = new MySessionHandler(); -$session = new \Yiisoft\Yii\Web\Session\Session([], $handler); -``` - -Custom storage must implement `\SessionHandlerInterface`. diff --git a/guide/es/security/authentication.md b/guide/es/security/authentication.md deleted file mode 100644 index 06edcad2..00000000 --- a/guide/es/security/authentication.md +++ /dev/null @@ -1,203 +0,0 @@ -# Authentication - -Authentication is the process of verifying the identity of a user. It usually uses an identifier -(e.g. a username or an email address) and a secret token (e.g. 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\Yii\Web\User\User` service; -* Create a class implementing the `\Yiisoft\Auth\IdentityInterface` interface; -* Create a class implementing the `\Yiisoft\Auth\IdentityRepositoryInterface` interface; - -## Configuring `Yiisoft\Yii\Web\User\User` - -The `Yiisoft\Yii\Web\User\User` application service manages the user authentication status. It depends on -`Yiisoft\Auth\IdentityRepositoryInterface` that should return an instance of `\Yiisoft\Auth\IdentityInterface` -which contains the actual authentication logic. - -```php -use Yiisoft\Yii\Web\Session\Session; -use Yiisoft\Yii\Web\Session\SessionInterface; -use Yiisoft\Yii\Web\User\User; -use Yiisoft\Auth\IdentityRepositoryInterface; -use Psr\Container\ContainerInterface; -use Psr\EventDispatcher\EventDispatcherInterface; - -return [ - // ... - - SessionInterface::class => [ - '__class' => Session::class, - '__construct()' => [ - $params['session']['options'] ?? [], - $params['session']['handler'] ?? null, - ], - ], - - - // User: - IdentityRepositoryInterface::class => static function (ContainerInterface $container) { - // instead of Cycle-based repository, any implementation could be used - return $container->get(\Cycle\ORM\ORMInterface::class)->getRepository(\App\Entity\User::class); - }, - User::class => static function (ContainerInterface $container) { - $session = $container->get(SessionInterface::class); - $identityRepository = $container->get(IdentityRepositoryInterface::class); - $eventDispatcher = $container->get(EventDispatcherInterface::class); - $user = new Yiisoft\Yii\Web\User\User($identityRepository, $eventDispatcher); - $user->setSession($session); - - return $user; - }, -]; -``` - -## Implementing`\Yiisoft\Auth\IdentityInterface` - -The identity class must implement the `\Yiisoft\Auth\IdentityInterface` which contains -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 implemented as a pure PHP object. - -```php -id = $id; - } - - public function getId(): string - { - return $this->id; - } -} -``` - -## Implementing`\Yiisoft\Auth\IdentityRepositoryInterface` - -The identity repository class must implement the `\Yiisoft\Auth\IdentityRepositoryInterface` which contains -the following methods: - -* `findIdentity(string $id): ?IdentityInterface`: it looks for an instance of the identity - class using the specified ID. This method used when you need to maintain 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 (e.g. in a stateless RESTful application). - -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 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\Yii\Web\User\User` - -`\Yiisoft\Yii\Web\User\User` service can be used to obtain 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\Yii\Web\User\User; - -class SiteController -{ - public function actionIndex(ServerRequestInterface $request, User $user) - { - if ($user->isGuest()) { - // user is guest - } else { - $identity = $user->getIdentity(); - // do something based on identity - } - } -} -``` - -`isGuest()` determines if user is logged in or not. `getIdentity()` returns an instance of identity. - -To login a user, you may use the following code: - -```php -$identity = $identityRepository->findByEmail($email); - -/* @var $user \Yiisoft\Yii\Web\User\User */ -$user->login($identity); -``` - -The `login()` method sets the identity to the User service. Identity is stored into session so user -authentication status is maintained. - -To logout a user, simply call - -```php -/* @var $user \Yiisoft\Yii\Web\User\User */ -$user->logout(); -``` - -## Authentication Events - -The user service raises a few events during the login and logout processes. - - -* `\Yiisoft\Yii\Web\User\Event\BeforeLogin`: raised at the beginning of `login()`. - If the event handler calls `invalidate()` on event object, the login process will be cancelled. -* `\Yiisoft\Yii\Web\User\Event\AfterLogin`: raised after a successful login. -* `\Yiisoft\Yii\Web\User\Event\BeforeLogout`: raised at the beginning of `logout()`. - If the event handler calls `invalidate()` on event object, the logout process will be cancelled. -* `\Yiisoft\Yii\Web\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\Yii\Web\User\Event\AfterLogin`, you may record the login time and IP -address in the `user` database table. diff --git a/guide/es/security/authorization.md b/guide/es/security/authorization.md deleted file mode 100644 index 30291c41..00000000 --- a/guide/es/security/authorization.md +++ /dev/null @@ -1,455 +0,0 @@ -# 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\Yii\Web\User\User` service: - -```php -namespace App\Blog\Post; - -use Psr\Http\Message\ServerRequestInterface; -use Yiisoft\Yii\Web\User\User; - -class PostController -{ - public function actionEdit(ServerRequestInterface $request, User $user, PostRepository $postRepository) - { - $postId = $request->getAttribute('id'); - if ($postId === null) { - // respond with 404 - } - - $post = $postRepository->findByPK($postId); - if ($post === null) { - // respond with 404 - } - - if (!$this->canEditPost($user, $post)) { - // respond with 403 - } - - // continue with editing a post - } - - private function canEditPost(User $user, Post $post): bool - { - return $post->getAuthorId() === $user->getId() || $user->can('updatePost'); - } -} -``` - -Behind the scenes, `Yiisoft\Yii\Web\User\User::can()` method calls `\Yiisoft\Access\AccessCheckerInterface::userHasPermission()` -so an implementation should be provided 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/rbac/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 is needed. Since RBAC implements -`\Yiisoft\Access\AccessCheckerInterface`, using it is similar to using any other implementation of access checker. - -To facilitate our description next, we will first introduce some basic RBAC concepts. - -### Basic Concepts - -A role represents a collection of *permissions* (e.g. creating posts, updating posts). A role may be assigned -to one or multiple users. To check if a user has a specified permission, we may check if the user is assigned -with a role that contains that permission. - -Associated with each role or permission, there may be a *rule*. A rule represents a piece of code that will be -executed during access check to determine 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, he/she will be considered not having the "update post" permission. - -Both roles and permissions can be organized 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 is not `true` vice versa. - - -### Configuring RBAC - -RBAC is available via `yiisoft/rbac` package so we need to require it: - -``` -composer require yiisoft/rbac -``` - -Before we set off to define authorization data and perform access checking, we need to configure the -`\Yiisoft\Access\AccessCheckerInterface` in dependency container: - -```php -use \Psr\Container\ContainerInterface; -use Yiisoft\Rbac\Manager\PhpManager; -use Yiisoft\Rbac\RuleFactory\ClassNameRuleFactory; - -return [ - \Yiisoft\Access\AccessCheckerInterface::class => static function (ContainerInterface $container) { - $aliases = $container->get(\Yiisoft\Aliases\Aliases::class); - return new PhpManager(new ClassNameRuleFactory(), $aliases->get('@rbac')); - } -]; -``` - -`\Yiisoft\Rbac\Manager\PhpManager` uses a PHP script files to store authorization data. The files are located under -`@rbac` alias. Make sure the directory and all the files in it are writable by the Web server process if permissions -hierarchy needs to be changed online. - -### Building Authorization Data - -Building authorization data is all about the following tasks: - -- defining roles and permissions; -- establishing relations among roles and permissions; -- defining rules; -- associating rules with roles and permissions; -- assigning roles to users. - -Depending on authorization flexibility requirements the tasks above could be done in different ways. -If your permissions hierarchy is meant to be changed by developers only, you can use either migrations -or a console command. Migration pro is that it could be executed along with other migrations. Console -command pro is that you have a good overview of the hierarchy in the code rather than it being scattered -among multiple migrations. - -Either way in the end you'll get the following RBAC hierarchy: - -![Simple RBAC hierarchy](img/rbac-hierarchy-1.svg "Simple RBAC hierarchy") - -In case you need permissions hierarchy to be formed dynamically you need a UI or a console command. API used to -build the hierarchy itself won't be different. - -### Using console command - -If your permissions 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 -manager = $manager; - } - - public function configure(): void - { - $this - ->setDescription('Builds RBAC hierarchy') - ->setHelp('Launch to dump RBAC data'); - } - - protected function execute(InputInterface $input, OutputInterface $output): int - { - $auth = $this->manager; - - $auth->removeAll(); - - $createPost = (new Permission('createPost'))->withDescription('Create a post'); - $auth->add($createPost); - - $updatePost = (new Permission('updatePost'))->withDescription('Update post'); - $auth->add($updatePost); - - // add "author" role and give this role the "createPost" permission - $author = new Role('author'); - $auth->add($author); - $auth->addChild($author, $createPost); - - // add "admin" role and give this role the "updatePost" permission - // as well as the permissions of the "author" role - $admin = new Role('admin'); - $auth->add($admin); - $auth->addChild($admin, $updatePost); - $auth->addChild($admin, $author); - - // Assign roles to users. 1 and 2 are IDs returned by IdentityInterface::getId() - // usually implemented in your User model. - $auth->assign($author, 2); - $auth->assign($admin, 1); - - return ExitCode::OK; - } -} -``` - -The command above could be executed from console the following way: - -``` -./vendor/bin/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](db-migrations.md) -to initialize and modify hierarchy via APIs offered by `\Yiisoft\Rbac\ManagerInterface`. - -Create new migration using `./vendor/bin/yii migrate:create init_rbac` then impement creating a hierarchy: - -```php -removeAll(); - - $createPost = (new Permission('createPost'))->withDescription('Create a post'); - $auth->add($createPost); - - $updatePost = (new Permission('updatePost'))->withDescription('Update post'); - $auth->add($updatePost); - - // add "author" role and give this role the "createPost" permission - $author = new Role('author'); - $auth->add($author); - $auth->addChild($author, $createPost); - - // add "admin" role and give this role the "updatePost" permission - // as well as the permissions of the "author" role - $admin = new Role('admin'); - $auth->add($admin); - $auth->addChild($admin, $updatePost); - $auth->addChild($admin, $author); - - // Assign roles to users. 1 and 2 are IDs returned by IdentityInterface::getId() - // usually implemented in your User model. - $auth->assign($author, 2); - $auth->assign($admin, 1); - } - - public function down() - { - $auth = /* obtain auth */; - - $auth->removeAll(); - } -} -``` - -> 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. - -Migration could be applied by using `./vendor/bin/yii migrate`. - -## Assigning roles to users - -TODO: update when signup implemented in demo / template. - -Author can create post, admin can update post and do everything author can. - -If your application allows user signup you need to assign roles to these new users once. For example, in order for all -signed up users to become authors in your advanced project template you need to modify `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: - $auth = \Yii::$app->authManager; - $authorRole = $auth->getRole('author'); - $auth->assign($authorRole, $user->getId()); - - return $user; - } - - return null; -} -``` - -For applications that require complex access control with dynamically updated authorization data, special user interfaces -(i.e. admin panel) may need to be developed using APIs offered by `authManager`. - - -### Using Rules - -As aforementioned, rules add additional constraint to roles and permissions. A rule is a class extending -from `\Yiisoft\Rbac\Rule`. It must implement the `execute()` method. In the hierarchy we've -created previously author cannot edit his own post. Let's fix it. First we need a rule to verify that the user is the post author: - -```php -namespace App\User\Rbac; - -use Yiisoft\Rbac\Item; -use \Yiisoft\Rbac\Rule; - -/** - * Checks if authorID matches user passed via params - */ -class AuthorRule extends Rule -{ - private const NAME = 'isAuthor'; - - public function __construct() { - parent::__construct(self::NAME); - } - - public function execute(string $userId, Item $item, array $parameters = []): bool - { - return isset($params['post']) ? $params['post']->getAuthorId() == $userId : false; - } -} -``` - -The rule above checks if the `post` is created by user rule is checked for. We'll create a special permission `updateOwnPost` in the -command we've used previously: - -```php -/** @var \Yiisoft\Rbac\ManagerInterface $auth */ - -// add the rule -$rule = new AuthorRule(); -$auth->add($rule); - -// add the "updateOwnPost" permission and associate the rule with it. -$updateOwnPost = (new \Yiisoft\Rbac\Permission('updateOwnPost')) - ->withDescription('Update own post') - ->withRuleName($rule->getName()); -$auth->add($updateOwnPost); - -// "updateOwnPost" will be used from "updatePost" -$auth->addChild($updateOwnPost, $updatePost); - -// allow "author" to update their own posts -$auth->addChild($author, $updateOwnPost); -``` - -Now we have got the following hierarchy: - -![RBAC hierarchy with a rule](img/rbac-hierarchy-2.svg "RBAC hierarchy with a rule") - - -### Access Check - -The check is done similar to how it was done in the first section of this guide: - -```php -namespace App\Blog\Post; - -use Psr\Http\Message\ServerRequestInterface; -use Yiisoft\Yii\Web\User\User; - -class PostController -{ - public function actionEdit(ServerRequestInterface $request, User $user, PostRepository $postRepository) - { - $postId = $request->getAttribute('id'); - if ($postId === null) { - // respond with 404 - } - - $post = $postRepository->findByPK($postId); - if ($post === null) { - // respond with 404 - } - - if (!$this->canEditPost($user, $post)) { - // respond with 403 - } - - // continue with editing a post - } - - private function canEditPost(User $user, Post $post): bool - { - return $user->can('updatePost', ['post' => $post]); - } -} -``` - -The difference is that now checking for user's own post is part of the RBAC. - -If the current user is Jane with `ID=1` we are starting at `createPost` and trying to get to `Jane`: - -![Access check](img/rbac-access-check-1.svg "Access check") - -In order to check if a user can update a post, we need to pass an extra parameter that is 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](img/rbac-access-check-2.svg "Access check") - -We are starting with the `updatePost` and going through `updateOwnPost`. In order 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, we will get to `author` which is assigned to John. - -In case of Jane it is a bit simpler since she is an admin: - -![Access check](img/rbac-access-check-3.svg "Access check") - -## Implementing your own access checker - -In case RBAC does not suit your needs, you can implement your own access checker without changing application code: - - -```php -namespace App\User; - -use \Yiisoft\Access\AccessCheckerInterface; - -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/guide/es/security/best-practices.md b/guide/es/security/best-practices.md deleted file mode 100644 index 81244c28..00000000 --- a/guide/es/security/best-practices.md +++ /dev/null @@ -1,206 +0,0 @@ -# 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 are not 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 input should never be considered safe, and you should always check if the value you've got is -actually among allowed ones. For example, if we know that sorting could be done by three fields `title`, `created_at` and `status` -and the field could be supplied via user input, it's better to check the value we've got right where we'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](../input/validation.md) to do alike checks. - -Further reading on the topic: - -- -- - - -### Escape output - -Escape output means that depending on context where we're using data it should be escaped i.e. in context of HTML you -should escape `<`, `>` and alike special characters. In context of JavaScript or SQL it will be different set of characters. -Since it's error-prone to escape everything manually Yii provides various tools to perform escaping for different -contexts. - -Further reading on the topic: - -- -- -- - - -## Avoiding SQL injections - -SQL injection happens when query text is formed 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; --`. -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 library you prefer is doing it. -In case of prepared statements it's not possible to manipulate the query as was demonstrated above. - -If data is used to specify column names or table names the best thing to do is to allow only 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 user name without escaping it will execute JavaScript `alert('Hello!');` resulting in alert box popping up -in a browser. Depending on website instead of innocent alert such script could send messages using your name or even -perform bank transactions. - -Avoiding XSS is quite easy in Yii. There are generally two cases: - -1. You want data to be outputted as plain text. -2. You want data to be outputted as HTML. - -If all you need is plain text then escaping is as easy as the following: - - -```php - -``` - -If it should be HTML we could get some help from [HtmlPurifier](https://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 visits frequently. 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 is not a serious thing, -however this was just an example, there are much more things one could do using this approach, for example triggering payments -or changing data. Imagine that some website has an URL -`http://an.example.com/purse/transfer?to=anotherUser&amount=2000`. Accessing it using GET request, causes transfer of $2000 -from authorized user account to user `anotherUser`. We know, that the browser will always send GET request to load an image, -so we can modify code to accept only POST requests on that URL. Unfortunately, this will not save us, because an attacker -can put some JavaScript code instead of `` tag, which allows to send POST requests to that URL as well. - -For this reason, Yii applies additional mechanisms to protect against CSRF attacks. - -In order to avoid CSRF you should always: - -1. Follow HTTP specification i.e. GET should not change application state. - See [RFC2616](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html) for more details. -2. Keep Yii CSRF protection enabled. - -In Yii CSRF protection is implemented as `Yiisoft\Yii\Web\Middleware\Csrf` middleware. Ensure it is in your application -middleware stack. - -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 case of shared hosting -environments it could be impossible to achieve, so we'll end up with all the code, configs and logs in server webroot. - -If it's the case don't forget to deny access to everything except `web`. If it can't be done 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. It could be used to get information -about database structure, code and to simply rewrite code with what's generated by Gii. - -Debug toolbar should be avoided at production unless really necessary. It exposes all the application and config -details possible. If you absolutely need it check twice that access is properly restricted 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 could 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 do not 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 may -not 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: diff --git a/guide/es/security/cryptography.md b/guide/es/security/cryptography.md deleted file mode 100644 index 5b8f2c75..00000000 --- a/guide/es/security/cryptography.md +++ /dev/null @@ -1,116 +0,0 @@ -# Cryptography - -In this section we'll review the following security aspects: - -- Generating random data -- Encryption and Decryption -- Confirming Data Integrity - -In order to use features above you need to install `yiisoft/security` package: - -``` -composer install yiisoft/security -``` - -## Generating Pseudorandom Data - -Pseudorandom data is 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 end user which in turn will allow them to prove ownership of -that account. It is very important that this token be unique and hard to guess, else there is a possibility that 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); -``` - -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 output may not be ASCII. -- `random_int()` for integers. - -## Encryption and Decryption - -Yii provides convenient helper functions that allow you to encrypt/decrypt data using a secret key. The data is passed -through the encryption function so that only the person which has the secret key will be able to decrypt it. -For example, we need to store some information in our database, but we need to make sure only the user who has -the secret key can view it (even if the application database compromised): - -```php -$encryptedData = (new \Yiisoft\Security\Crypt())->encryptByPassword($data, $password); - -// save data to database or another storage -saveData($encryptedData); -``` - -Decrypting it: - -```php -// obtain encrypted data from database or another storage -$encryptedData = getEncryptedData(); - -$data = (new \Yiisoft\Security\Crypt())->decryptByPassword($encryptedData, $password); -``` - -Key could be used instead of password: - -```php -$encryptedData = (new \Yiisoft\Security\Crypt())->encryptByKey($data, $key); - -// save data to database or another storage -saveData($encryptedData); -``` - -Decrypting it: - -```php -// obtain encrypted data from 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. At the sending side: - -```php -$signedMessage = (new \Yiisoft\Security\Mac())->sign($message, $key); - -sendMessage($signedMessage); -``` - -At 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 BREACH attack by randomizing how token outputted on each request. -A random mask applied to the token making the string always unique. - -In order to mask a token: - -```php -$maskedToken = \Yiisoft\Security\TokenMask::apply($token); -``` - -In order to get original value from the masked one: - -```php -$token = \Yiisoft\Security\TokenMask::remove($maskedToken); -``` diff --git a/guide/es/security/overview.md b/guide/es/security/overview.md deleted file mode 100644 index 78ef4347..00000000 --- a/guide/es/security/overview.md +++ /dev/null @@ -1,16 +0,0 @@ -# Security - -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/guide/es/security/passwords.md b/guide/es/security/passwords.md deleted file mode 100644 index 41e1d816..00000000 --- a/guide/es/security/passwords.md +++ /dev/null @@ -1,41 +0,0 @@ -# Working with Passwords - -Most developers know that passwords cannot 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 sufficient, -but modern hardware makes it possible to reverse such hashes and even stronger ones very quickly using brute force attacks. - -In order to provide increased security for user passwords, even in the worst case scenario (your application is breached), -you need to use a hashing algorithm that is 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. - -In order to use it you need to require the package first: - -``` -composer require yiisoft/secrurity -``` - -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 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 -// obtain hash from database or another storage -$hash = getHash(); - -if ((new PasswordHasher())->validate($password, $hash)) { - // all good, logging user in -} else { - // wrong password -} -``` diff --git a/guide/es/security/trusted-request.md b/guide/es/security/trusted-request.md deleted file mode 100644 index 1faac3d4..00000000 --- a/guide/es/security/trusted-request.md +++ /dev/null @@ -1,43 +0,0 @@ -# Trusted request - -Getting user information like 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 should not blindly trust headers provided by proxies unless you explicitly trust the proxy. -Yii supports configuring trusted proxies via the `Yiisoft\Yii\Web\Middleware\TrustedHostsNetworkResolver`. -It should be added 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 -use Yiisoft\Yii\Web\Middleware\TrustedHostsNetworkResolver; - -/** @var \Psr\Http\Message\ResponseFactoryInterface $responseFactory */ -$trustedHostsNetworkResolver = (new TrustedHostsNetworkResolver($responseFactory)) - ->withAddedTrustedHosts(['1.0.2.0/24']); -``` - -The IP is sent by the proxy in the `X-Forwarded-For` header by default, and the protocol (`http` or `https`) is sent in -`X-Forwarded-Proto`. - -In case your proxies are using different headers you can use the request configuration to adjust these, e.g.: - -```php -use Yiisoft\Yii\Web\Middleware\TrustedHostsNetworkResolver; - -/** @var \Psr\Http\Message\ResponseFactoryInterface $responseFactory */ -$trustedHostsNetworkResolver = (new TrustedHostsNetworkResolver($responseFactory)) - ->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/guide/es/start/databases.md b/guide/es/start/databases.md deleted file mode 100644 index 2acf1d67..00000000 --- a/guide/es/start/databases.md +++ /dev/null @@ -1,16 +0,0 @@ -# Working with Databases - -Yii does not dictate using particular database or storage for your application. -There are many ways you can work with relational databases: - -- [PDO](https://www.php.net/manual/en/book.pdo.php) -- [Doctrine](https://www.doctrine-project.org/) -- [Cycle](https://github.com/cycle) - -For non-relational ones there are usually official libraries available: - -- [ElasticSearch](https://github.com/elastic/elasticsearch-php) -- [Redis](https://redis.io/clients#php) -- ... - -Out of the box, Yii provides [an integration package for Cycle ORM](https://github.com/yiisoft/yii-cycle). diff --git a/guide/es/start/forms.md b/guide/es/start/forms.md deleted file mode 100644 index 3e72a151..00000000 --- a/guide/es/start/forms.md +++ /dev/null @@ -1,2 +0,0 @@ -# Working with Forms - diff --git a/guide/es/start/gii.md b/guide/es/start/gii.md deleted file mode 100644 index e69de29b..00000000 diff --git a/guide/es/start/hello.md b/guide/es/start/hello.md deleted file mode 100644 index ed15c644..00000000 --- a/guide/es/start/hello.md +++ /dev/null @@ -1,238 +0,0 @@ -# Saying Hello - -> [!NOTE] -> This document reflects the current configuration. Yii team is going to make it significantly simpler before release. - -This section describes how to create a new "Hello" page in your application. -To achieve this goal, you will define a route, create [a handler](../structure/handler.md) -and use [view](../structure/views.md) to get content for response: - -* The application will dispatch the request to the handler -* and the handler will in turn use view to render a template that shows the word "Hello" to the end user. - -Through this tutorial, you will learn three things: - -1. how to create a handler to respond to requests, -2. how to create a [view](../structure/view.md) to compose the response's content, and -3. how an application dispatches requests to [handlers](../structure/handler.md). - - -## Creating a Handler - -For the "Hello" task, you will create a `Hello` class with `say` method that reads -a `message` parameter from the request and displays that message back to the user. If the request -does not provide a `message` parameter, the action will display the default "Hello" message. - -Create `src/Controller/Hello.php`: - -```php -responseFactory = $responseFactory; - } - - public function say(ServerRequestInterface $request): ResponseInterface - { - $message = $request->getAttribute('message', 'Hello!'); - - $response = $this->responseFactory->createResponse(); - $response->getBody()->write('The message is: ' . Html::encode($message)); - return $response; - } -} -``` - -The `say` method in our example is given `$request` parameter that we can use to obtain -message, whose value defaults to `"Hello"` (in -the same way you set a default value for any function or method argument in PHP). When the application -receives a request and determines that the `say` action is responsible for handling said request, the application will -populate this parameter with the same named parameter found in the request. In other words, if the request includes -a `message` parameter with a value of `"Goodbye"`, the `$message` variable within the action will be assigned that value. - -The response returned goes through [middleware stack](../structure/middleware.md) and then is outputted to end user -via emitter. - -## Configuring router - -Now to map our handler to URL we need to configure router. We will use a factory -to create the configured router. Create `src/Factory/AppRouterFactory`: - -```php -get(RouteCollectorInterface::class); - $collector->addGroup(Group::create(null, $routes)); - - return new UrlMatcher(new RouteCollection($collector)); - } -} -``` - -In the above we are using FastRoute as routing engine and configuring two routes. For each route -a "controller" `Hello` will be created and its "action" method `say` will be invoked. - -The factory class should be used in the DI container to define router instance. To do that edit `config/web.php` by adding: - -```php -use Yiisoft\Router\FastRoute\UrlGenerator; -use Yiisoft\Router\GroupFactory; -use Yiisoft\Router\RouteCollectorInterface; -use Yiisoft\Router\UrlGeneratorInterface; -use Yiisoft\Router\UrlMatcherInterface; -use App\Factory\AppRouterFactory; - -return [ - // ... - - RouteCollectorInterface::class => new GroupFactory(), - UrlMatcherInterface::class => new AppRouterFactory(), - UrlGeneratorInterface::class => UrlGenerator::class, -]; -``` - -## Trying it out - -After creating the action and the view, start a web server with `./yii serve` and follow the following URL: - -``` -http://localhost:8080/say/Hello+World -``` - -This URL will result in a page displaying "The message is: Hello World". - -If you omit the `message` parameter in the URL, you would see the page display "The message is: Hello!". - -## Creating a View Template - -Usually the task is more complicated than printing out hello world and involves rendering some complex -HTML. For this task it is handy to use [views templates](structure/view.md). They are scripts you -write to generate a response's body. - -For the "Hello" task, you will create a `/views/say/say.php` view that prints the `message` parameter received from the action method: - -```php - - -``` - -Note that in the above code, the `message` parameter is HTML-encoded -before being printed. This is necessary as the parameter comes from an end user, making it vulnerable to -[cross-site scripting (XSS) attacks](https://en.wikipedia.org/wiki/Cross-site_scripting) by embedding -malicious JavaScript code in the parameter. - -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 `say` view is a PHP script that is executed by the view service. - -To use the view we need to modify `src/Controller/Hello.php`: - -```php -responseFactory = $responseFactory; - $this->aliases = $aliases; - $this->view = $view; - } - - public function say(ServerRequestInterface $request): ResponseInterface - { - $message = $request->getAttribute('message', 'Hello!'); - - return $this->render('say', [ - 'message' => $message, - ]); - } - - private function render(string $view, array $parameters = []): ResponseInterface - { - $response = $this->responseFactory->createResponse(); - $content = $this->view->render($view, $parameters, $this); - $response->getBody()->write($content); - - return $response; - } - - public function getViewPath(): string - { - return $this->aliases->get('@views') . '/say'; - } -} -``` - -Here we're using `ViewContextInterface` tell a `view` service where to get templates. Producing response from a -template and parameters is done with `render()` method. - -Sine we've used aliases, we have to configure them in DI container: - -```php -use Yiisoft\Aliases\Aliases; - -return [ - Aliases::class => [ - '__class' => Aliases::class, - '__construct()' => [ - '@root' => dirname(__DIR__), - '@views' => '@root/views', - ], - ], -]; -``` - -TODO: Rewrite when application template is available. Should be way simpler then. - -## Summary - -In this section, you have touched the handler and view parts of the typical web application. -You created a handler as part of a class to handle a specific request. And 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. - -You have also learned about routing in Yii, which act as the bridge between user requests and handlers. - -In the next section, you will learn how to fetch data, and add a new page containing an HTML form. diff --git a/guide/es/start/looking-ahead.md b/guide/es/start/looking-ahead.md deleted file mode 100644 index e69de29b..00000000 diff --git a/guide/es/start/prerequisites.md b/guide/es/start/prerequisites.md deleted file mode 100644 index 64cfefce..00000000 --- a/guide/es/start/prerequisites.md +++ /dev/null @@ -1,25 +0,0 @@ -# What do you need to know - -The Yii learning curve is not as steep as other PHP frameworks but still there are some things you should learn before starting with Yii. - -## PHP - -Yii is a PHP framework so make sure you [read and understand language reference](https://secure.php.net/manual/en/langref.php). -When developing with Yii you will be writing code in an object oriented fashion, so make sure you are familiar with -[Classes and Objects](https://secure.php.net/manual/en/language.oop5.basic.php) as well as -[namespaces](https://secure.php.net/manual/en/language.namespaces.php). - -## Object oriented programming - -Basic understanding of object oriented programming is required. 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). - -Note that the more complicated your application is the more advanced OOP concepts you should learn to successfully -manage that complexity. - -## Command line and composer - -Yii extensively uses 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 are not familiar with using command -line it is time to start trying. Once you learn the basics you'll never want to work without it. - diff --git a/guide/es/start/workflow.md b/guide/es/start/workflow.md deleted file mode 100644 index c4fb91df..00000000 --- a/guide/es/start/workflow.md +++ /dev/null @@ -1,93 +0,0 @@ -# Running Applications - -After installing Yii, you have a working Yii application that can be accessed via -the URL `http://hostname/`. This section will introduce the application's built-in functionality, -how the code is organized, and how the application handles requests in general. - -> [!IMPORTANT] -> For simplicity, throughout this "Getting Started" tutorial, it's assumed that you have set `app/public` - as the document root of your Web server, and configured the URL for accessing - your application to be `http://hostname/index.php` or something similar. - For your needs, please adjust the URLs in our descriptions accordingly. - -Note that unlike the framework itself, after the project template is installed, it is all yours. You're free to add or delete -code and overall modify it as you need. - - -## Functionality - -The application installed contains four pages: - -* the homepage, displayed when you access the URL `http://hostname/index.php`, -* the "About" page, -* the "Contact" page, which displays a contact form that allows end-users to contact you via email, -* and the "Login" page, which displays a login form that can be used to authenticate end-users. Try logging in - with "admin/admin", and you will find the "Login" main menu item will change to "Logout". - -These pages share a common header and footer. The header contains the main menu bar to allow navigation -among different pages. - -You should also see a toolbar at the bottom of the browser window. -This is a useful [debugger tool](https://github.com/yiisoft/yii-debug) provided by Yii to record and display a lot of -debugging information, such as log messages, response statuses, the database queries run, and so on. - -Additionally, to the web application, there is a console script called `yii`, which is located in the applications base directory. -This script can be used to run background and maintenance tasks for the application, which are described -in the [Console Application Section](../tutorial/console.md). - - -## Application Structure - -The most important directories and files in your application are (assuming the application's root directory is `app`): - -``` -app/ application base path - composer.json used by Composer, describes package information - config/ contains application and other configurations - console.php the console application container configuration - web.php the Web application container configuration - src/ source code root - Command/ contains console command classes - Controller/ contains controller classes - Factory/ contains container factories simplifying creation of complicated services - runtime/ contains files generated by Yii during runtime, such as logs and cache files - vendor/ contains the installed Composer packages, including the Yii framework itself - bin/ - yii the Yii console command execution script - views/ contains view files - public/ application Web root, contains Web accessible files - assets/ contains published asset files (javascript and css) by Yii - index.php the entry (or bootstrap) script for the application -``` - -In general, the files in the application can be divided into two types: those under `app/public` and those -under other directories. The former can be directly accessed via HTTP (i.e., in a browser), while the latter can not and should not be. - -The following diagram shows the static structure of an application. - -![Static Structure of Application](images/application-structure.png) - -Each application has an entry script `public/index.php` which is the only Web accessible PHP script in the application. -The entry script is creating an instance an incoming request with the help of one of PSR-7 packages -and passes it to [application](structure-applications.md) instance. An application contains a set of -middleware that are executed sequentially processing the request. The result is passed further to emitter -that takes care of sending a response to the browser. - -Depending on the middleware used, the application may behave differently. By default, there is a router -that, based on URL requested and configuration, chooses a handler that is executed to produce a response. - - -## Request Lifecycle - -The following diagram shows how an application handles a request. - -![Request Lifecycle](images/request-lifecycle.png) - -1. A user makes a request to the [entry script](structure/entry-script.md) `public/index.php`. -2. The entry script loads the container configuration [configuration](concept/configuration.md) and creates - an [application](structure/application.md) instance to handle the request. -3. Application is starting to execute middleware configured. One of these is typically a router. -4. Router finds out what handler to execute based on request and configuration. -5. The handler may load some data, possibly from a database. -6. The handler forms a response by using data. Either directly or with the help of the view package. -7. The response is passed to the emitter that takes care of sending the response to the user's browser. diff --git a/guide/es/structure/action.md b/guide/es/structure/action.md deleted file mode 100644 index dbbe9ca2..00000000 --- a/guide/es/structure/action.md +++ /dev/null @@ -1,122 +0,0 @@ -# Actions - -In a web application what is executed is determined by request URL. Matching is made by router that is -configured with multiple routes. Each route can be attached a middleware that, given request, produces -a response. Since middleware overall could be chained and can pass actual handling to next middleware, -we call the middleware actually doing the job an action. - -There are multiple ways to describe an action. Simplest one is using a closure: - -```php -use \Psr\Http\Message\ServerRequestInterface; -use \Psr\Http\Message\ResponseInterface; -use Yiisoft\Router\Route; - -Route::get('/', function (ServerRequestInterface $request) use ($responseFactory): ResponseInterface { - $response = $responseFactory->createResponse(); - $response->getBody()->write('You are at homepage.'); - return $response; -})); -``` - -It is 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('/', [FrontPageAction::class, 'run']), -``` - -The class itself would like: - -```php -use \Psr\Http\Message\ServerRequestInterface; -use \Psr\Http\Message\ResponseInterface; - -class FrontPageAction -{ - public function run(ServerRequestInterface $request): ResponseInterface - { - // build response for a front page - } -} -``` - -For many cases it makes sense to group handling for multiple routes into a single class: - - -```php -use Yiisoft\Router\Route; - -Route::get('/post/index', [PostController::class, 'actionIndex']), -Route::get('/post/view/{id:\d+}', [PostController::class, 'actionView']), -``` - -The class itself would look like the following: - -```php -use \Psr\Http\Message\ServerRequestInterface; -use \Psr\Http\Message\ResponseInterface; - -class PostController -{ - public function actionIndex(ServerRequestInterface $request): ResponseInterface - { - // render posts list - } - - - public function actionView(ServerRequestInterface $request): ResponseInterface - { - // render a single post - } -} -``` - -This class is usually called "controller". Above code is repetitive so you can use `WebActionsCaller` -middleware: - -```php -use Yiisoft\Router\Route; -use Yiisoft\Yii\Web\Middleware\WebActionsCaller; - -Route::anyMethod('/post/{action:\w+}', new WebActionsCaller(PostController::class, $container)), -``` - -## Autowiring - -Both constructors of action-classes and action-methods are automatically getting services from -dependency injection container: - -```php -use \Psr\Http\Message\ServerRequestInterface; -use \Psr\Http\Message\ResponseInterface; -use Psr\Log\LoggerInterface; - -class PostController -{ - private $postRepository; - - public function __construct(PostRepository $postRepository) - { - $this->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/guide/es/structure/application.md b/guide/es/structure/application.md deleted file mode 100644 index 600bae22..00000000 --- a/guide/es/structure/application.md +++ /dev/null @@ -1,11 +0,0 @@ -# Application - -The primary purpose of the web application in Yii 3 is to process requests in order to get responses. - -Typically, application runtime consists of: - -1. Startup. There it registers error handler, so it can handle errors occurring and firing `ApplicationStartup` event. -2. Handle requests by passing request object to middleware dispatcher to execute [middleware stack](middleware.md) and - get response object. In usual PHP applications it is done once. In [environments such as RoadRunner](../tutorial/using-with-event-loop.md) - it could be done multiple times with the same application instance. Outside of the application response object is converted into actual HTTP response. -3. Shutdown. `ApplicationShutdown` event is called. diff --git a/guide/es/structure/domain.md b/guide/es/structure/domain.md deleted file mode 100644 index e7703a3b..00000000 --- a/guide/es/structure/domain.md +++ /dev/null @@ -1,77 +0,0 @@ -# Domain - -Domain or domain model is what makes the project unique. With requirements and terminology of the problem being solved -in mind (the problem context), we 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 -infrastructure part of the system (i.e., how to save data into 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 complex solution to a simple problem. -> 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 is nearly impossible to build a model that solves multiple problems that is not too complicated by itself. Therefore, -it is a good practice to divide 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 is not mandatory to use -all of them. - -### Entity - -Entity is an 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 are 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, object is considered being 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 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 which only purpose is to hold data as is. It is 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 - -Repository task is to abstract away how domain objects are obtained. These are usually separated in two parts: an interface -that stays in the domain layer and implementation that is situated in infrastructure layer. In such way domain doesn't -care how data is obtained and saves 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 event are not services and should not 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/guide/es/structure/entry-script.md b/guide/es/structure/entry-script.md deleted file mode 100644 index 7d1ec297..00000000 --- a/guide/es/structure/entry-script.md +++ /dev/null @@ -1,118 +0,0 @@ -# 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 are often named as `index.php`, but can also use any other names, -provided Web servers can locate them. - -Entry script for console application is `./vendor/bin/yii`. - -Entry scripts mainly perform the following work: - - -* Register [Composer autoloader](https://getcomposer.org/doc/01-basic-usage.md#autoloading); -* Obtain configuration; -* Use configuration to initialize dependency injection container; -* Get an instance of request. -* Pass it to `Application` to handle and get a response from it. -* With the help of emitter that transform response object into actual HTTP response that is sent to client browser. - -## Web Applications - -The following is the code in the entry script for the application template: - -```php -get(ContainerInterface::class); - -require_once dirname(__DIR__) . '/src/globals.php'; - -$application = $container->get(Application::class); - -$request = $container->get(ServerRequestFactory::class)->createFromGlobals(); - -try { - $application->start(); - $response = $application->handle($request); - $emitter = new SapiEmitter(); - $emitter->emit($response, $request->getMethod() === Method::HEAD); -} finally { - $application->shutdown(); -} -``` - - -## Console Applications - -Similarly, the following is the code for the entry script of a console application: - -```php -#!/usr/bin/env php -get(Application::class)->run(); -})(); -``` - -## Alternative runtimes - -For alternative runtimes such as RoadRunner or Swoole, special entry scripts should be used. See: - -- [Using Yii with RoadRunner](../tutorial/using-yii-with-roadrunner.md) -- [Using Yii with Swoole](../tutorial/using-yii-with-swoole.md) diff --git a/guide/es/structure/handler.md b/guide/es/structure/handler.md deleted file mode 100644 index 651475be..00000000 --- a/guide/es/structure/handler.md +++ /dev/null @@ -1,3 +0,0 @@ -# Request handlers - - diff --git a/guide/es/structure/middleware.md b/guide/es/structure/middleware.md deleted file mode 100644 index 19da987e..00000000 --- a/guide/es/structure/middleware.md +++ /dev/null @@ -1,173 +0,0 @@ -# Middleware - -Yii works with HTTP using 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 from one or several middleware. When the URL is requested, the request object is passed to -the middleware dispatcher that executes middleware from the stack one by one. Each middleware, given the request, can -either return a response or pass execution to the next middleware. - -![Middleware](img/middleware.svg) - -Depending on how stack is configured, application behavior may vary significantly. - -## Using middleware - -Any PSR-15 compatible middleware could be used with Yii and there are many. Say, we need to add basic authentication -one of the application URLs. URL-dependent middeware are configured using router, so we need to modify 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 router factory, `src/Factory/AppRouterFactory.php` modify the route: - -```php -get(\Middlewares\BasicAuthentication::class); - - $routes = [ - // ... - Route::get('/basic-auth', [SiteController::class, 'auth'])->addMiddleware($basicAuth), - ]; - - $collector = $container->get(RouteCollectorInterface::class); - $collector->addGroup(Group::create(null, $routes)); - - return new UrlMatcher(new RouteCollection($collector)); - } -} -``` - -In the above when configuring routing, we are binding `/basic-auth` URL to a chain of middeware consisting of basic -authentication and the action itself. A chain is a special middleware that executes all the middleware it is configured -with. - -The action itself may 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 we can access the data if needed. - -To apply middleware to application overall regardless of URL, adjust `src/Factory/MiddlewareDispatcherFactory.php`: - -```php -use Psr\Container\ContainerInterface; -use Yiisoft\Router\Middleware\Router; -use Yiisoft\Yii\Web\ErrorHandler\ErrorCatcher; -use Yiisoft\Yii\Web\Middleware\SubFolder; -use Yiisoft\Yii\Web\MiddlewareDispatcher; -use Yiisoft\Yii\Web\Session\SessionMiddleware; - -class MiddlewareDispatcherFactory -{ - public function __invoke(ContainerInterface $container) - { - $session = $container->get(SessionMiddleware::class); - $router = $container->get(Router::class); - $errorCatcher = $container->get(ErrorCatcher::class); - $subFolder = $container->get(SubFolder::class); - $basicAuth = $container->get(\Middlewares\BasicAuthentication::class); - - return (new MiddlewareDispatcher($container)) - ->addMiddleware($router) - ->addMiddleware($subFolder) - ->addMiddleware($session) - ->addMiddleware($basicAuth) - ->addMiddleware($errorCatcher); - } -} -``` - -## Creating your own middleware - -To create a middleware you need to implement a single `process` method of `Psr\Http\Server\MiddlewareInterface`: - -```php -public function process(ServerRequestInterface $request, RequestHandlerInterface $next): ResponseInterface; -``` - -There are multiple ways to handle request and choosing one depends on what the middleware should achieve. - -### Forming response directly - -To respond directly one needs a response factory passed via constructor: - -```php -responseFactory = $responseFactory; - } - - public function process(ServerRequestInterface $request, RequestHandlerInterface $next): ResponseInterface - { - $response = $this->responseFactory->createResponse(); - $response->getBody()->write('Hello!'); - return $response; - } -} -``` - -### Delegating handling to the next middleware - -If middleware either is not intended form response / modify request or cannot do it this time, handling could be -left to next middleware in the stack: - -```php -return $next->handle($request); -``` - -### Capturing response to manipulate it - -You may want to capture response to manipulate it. It could be useful for adding CORS headers, gzipping content etc. - -```php -$response = $next->handle($request); -// extra handing -return $response; -``` - diff --git a/guide/es/structure/overview.md b/guide/es/structure/overview.md deleted file mode 100644 index ff1eafa6..00000000 --- a/guide/es/structure/overview.md +++ /dev/null @@ -1,59 +0,0 @@ -# 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, contexts 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 is 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 what is returned by domain layer. - -Besides, Yii applications also have the following: - -* [entry scripts](entry-script.md): they are PHP scripts that are directly accessible by end users. - They are responsible for starting a request handling cycle. Typically a single entry script is handling - whole application. -* [services](service.md): they are typically stateless objects registered within dependency container and - provide various action methods. -* [middleware](middleware.md): they represent code that need to be invoked before and after the actual - handling of each request by action handlers. diff --git a/guide/es/structure/package.md b/guide/es/structure/package.md deleted file mode 100644 index 9b64000b..00000000 --- a/guide/es/structure/package.md +++ /dev/null @@ -1,192 +0,0 @@ -# Packages - -Reusable code could be released as [Composer package](https://getcomposer.org/doc/05-repositories.md#package). -It could be an infrastructure library, a module representing one of the application contexts or, basically, any -reusable code. - -## Using packages - -By default, Composer installs packages registered on [Packagist](https://packagist.org/) - the biggest repository -for open source PHP packages. You can look for packages on Packagist. You may also -[create your own repository](https://getcomposer.org/doc/05-repositories.md#repository) and configure Composer -to use it. This is useful if you are developing private packages that you want to share within your projects only. - -Packages installed by Composer are stored in the `vendor` directory of your project. -Because Composer is a dependency manager, when it installs a package, it will also install all its dependent packages. - -> [!WARNING] -> `vendor` directory of your application should never be modified. - -A package could be installed with the following command: - -``` -composer install vendor-name/package-name -``` - -After it is done, Composer modifies `composer.json` and `composer.lock`. The former defines what packages to install, -and their version constraints the later stores a snapshot of exact versions actually installed. - -Classes from the package will be available immediately via [autoloading](../concept/autoloading.md). - -## Creating packages - - -You may consider creating a package when you feel the need to share with other people your great code. -A package can contain any code you like, such as a helper class, a widget, a service, a middleware, whole module, etc. - -Below are the basic steps you may follow. - -1. Create a project for your package and host it on a VCS repository, such as [github.com](https://github.com). - The development and maintenance work for the package should be done on this repository. -2. Under the root directory of the project, create a file named `composer.json` as required by Composer. Please - refer to the next subsection for more details. -3. Register your package with a Composer repository, such as [Packagist](https://packagist.org/), so that - other users can find and install your package using Composer. - - -### `composer.json` - -Each Composer package must have a `composer.json` file in its root directory. The file contains the metadata about -the package. You may find complete specification about this file in the [Composer Manual](https://getcomposer.org/doc/01-basic-usage.md#composer-json-project-setup). -The following example shows the `composer.json` file for the `yiisoft/yii-widgets` package: - -```json -{ - "name": "yiisoft/yii-widgets", - "type": "library", - "description": "Yii widgets collection", - "keywords": [ - "yii", - "widgets" - ], - "homepage": "https://www.yiiframework.com/", - "license": "BSD-3-Clause", - "support": { - "issues": "https://github.com/yiisoft/yii-widgets/issues?state=open", - "forum": "https://www.yiiframework.com/forum/", - "wiki": "https://www.yiiframework.com/wiki/", - "irc": "ircs://irc.libera.chat:6697/yii", - "source": "https://github.com/yiisoft/yii-widgets" - }, - // package dependencies - "require": { - "php": "^7.4", - "yiisoft/cache": "^3.0@dev", - "yiisoft/view": "^3.0@dev", - "yiisoft/widget": "^3.0@dev" - }, - // development depdendencies - "require-dev": { - "yiisoft/composer-config-plugin": "^1.0@dev", - "phpunit/phpunit": "^8.4", - "phan/phan": "^2.4", - "yiisoft/di": "^3.0@dev", - "yiisoft/event-dispatcher": "^3.0@dev", - "yiisoft/log": "^3.0@dev" - }, - // class autoloading configuration - "autoload": { - "psr-4": { - "Yiisoft\\Yii\\Widgets\\": "src" - } - }, - // development class autoloading configuration - "autoload-dev": { - "psr-4": { - "Yiisoft\\Yii\\Widgets\\Tests\\": "tests" - } - }, - "extra": { - "config-plugin": { - "tests": "config/tests.php" - } - }, - "config": { - "sort-packages": true - } -} -``` - - -#### Package Name - -Each Composer package should have a package name which uniquely identifies the package among all others. -The format of package names is `vendorName/projectName`. For example, in the package name `yiisoft/queue`, -the vendor name and the project name are `yiisoft` and `queue`, respectively. - -> [!WARNING] -> Do NOT use `yiisoft` as your vendor name as it is reserved for use by the Yii itself. - -We recommend you prefix `yii-` to the project name for packages that are not able to work as general PHP -packages and require Yii application. This will allow users to more easily tell whether a package is Yii specific. - - -#### Dependencies - -If your extension depends on other packages, you should list them in `require` section of `composer.json`. -Make sure you also list appropriate version constraints (e.g. `^1.0`, `@stable`) for each dependent package. -Use stable dependencies when your extension released in a stable version. - -#### Class Autoloading - -In order for your classes to be autoloaded, you should specify the `autoload` entry in the `composer.json` file, -like shown below: - -```json -{ - // .... - - "autoload": { - "psr-4": { - "MyVendorName\\MyPackageName\\": "src" - } - } -} -``` - -You may list one or multiple root namespaces and their corresponding file paths. - -### Recommended Practices - -Because packages are meant to be used by other people, you often need to make an extra effort during development. -Below we introduce some common and recommended practices in creating high quality extensions. - - -#### Testing - -You want your package to run flawlessly without bringing problems to other people. To reach this goal, you should -test your extension before releasing it to public. - -It is recommended that you create various test cases to cover your extension code rather than relying on manual tests. -Each time before you release a new version of your package, you may run these test cases to make sure -everything is in good shape. For more details, please refer to the [Testing](../testing/overview.md) section. - - -#### Versioning - -You should give each release of your extension a version number (e.g. `1.0.1`). We recommend you follow the -[semantic versioning](https://semver.org) practice when determining what version numbers should be used. - - -#### Releasing - -To let other people know about your package, you need to release it to the public. - -If it is the first time you are releasing a package, you should register it on a Composer repository, such as -[Packagist](https://packagist.org/). After that, all you need to do is simply create a release tag (e.g. `v1.0.1`) -on the VCS repository of your extension and notify the Composer repository about the new release. People will -then be able to find the new release, and install or update the package through the Composer repository. - -In the releases of your package, in addition to code files, you should also consider including the following to -help other people learn about and use your extension: - -* A readme file in the package root directory: it describes what your extension does and how to install and use it. - We recommend you write it in [Markdown](https://daringfireball.net/projects/markdown/) format and name the file - as `README.md`. -* A changelog file in the package root directory: it lists what changes are made in each release. The file - may be written in Markdown format and named as `CHANGELOG.md`. -* An upgrade file in the package root directory: it gives the instructions on how to upgrade from older releases - of the extension. The file may be written in Markdown format and named as `UPGRADE.md`. -* Tutorials, demos, screenshots, etc.: these are needed if your extension provides many features that cannot be - fully covered in the readme file. -* API documentation: your code should be well documented to allow other people to more easily read and understand it. diff --git a/guide/es/structure/service.md b/guide/es/structure/service.md deleted file mode 100644 index c300c472..00000000 --- a/guide/es/structure/service.md +++ /dev/null @@ -1,113 +0,0 @@ -# Service components - -Application may get complicated, so it makes sense to extract focused parts of business logic -or infrastructure into service components. They are typically injected into other components or action handler. -It is usually done via autowiring: - -```php -public function actionIndex(ServerRequestInterface $request, MyService $myService): ResponseInterface -{ - $id = $request->getAttribute('id'); - - // ... - $extraData = $myService->getExtraData($id); - - // ... -} -``` - -Yii 3 does not 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. - -Services either perform a task or return data. They are created once, put into DI container and then could be used -multiple times. Because of that, it is a good idea to keep your services stateless i.e. both service itself and any of -its dependencies should not hold state. - -## Service dependencies and configuration - -Services should always define all their dependencies on other services via `__construct()`. It both allows you to use -service right away after it is created and serves as an indicator of a service doing too much if there are too many -dependencies. - -- After the service created it should not be re-configured in runtime. -- DI container instance usually **should not** not be injected as a dependency. Prefer concrete interfaces. -- In case of complicated or "heavy" initialization, try to postpone it until service method called. - -The same is valid for configuration values. They should be provided as 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 -class Dsn -{ - private string $dsn; - private string $username; - private string $password; - - public function __construct(string $dsn, string $username, string $password) - { - if (!$this->isValidDsn($dsn)) { - throw new \InvalidArgumentException('DSN provided is not valid.'); - } - - $this->dsn = $dsn; - $this->username = $username; - $this->password = $password; - } - - public function dsn(): string - { - return $this->dsn; - } - - public function username(): string - { - return $this->username; - } - - public function password(): string - { - return $this->password; - } - - private function isValidDsn(string $dsn): bool - { - // check DSN validity - } -} -``` - -## Service methods - -Service method usually does something. It could be a simple thing that is repeated exactly but usually it depends on the -context. For example: - -```php -class PostPersister -{ - private Storage $db; - - public function __construct(Storage $db) - { - $this->db = $db; - } - - public function persist(Post $post) - { - $this->db->insertOrUpdate('post', $post); - } -} -``` - -In the code above we have a service saving posts into permanent storage such as database. An object allowing -communication with a concrete storage is always the same, so it is injected using constructor while the post saved -could vary, so it is passed as a method argument. - -## Is everything a service? - -In many cases it makes sense to choose another class type to place your code into. Check: - -- Repository -- Widget -- [Middleware](middleware.md) -- Entity diff --git a/guide/es/tutorial/console-applications.md b/guide/es/tutorial/console-applications.md index aaf5e7e8..9c2ad6a4 100644 --- a/guide/es/tutorial/console-applications.md +++ b/guide/es/tutorial/console-applications.md @@ -1,28 +1,33 @@ # Console applications -Console applications are mainly used to create utility, background processing and maintenance tasks. +Console applications are mainly used to create utility, background +processing and maintenance tasks. -To get support for console application in your project, get `yiisoft/yii-console` via composer: +To get support for console application in your project, get +`yiisoft/yii-console` via composer: ``` composer require yiisoft/yii-console ``` -After it is installed, you can access entry point as +After it's installed, you can access the entry point as ``` -./vendor/bin/yii +./yii ``` -Out of the box only `serve` command is available. It is starting PHP built-in web server to serve the application locally. +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: +Commands are executed with `symfony/console`. To create your own console +command, you need to define a command: ```php setDescription('Echoes hello') + $this ->setHelp('This command serves for demo purpose') ->addArgument('name', InputArgument::OPTIONAL, 'Name to greet', 'anonymous'); } @@ -65,13 +72,14 @@ return [ ]; ``` -After it is done, the command could be executed as +After it's done, the command could be executed as ``` -./vendor/bin/yii demo/hello Alice +./yii demo:hello Alice ``` -## References +## Referencias -- [Symfony Console component guide](https://symfony.com/doc/current/components/console.html) +- [Symfony Console component + guide](https://symfony.com/doc/current/components/console.html) diff --git a/guide/es/tutorial/performance-tuning.md b/guide/es/tutorial/performance-tuning.md deleted file mode 100644 index ae37eea5..00000000 --- a/guide/es/tutorial/performance-tuning.md +++ /dev/null @@ -1,103 +0,0 @@ -# Performance Tuning - -There are many factors affecting the performance of your application. Some are environmental, some are related -with your code, while some others are related with Yii itself. In this section, we will enumerate 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 in 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/) is not installed in production environment. -- Try [PHP 7 preloading](https://wiki.php.net/rfc/preload). - -## 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 are 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 session file is locked all other requests, which are trying to use the same session are blocked i.e. waiting for the -initial request to release session file. This is fine for development and probably small projects. But when it comes -to handling massive concurrent requests, it is 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\Yii\Web\Session\SessionInterface::class => [ - '__class' => \Yiisoft\Yii\Web\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 alleviate the performance hit, -it does not fully solve the problem. When the database contains enormous amounts of data and the cached data is invalid, -fetching the latest data could be prohibitively expensive without 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 is 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 database. You then use a separate process (such as a cron job) to pull the tasks and process them. -This method is easy 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 on the queue, it will initiate or notify the task handling process to trigger the task processing. - - -## 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: - -- [Yii debug toolbar and debugger](https://github.com/yiisoft/yii2-debug/blob/master/docs/guide/README.md) -- [Blackfire](https://blackfire.io/) -- [XHProf](https://secure.php.net/manual/en/book.xhprof.php) -- [XDebug profiler](https://xdebug.org/docs/profiler) diff --git a/guide/es/tutorial/using-with-event-loop.md b/guide/es/tutorial/using-with-event-loop.md deleted file mode 100644 index b3156e19..00000000 --- a/guide/es/tutorial/using-with-event-loop.md +++ /dev/null @@ -1,48 +0,0 @@ -# Using Yii with event loop - -Normal PHP web request execution cycle consist of setting up environment, getting response, processing it to form response -and sending response. After response is sent, execution is terminated and its context is lost. So for the subsequent -request the whole sequence is repeated. Such approach has a big advantage in ease of development since developer does not -have to take much care about memory leaks or properly cleaning 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 initilize everything possible once -and then process a number of requests using it. Such approach is usually called event loop. - -There are multiple tools that could be used to achieve it. Notably, [RoadRunner](https://roadrunner.dev/) and -[Swoole](https://www.swoole.co.uk/). - -## Event loop implications - -Event loop worker basically looks the following: - -```php -initializeContext(); -while ($request = getRequest()) { - $response = process($request); - emit($response); -} -``` - -Usually there are muliple workers processing requests at the same time same 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 i.e., current processing is blocking processing next request. That means that -long running processes, same as in general PHP applications, should be put into background via using a queue. - -### Services and state - -Since context in event loop is shared between all request-responses processed by a single worker, all changes -in the state of a service made by previous request may affect current request. Moreover, it can be a security problem -if data from one user would be available to another user. - -There are two ways dealing with it. First, you can avoid having state by making services stateless. Second, you can -clean up services at the end of the request processing. - -## Integrations - -- [RoadRunner](using-yii-with-roadrunner.md) -- [Swoole](using-yii-with-swoole.md) diff --git a/guide/es/tutorial/using-yii-with-roadrunner.md b/guide/es/tutorial/using-yii-with-roadrunner.md deleted file mode 100644 index de50e2a0..00000000 --- a/guide/es/tutorial/using-yii-with-roadrunner.md +++ /dev/null @@ -1,100 +0,0 @@ -# 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 operation mode is often called -[event loop](using-with-event-loop.md) and allows not to re-initialize framework for each request that improves -performance significantly. - -## Installation - -RoadRunner works on Linux, MacOS and Windows. Best way to install it is to use Composer: - -``` -composer require spiral/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.yml` and add the following config: - -```yaml -http: - address: ":8080" - workers: - command: "php psr-worker.php" - pool: - numWorkers: 3 -static: - dir: "public" - forbid: [".php", ".htaccess"] -headers: - response: - "Cache-Control": "no-cache" -``` - -We're specifying that entry script is `psr-worker.php`, there should be three workers on port 8080, `public` directory -files are static ones except `.php` and `.htaccess`. Also, we're sending additional header. - -Create `/psr-worker.php`: - -```php -set(Spiral\RoadRunner\PSR7Client::class, $psr7); -$application = $container->get(Application::class); -$application->start(); - -while ($request = $psr7->acceptRequest()) { - $response = $application->handle($request); - $psr7->respond($response); - $application->afterEmit($response); - gc_collect_cycles(); -} - -$application->shutdown(); -``` - -We're creating a worker, initializing DI container and then starting to process requests in an event loop. - -## Starting a server - -To start a server execute the following command: - -``` -./rr serve -d -``` - -## On worker scope - -- Each worker scope is isolated from other workers. Memory is not shared. -- A single worker serves multiple requests where scope is shared. -- At each iteration of event loop every service that depends on state should be reset. diff --git a/guide/es/tutorial/using-yii-with-swoole.md b/guide/es/tutorial/using-yii-with-swoole.md deleted file mode 100644 index fbd888d4..00000000 --- a/guide/es/tutorial/using-yii-with-swoole.md +++ /dev/null @@ -1,89 +0,0 @@ -# Using Yii with Swoole - -[Swoole](https://www.swoole.co.uk/) is a PHP network framework distributed as PECL extension. It allows you built-in async, -multiple threads I/O modules. Developers can use sync or async, coroutine API to write the applications. - -In the context of Yii, it allows running request handlers as workers. Each worker may handle multiple requests. -Such operation mode is often called [event loop](using-with-event-loop.md) and allows not to re-initialize framework -for each request that improves performance significantly. - -## Installation - -Swoole works on Linux and MacOS and can be installed via pecl: - -```bash -pecl install swoole -``` - -## Putting up a server - -Since Swoole doesn't have built-in PSR-7 support, we need a package fixing so: - -```php -composer require ilexn/swoole-convent-psr7 -``` - -Create an entry script, `server.php`: - -```php -get(Application::class); - -$serverRequestFactory = new \Ilex\SwoolePsr7\SwooleServerRequestConverter( - $container->get(ServerRequestFactoryInterface::class), - $container->get(UriFactoryInterface::class), - $container->get(UploadedFileFactoryInterface::class), - $container->get(StreamFactoryInterface::class) -); - -$server = new Swoole\HTTP\Server('0.0.0.0', 9501); - -$server->on('start', static function (Swoole\Http\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 (Swoole\Http\Request $request, Swoole\Http\Response $response) use ($serverRequestFactory, $application) { - $psr7Request = $serverRequestFactory->createFromSwoole($request); - $psr7Response = $application->handle($psr7Request); - - $converter = new \Ilex\SwoolePsr7\SwooleResponseConverter($response); - $converter->send($psr7Response); - $application->afterEmit($psr7Response); -}); - -$server->on('shutdown', static function (Swoole\Http\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 event loop every service that depends on state should be reset. diff --git a/guide/id/README.md b/guide/id/README.md index 828481c8..c921e84f 100644 --- a/guide/id/README.md +++ b/guide/id/README.md @@ -1,6 +1,7 @@ # Panduan Definitif untuk Yii 3.0 -Panduan ini dirilis di bawah [Ketentuan Dokumentasi Yii](https://www.yiiframework.com/doc/terms/). +Panduan ini dirilis di bawah [Ketentuan Dokumentasi +Yii](https://www.yiiframework.com/license#docs). Pengenalan + ------------ @@ -13,7 +14,7 @@ Mulai - --------------- * [Apa yang perlu kamu ketahui](start/prerequisites.md) + -* [Menginstal Yii](start/installation.md) + +* [Membuat proyek](start/creating-project.md) + * [Menjalankan Aplikasi](start/workflow.md) + * [Mengucapkan halo](start/hello.md) + * [Bekerja Dengan Formulir](start/forms.md) + @@ -42,45 +43,47 @@ Konsep Dasar - * [Configuration](concept/configuration.md) + * [Aliases](concept/aliases.md) + * [Events](concept/events.md) + +* [Immutability](concept/immutability.md) + Menangani Permintaan - ----------------- -* [Request Handling Overview](runtime/overview.md) - -* [Bootstrapping](runtime/bootstrapping.md) - * [Routing and URL generation](runtime/routing.md) + * [Request](runtime/request.md) + * [Response](runtime/response.md) + * [Sessions](runtime/sessions.md) + * [Cookies](runtime/cookies.md) + -* [Flash messages](runtime/flash-messages.md) - -* [Handling Errors](runtime/handling-errors.md) ! +* [Handling errors](runtime/handling-errors.md) + * [Logging](runtime/logging.md) + Tampilan - ----- * [Views](views/view.md) - -* [Widgets](views/widget.md) - -* [Assets](views/asset.md) - -* [Bekerja dengan Skrip Klien](views/client-scripts.md) - -* [Theming](views/theming.md) - * [Template Engines](views/template-engines.md) - +* [View injections](views/view-injections.md) + +* [Scripts, styles and metatags](views/script-style-meta.md) +* [Assets](views/asset.md) - +* [Widgets](views/widget.md) - - -Bekerja Dengan Basis Data - +Bekerja Dengan Basis Data +- ---------------------- -* [Database Access Objects](db-dao.md): Menghubungkan ke basis data, permintaan dasar,transaksi, dan manipulasi skema -* [Query Builder](db-query-builder.md): Meminta basis data menggunakan lapisan abstraksi sederhana -* [Active Record](db-active-record.md): Active Record ORM, mengambil dan memanipulasi catatan, dan mendefinisikan hubungan -* [Migrations](db-migrations.md): Terapkan versi kontrol ke basis data Anda di lingkungan pengembangan tim +* [Database Access Objects](db-dao.md): Menghubungkan ke basis data, + permintaan dasar,transaksi, dan manipulasi skema +* [Query Builder](db-query-builder.md): Meminta basis data menggunakan + lapisan abstraksi sederhana +* [Active Record](db-active-record.md): Active Record ORM, mengambil dan + memanipulasi catatan, dan mendefinisikan hubungan +* [Migrations](db-migrations.md): + Mendapatkan Data dari Pengguna - ----------------------- * [Membuat Formulir](input/forms.md) - -* [Memvalidasi Input](input/validation.md) - +* [Memvalidasi + Input](https://github.com/yiisoft/validator/blob/master/docs/guide/en/README.md) + + * [Mengunggah File](input/file-upload.md) - * [Mengumpulkan Input Tabular](input/tabular-input.md) - @@ -105,18 +108,18 @@ Keamanan +- * [Praktik terbaik](security/best-practices.md) + -Caching - +Caching +- ------- -* [Ikhtisar Caching](caching/overview.md) - -* [Data Caching](caching/data.md) - +* [Ikhtisar Caching](caching/overview.md) + +* [Data Caching](caching/data.md) + * [Fragment Caching](caching/fragment.md) - * [Page Caching](caching/page.md) - -* [HTTP Caching](caching/http.md) - +* [HTTP caching](caching/http.md) - RESTful Web Services - --------------------- +---------------------- * [Mulai cepat](rest/quick-start.md) * [Resources](rest/resources.md) @@ -153,10 +156,11 @@ Topik Khusus - * [Aplikasi Konsol](tutorial/console-applications.md) + * [Docker](tutorial/docker.md) - * [Penginternasionalan](tutorial/i18n.md) - -* [Mailing](tutorial/mailing.md) - +* [Mailing](tutorial/mailing.md) + * [Penyesuaian Kinerja](tutorial/performance-tuning.md) + * [Menggunakan Yii dengan event loop](tutorial/using-with-event-loop.md) + -* [Menggunakan Yii dengan RoadRunner](tutorial/using-yii-with-roadrunner.md) + +* [Menggunakan Yii dengan RoadRunner](tutorial/using-yii-with-roadrunner.md) + + * [Menggunakan Yii dengan Swoole](using-yii-with-swoole.md) + Widgets - @@ -169,18 +173,22 @@ Widgets - * [Menu](https://www.yiiframework.com/doc-2.0/yii-widgets-menu.html) * [LinkPager](https://www.yiiframework.com/doc-2.0/yii-widgets-linkpager.html) * [LinkSorter](https://www.yiiframework.com/doc-2.0/yii-widgets-linksorter.html) -* [Bootstrap Widgets](https://www.yiiframework.com/extension/yiisoft/yii2-bootstrap/doc/guide) +* [Bootstrap + Widgets](https://www.yiiframework.com/extension/yiisoft/yii2-bootstrap/doc/guide) -Helpers - +Helpers + ------- -* [Helpers Overview](helper-overview.md) -* [ArrayHelper](helper/array.md) -* [Html](helper-html.md) -* [Url](helper-url.md) +* [Arrays](https://github.com/yiisoft/arrays/) +* [Files](https://github.com/yiisoft/files/) +* [Html](https://github.com/yiisoft/html/) +* [Json](https://github.com/yiisoft/json) +* [Network utilities](https://github.com/yiisoft/network-utilities/) +* [VarDumper](https://github.com/yiisoft/var-dumper) +* [Strings](https://github.com/yiisoft/strings) -Lainnya +Lainnya+ ------ * [Glosarium](glossary.md) diff --git a/guide/id/caching/data.md b/guide/id/caching/data.md index f6c541f4..87208252 100644 --- a/guide/id/caching/data.md +++ b/guide/id/caching/data.md @@ -1,15 +1,19 @@ # Caching data -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 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). -Untuk menggunakan cache, pasang paket [yiisoft/cache](https://github.com/yiisoft/cache): +Untuk menggunakan cache, pasang paket +[yiisoft/cache](https://github.com/yiisoft/cache): ```shell composer require yiisoft/cache ``` -Kode berikut adalah pola penggunaan umum caching data, di mana `$cache` merujuk ke +Kode berikut adalah pola penggunaan umum caching data, di mana `$cache` +merujuk ke instance `Cache` dari paket tersebut: ```php @@ -19,7 +23,7 @@ public function getTopProducts(\Yiisoft\Cache\CacheInterface $cache): array // Try retrieving $data from cache. $data = $cache->getOrSet($key, function (\Psr\SimpleCache\CacheInterface $cache) use ($count) { - // Can't find $data in cache, calculate it from scratch. + // Can't find $data in a cache, calculate it from scratch. return getTopProductsFromDatabase($count); }, 3600); @@ -27,63 +31,90 @@ public function getTopProducts(\Yiisoft\Cache\CacheInterface $cache): array } ``` -Ketika cache memiliki data yang terkait dengan `$key`, ia akan mengembalikan nilai yang di-cache. -Jika tidak, ia akan mengeksekusi fungsi anonim yang diberikan untuk menghitung nilai yang akan di-cache dan dikembalikan. +Ketika cache memiliki data yang terkait dengan `$key`, ia akan mengembalikan +nilai yang di-cache. +Jika tidak, ia akan mengeksekusi fungsi anonim yang diberikan untuk +menghitung nilai yang akan di-cache dan dikembalikan. -Jika fungsi anonim membutuhkan beberapa data dari scope luar, Anda dapat meneruskannya menggunakan pernyataan `use`. +Jika fungsi anonim membutuhkan beberapa data dari scope luar, Anda dapat +meneruskannya menggunakan pernyataan `use`. ## Cache handlers -Layanan cache menggunakan handler cache yang kompatibel dengan [PSR-16](https://www.php-fig.org/psr/psr-16/) yang merepresentasikan berbagai +Layanan cache menggunakan handler cache yang kompatibel dengan +[PSR-16](https://www.php-fig.org/psr/psr-16/) yang merepresentasikan +berbagai penyimpanan cache, seperti memori, berkas, dan basis data. Yii menyediakan handler berikut: -- `NullCache` — placeholder cache yang tidak melakukan caching nyata. Tujuan handler ini adalah menyederhanakan - kode yang perlu memeriksa ketersediaan cache. Misalnya, selama pengembangan atau jika server tidak memiliki - dukungan cache, Anda dapat mengonfigurasi layanan cache untuk menggunakan handler ini. - Saat Anda mengaktifkan dukungan cache nyata, Anda dapat beralih menggunakan handler cache yang sesuai. - Pada kedua kasus, Anda dapat menggunakan kode yang sama tanpa pemeriksaan tambahan. -- `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). - Ini bisa dianggap sebagai opsi tercepat saat berurusan dengan cache untuk aplikasi terpusat (mis., satu - server, tanpa load balancer khusus, dll.). -- [Database](https://github.com/yiisoft/cache-db) — menggunakan tabel basis data untuk menyimpan data yang di-cache. -- [File](https://github.com/yiisoft/cache-file) — menggunakan berkas standar untuk menyimpan data yang di-cache. Ini sangat cocok - untuk menyimpan potongan data besar, seperti konten halaman. -- [Memcached](https://github.com/yiisoft/cache-memcached) — menggunakan ekstensi PHP [memcached](https://secure.php.net/manual/en/book.memcached.php). - Ini bisa dianggap sebagai opsi tercepat saat berurusan dengan cache di aplikasi terdistribusi - (mis., beberapa server, load balancer, dll.) -- [Wincache](https://github.com/yiisoft/cache-wincache) — menggunakan ekstensi PHP [WinCache](https://iis.net/downloads/microsoft/wincache-extension) - ([lihat juga](https://secure.php.net/manual/en/book.wincache.php)). - -[Anda dapat menemukan lebih banyak handler di packagist.org](https://packagist.org/providers/psr/simple-cache-implementation). +- `NullCache` — placeholder cache yang tidak melakukan caching nyata. Tujuan + handler ini adalah menyederhanakan + kode yang perlu memeriksa ketersediaan cache. Misalnya, selama + pengembangan atau jika server tidak memiliki + dukungan cache, Anda dapat mengonfigurasi layanan cache untuk + menggunakan handler ini. + Saat Anda mengaktifkan dukungan cache nyata, Anda dapat beralih + menggunakan handler cache yang sesuai. + Pada kedua kasus, Anda dapat menggunakan kode yang sama tanpa + pemeriksaan tambahan. +- `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). + Ini bisa dianggap sebagai opsi tercepat saat berurusan dengan cache + untuk aplikasi terpusat (mis., satu + server, tanpa load balancer khusus, dll.). +- [Database](https://github.com/yiisoft/cache-db) — menggunakan tabel basis + data untuk menyimpan data yang di-cache. +- [File](https://github.com/yiisoft/cache-file) — menggunakan berkas standar + untuk menyimpan data yang di-cache. Ini sangat cocok + untuk menyimpan potongan data besar, seperti konten halaman. +- [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. + +[Anda dapat menemukan lebih banyak handler di +packagist.org](https://packagist.org/providers/psr/simple-cache-implementation). > [!TIP] > Anda dapat menggunakan penyimpanan cache yang berbeda dalam aplikasi yang sama. Strategi umum adalah: > - Gunakan penyimpanan cache berbasis memori untuk menyimpan data kecil tetapi sering digunakan (mis., statistik) > - Gunakan penyimpanan cache berbasis berkas atau basis data untuk menyimpan data besar dan jarang digunakan (mis., konten halaman) -Handler cache biasanya disetel dalam [dependency injection container](../concept/di-container.md) sehingga dapat +Handler cache biasanya disetel dalam [dependency injection +container](../concept/di-container.md) sehingga dapat dikonfigurasi dan diakses secara global. -Karena semua handler cache mendukung kumpulan API yang sama, Anda dapat menukar handler cache yang digunakan -dengan yang lain. Anda dapat melakukannya dengan mengonfigurasi ulang aplikasi tanpa mengubah kode yang menggunakan cache. +Karena semua handler cache mendukung kumpulan API yang sama, Anda dapat +menukar handler cache yang digunakan +dengan yang lain. Anda dapat melakukannya dengan mengonfigurasi ulang +aplikasi tanpa mengubah kode yang menggunakan cache. ### Cache keys -Sebuah kunci mengidentifikasi secara unik setiap item data yang disimpan di cache. Saat Anda menyimpan sebuah item data, -Anda harus menentukan kunci untuknya. Nantinya, ketika Anda mengambil item data tersebut, Anda perlu memberikan +Sebuah kunci mengidentifikasi secara unik setiap item data yang disimpan di +cache. Saat Anda menyimpan sebuah item data, +Anda harus menentukan kunci untuknya. Nantinya, ketika Anda mengambil item +data tersebut, Anda perlu memberikan kunci yang sesuai. -Anda dapat menggunakan string atau nilai arbitrer sebagai kunci cache. Ketika kunci bukan string, ia akan +Anda dapat menggunakan string atau nilai arbitrer sebagai kunci +cache. Ketika kunci bukan string, ia akan diserialisasi menjadi string secara otomatis. -Strategi umum dalam mendefinisikan kunci cache adalah menyertakan semua faktor penentu dalam bentuk array. +Strategi umum dalam mendefinisikan kunci cache adalah menyertakan semua +faktor penentu dalam bentuk array. -Ketika aplikasi yang berbeda menggunakan penyimpanan cache yang sama, Anda harus menentukan prefiks kunci cache yang unik +Ketika aplikasi yang berbeda menggunakan penyimpanan cache yang sama, Anda +harus menentukan prefiks kunci cache yang unik untuk setiap aplikasi guna menghindari konflik kunci cache. -Anda dapat melakukannya dengan menggunakan dekorator `\Yiisoft\Cache\PrefixedCache`: +Anda dapat melakukannya dengan menggunakan dekorator +`\Yiisoft\Cache\PrefixedCache`: ```php $arrayCacheWithPrefix = new \Yiisoft\Cache\PrefixedCache(new \Yiisoft\Cache\ArrayCache(), 'myapp_'); @@ -92,9 +123,12 @@ $cache = new \Yiisoft\Cache\Cache($arrayCacheWithPrefix); ### Cache expiration -Item data yang disimpan di cache akan tetap di sana selamanya kecuali dihapus karena beberapa kebijakan -caching. Misalnya, ruang cache penuh dan penyimpanan cache menghapus data tertua. -Untuk mengubah perilaku ini, Anda dapat menyetel parameter TTL saat memanggil metode untuk menyimpan item data: +Item data yang disimpan di cache akan tetap di sana selamanya kecuali +dihapus karena beberapa kebijakan +caching. Misalnya, ruang cache penuh dan penyimpanan cache menghapus data +tertua. +Untuk mengubah perilaku ini, Anda dapat menyetel parameter TTL saat +memanggil metode untuk menyimpan item data: ```php $ttl = 3600; @@ -103,11 +137,13 @@ return getTopProductsFromDatabase($count); }, $ttl); ``` -Parameter `$ttl` menunjukkan berapa detik item data dapat tetap valid di cache. Ketika Anda mengambil -item data tersebut, jika waktu kedaluwarsanya telah lewat, metode akan mengeksekusi fungsi dan menyetel nilai yang dihasilkan +Parameter `$ttl` menunjukkan berapa detik item data dapat tetap valid di +cache. Ketika Anda mengambil +item data tersebut, jika waktu kedaluwarsanya telah lewat, metode akan +mengeksekusi fungsi dan menyetel nilai yang dihasilkan ke dalam cache. -Anda dapat menyetel TTL bawaan untuk cache: +You may set the default TTL for the cache: ```php $cache = new \Yiisoft\Cache\Cache($arrayCache, 60 * 60); // 1 hour @@ -121,13 +157,20 @@ $cache->remove($key); ### Invalidation dependencies -Selain pengaturan kedaluwarsa, perubahan pada yang disebut sebagai **ketergantungan invalidasi** juga dapat menginvalidasi item data yang di-cache. -Misalnya, `\Yiisoft\Cache\Dependency\FileDependency` merepresentasikan ketergantungan pada waktu modifikasi sebuah berkas. -Ketika ketergantungan ini berubah, itu berarti ada sesuatu yang memodifikasi berkas terkait. -Akibatnya, konten berkas yang usang yang ditemukan di cache harus diinvalidasi. - -Ketergantungan cache adalah objek dari kelas turunan `\Yiisoft\Cache\Dependency\Dependency`. Ketika Anda -menyimpan sebuah item data ke cache, Anda dapat menyertakan objek ketergantungan cache terkait. Contohnya, +Selain pengaturan kedaluwarsa, perubahan pada yang disebut sebagai +**ketergantungan invalidasi** juga dapat menginvalidasi item data yang +di-cache. +Misalnya, `\Yiisoft\Cache\Dependency\FileDependency` merepresentasikan +ketergantungan pada waktu modifikasi sebuah berkas. +Ketika ketergantungan ini berubah, itu berarti ada sesuatu yang memodifikasi +berkas terkait. +Akibatnya, konten berkas yang usang yang ditemukan di cache harus +diinvalidasi. + +Ketergantungan cache adalah objek dari kelas turunan +`\Yiisoft\Cache\Dependency\Dependency`. Ketika Anda +menyimpan sebuah item data ke cache, Anda dapat menyertakan objek +ketergantungan cache terkait. Contohnya, ```php /** @@ -147,28 +190,38 @@ TagDependency::invalidate($cache, 'item_42'); Berikut ringkasan ketergantungan cache yang tersedia: -- `\Yiisoft\Cache\Dependency\ValueDependency`: menginvalidasi cache ketika nilai yang ditentukan berubah. -- `\Yiisoft\Cache\Dependency\CallbackDependency`: menginvalidasi cache ketika hasil dari callback PHP yang ditentukan - berbeda. -- `\Yiisoft\Cache\Dependency\FileDependency`: menginvalidasi cache ketika waktu modifikasi terakhir berkas berbeda. -- `\Yiisoft\Cache\Dependency\TagDependency`: mengaitkan item data yang di-cache dengan satu atau banyak tag. Anda dapat menginvalidasi - item data yang di-cache dengan tag tertentu dengan memanggil `TagDependency::invalidate()`. - -Anda dapat mengombinasikan banyak ketergantungan menggunakan `\Yiisoft\Cache\Dependency\AnyDependency` atau `\Yiisoft\Cache\Dependency\AllDependencies`. - -Untuk mengimplementasikan ketergantungan Anda sendiri, turunkan dari `\Yiisoft\Cache\Dependency\Dependency`. +- `\Yiisoft\Cache\Dependency\ValueDependency`: menginvalidasi cache ketika + nilai yang ditentukan berubah. +- `\Yiisoft\Cache\Dependency\CallbackDependency`: menginvalidasi cache + ketika hasil dari callback PHP yang ditentukan + berbeda. +- `\Yiisoft\Cache\Dependency\FileDependency`: menginvalidasi cache ketika + waktu modifikasi terakhir berkas berbeda. +- `\Yiisoft\Cache\Dependency\TagDependency`: mengaitkan item data yang + di-cache dengan satu atau banyak tag. Anda dapat menginvalidasi + item data yang di-cache dengan tag tertentu dengan memanggil + `TagDependency::invalidate()`. + +Anda dapat mengombinasikan banyak ketergantungan menggunakan +`\Yiisoft\Cache\Dependency\AnyDependency` atau +`\Yiisoft\Cache\Dependency\AllDependencies`. + +Untuk mengimplementasikan ketergantungan Anda sendiri, turunkan dari +`\Yiisoft\Cache\Dependency\Dependency`. ### Cache stampede prevention -[Cache stampede](https://en.wikipedia.org/wiki/Cache_stampede) adalah jenis kegagalan berantai yang dapat terjadi ketika sistem komputasi paralel masif +[Cache stampede](https://en.wikipedia.org/wiki/Cache_stampede) adalah jenis +kegagalan berantai yang dapat terjadi ketika sistem komputasi paralel masif dengan mekanisme cache berada di bawah beban tinggi. Perilaku ini terkadang juga disebut dog-piling. -`\Yiisoft\Cache\Cache` menggunakan algoritma bawaan "Probably early expiration" yang mencegah cache stampede. -Algoritma ini secara acak memalsukan cache miss untuk satu pengguna sementara yang lain masih dilayani nilai dari cache. -Anda dapat mengontrol perilakunya dengan parameter opsional kelima dari `getOrSet()`, yaitu nilai float bernama `$beta`. -Secara bawaan, beta adalah `1.0`, yang biasanya sudah cukup. -Semakin tinggi nilainya, semakin awal cache akan dibuat ulang. +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 /** diff --git a/guide/id/caching/overview.md b/guide/id/caching/overview.md index 72f5d0bb..c688cfba 100644 --- a/guide/id/caching/overview.md +++ b/guide/id/caching/overview.md @@ -1,13 +1,20 @@ # Caching -Caching adalah cara yang murah dan efektif untuk meningkatkan performa aplikasi. -Dengan menyimpan data yang relatif statis di cache dan menyajikannya dari cache saat diminta, -aplikasi menghemat waktu yang sebaliknya diperlukan untuk menghasilkan data dari awal setiap kali. +Caching adalah cara yang murah dan efektif untuk meningkatkan performa +aplikasi. +Dengan menyimpan data yang relatif statis di cache dan menyajikannya dari +cache saat diminta, +aplikasi menghemat waktu yang sebaliknya diperlukan untuk menghasilkan data +dari awal setiap kali. -Caching dapat terjadi pada berbagai level dan lokasi dalam sebuah aplikasi. Di sisi server, pada level rendah, -cache dapat digunakan untuk menyimpan data dasar, seperti daftar artikel terbaru yang diambil dari basis data; -dan pada level yang lebih tinggi, cache dapat digunakan untuk menyimpan fragmen atau seluruh halaman web, seperti hasil rendering -artikel terbaru. Di sisi klien, Anda dapat menggunakan HTTP caching untuk menyimpan konten halaman yang terakhir dikunjungi +Caching dapat terjadi pada berbagai level dan lokasi dalam sebuah +aplikasi. Di sisi server, pada level rendah, +cache dapat digunakan untuk menyimpan data dasar, seperti daftar artikel +terbaru yang diambil dari basis data; +dan pada level yang lebih tinggi, cache dapat digunakan untuk menyimpan +fragmen atau seluruh halaman web, seperti hasil rendering +artikel terbaru. Di sisi klien, Anda dapat menggunakan HTTP caching untuk +menyimpan konten halaman yang terakhir dikunjungi di cache browser. Yii mendukung semua mekanisme caching berikut: diff --git a/guide/id/concept/aliases.md b/guide/id/concept/aliases.md index 849f9adf..2c661fac 100644 --- a/guide/id/concept/aliases.md +++ b/guide/id/concept/aliases.md @@ -1,11 +1,15 @@ # Aliases -Anda dapat menggunakan alias untuk merepresentasikan path file atau URL sehingga Anda tidak perlu menulis path absolut atau URL secara hard-code di -proyek Anda. Sebuah alias harus diawali karakter `@` agar dapat dibedakan dari path file dan URL biasa. Alias yang +Anda dapat menggunakan alias untuk merepresentasikan path file atau URL +sehingga Anda tidak perlu menulis path absolut atau URL secara hard-code di +proyek Anda. Sebuah alias harus diawali karakter `@` agar dapat dibedakan +dari path file dan URL biasa. Alias yang didefinisikan tanpa `@` di awal akan diprefiks otomatis dengan karakter `@`. -Aplikasi Yii bawaan memiliki beberapa alias yang sudah didefinisikan di `config/params.php`. Misalnya, alias `@public` merepresentasikan -path web root; `@baseUrl` merepresentasikan URL dasar untuk aplikasi Web yang sedang berjalan. +Aplikasi Yii bawaan memiliki beberapa alias yang sudah didefinisikan di +`config/params.php`. Misalnya, alias `@public` merepresentasikan +path web root; `@baseUrl` merepresentasikan URL dasar untuk aplikasi Web +yang sedang berjalan. ## Defining aliases @@ -35,18 +39,22 @@ return [ > [!NOTE] > Path file atau URL yang dialias tidak harus selalu merujuk pada file atau sumber daya yang benar-benar ada. -Dengan alias yang telah didefinisikan, Anda dapat menurunkan alias baru dengan menambahkan garis miring `/` diikuti satu atau beberapa segmen path. -Sebagai contoh, `@foo` adalah alias akar (root), sedangkan `@foo/bar/file.php` adalah alias turunan. - -Anda dapat mendefinisikan sebuah alias menggunakan alias lain (baik alias akar maupun turunan): +Dengan alias yang telah didefinisikan, Anda dapat menurunkan alias baru +dengan menambahkan garis miring `/` diikuti satu atau beberapa segmen path. +Sebagai contoh, `@foo` adalah alias akar (root), sedangkan +`@foo/bar/file.php` adalah alias turunan. +Anda dapat mendefinisikan sebuah alias menggunakan alias lain (baik alias +akar maupun turunan): ```php -'@foobar' => '@foo/bar', +'@foobar' => '@foo/bar', ``` -Parameter `yiisoft/aliases` menginisialisasi layanan `Aliases` dari [paket `yiisoft/aliases`](https://github.com/yiisoft/aliases). -Anda dapat menyetel alias tambahan saat runtime menggunakan layanan tersebut: +Parameter `yiisoft/aliases` menginisialisasi layanan `Aliases` dari [paket +`yiisoft/aliases`](https://github.com/yiisoft/aliases). +Anda dapat menyetel alias tambahan saat runtime menggunakan layanan +tersebut: ```php use \Yiisoft\Aliases\Aliases; @@ -59,7 +67,8 @@ public function actionIndex(Aliases $aliases) ## Menggunakan aliases di konfigurasi -Disarankan untuk me-resolve alias pada level konfigurasi, sehingga service menerima URL dan path sebagai string siap pakai: +Disarankan untuk me-resolve alias pada level konfigurasi, sehingga service +menerima URL dan path sebagai string siap pakai: ```php -Anda dapat menggunakan layanan `Aliases` +Anda dapat menggunakan layanan `Aliases`: ```php use \Yiisoft\Aliases\Aliases; @@ -93,15 +102,18 @@ public function actionIndex(Aliases $aliases) } ``` -Path/URL yang direpresentasikan oleh alias turunan ditentukan dengan mengganti bagian alias akar dengan path/URL yang sesuai +Path/URL yang direpresentasikan oleh alias turunan ditentukan dengan +mengganti bagian alias akar dengan path/URL yang sesuai pada alias turunan tersebut. > [!NOTE] > Metode `get()` tidak memeriksa apakah path/URL hasilnya merujuk pada file atau sumber daya yang ada. -Alias akar juga dapat berisi karakter garis miring `/`. Metode `get()` cukup cerdas untuk menentukan bagian mana -dari sebuah alias yang merupakan alias akar, sehingga dapat menentukan path file atau URL yang sesuai dengan benar: +Alias akar juga dapat berisi karakter garis miring `/`. Metode `get()` cukup +cerdas untuk menentukan bagian mana +dari sebuah alias yang merupakan alias akar, sehingga dapat menentukan path +file atau URL yang sesuai dengan benar: ```php use \Yiisoft\Aliases\Aliases; @@ -116,15 +128,14 @@ 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`. - - -Jika `@foo/bar` tidak didefinisikan sebagai alias akar, pernyataan terakhir akan menghasilkan `/path/to/foo/bar/file.php`. +Jika `@foo/bar` tidak didefinisikan sebagai alias akar, pernyataan terakhir +akan menghasilkan `/path/to/foo/bar/file.php`. ## Alias bawaan -[Aplikasi Yii](https://github.com/yiisoft/app) mendefinisikan serangkaian alias untuk mereferensikan path file dan URL yang umum digunakan: +[Aplikasi Yii](https://github.com/yiisoft/app) mendefinisikan serangkaian +alias untuk mereferensikan path file dan URL yang umum digunakan: - `@root` - direktori dasar dari aplikasi yang sedang berjalan. - `@assets` - direktori publik aplikasi tempat aset dipublikasikan. @@ -134,8 +145,9 @@ Jika `@foo/bar` tidak didefinisikan sebagai alias akar, pernyataan terakhir akan - `@bower` - direktori paket bower. - `@vendor` - direktori `vendor` milik Composer. - `@public` - direktori publik aplikasi yang berisi `index.php`. -- `@runtime` - path runtime aplikasi yang sedang berjalan. Bawaannya `@root/runtime`. +- `@runtime` - path runtime aplikasi yang sedang berjalan. Bawaannya + `@root/runtime`. - `@layout` - direktori berkas layout. -- `@resources` - direktori yang berisi view, sumber aset, dan sumber daya lainnya. +- `@resources` - direktori yang berisi view, sumber aset, dan sumber daya + lainnya. - `@views` - direktori dasar template view aplikasi. - diff --git a/guide/id/concept/autoloading.md b/guide/id/concept/autoloading.md index 775b5a8f..ec70f271 100644 --- a/guide/id/concept/autoloading.md +++ b/guide/id/concept/autoloading.md @@ -1,12 +1,18 @@ # Class autoloading -Karena Yii menggunakan [Composer](https://getcomposer.org) untuk mengelola paket, Yii secara otomatis memuat kelas dari paket-paket tersebut +Karena Yii menggunakan [Composer](https://getcomposer.org) untuk mengelola +paket, Yii secara otomatis memuat kelas dari paket-paket tersebut tanpa perlu melakukan `require` file-nya secara eksplisit. -Saat Composer memasang paket, ia menghasilkan sebuah [autoloader yang kompatibel PSR-4](https://www.php-fig.org/psr/psr-4/). -Untuk menggunakannya, lakukan `require_once` terhadap autoloader `/vendor/autoload.php` di file entry point `index.php` Anda. +Saat Composer memasang paket, ia menghasilkan sebuah [autoloader yang +kompatibel PSR-4](https://www.php-fig.org/psr/psr-4/). +Untuk menggunakannya, lakukan `require_once` terhadap autoloader +`/vendor/autoload.php` di file entry point `index.php` Anda. -Anda dapat menggunakan autoloader tidak hanya untuk paket yang diinstal, tetapi juga untuk aplikasi Anda sendiri karena aplikasi Anda juga merupakan sebuah paket. -Untuk memuat kelas-kelas dari namespace tertentu, tambahkan berikut ini ke `composer.json`: +Anda dapat menggunakan autoloader tidak hanya untuk paket yang diinstal, +tetapi juga untuk aplikasi Anda sendiri karena aplikasi Anda juga merupakan +sebuah paket. +Untuk memuat kelas-kelas dari namespace tertentu, tambahkan berikut ini ke +`composer.json`: ```json { @@ -18,14 +24,19 @@ Untuk memuat kelas-kelas dari namespace tertentu, tambahkan berikut ini ke `comp } ``` -Di mana `App\\` adalah namespace akar dan `src/` adalah direktori tempat kelas-kelas Anda berada. Anda dapat menambahkan lebih banyak sumber (source roots) jika -diperlukan. Setelah selesai, jalankan `composer dump-autoload` atau cukup `composer du` dan kelas-kelas dari namespace terkait +Di mana `App\\` adalah namespace akar dan `src/` adalah direktori tempat +kelas-kelas Anda berada. Anda dapat menambahkan lebih banyak sumber (source +roots) jika +diperlukan. Setelah selesai, jalankan `composer dump-autoload` atau cukup +`composer du` dan kelas-kelas dari namespace terkait akan mulai dimuat secara otomatis. -Jika Anda membutuhkan autoloading khusus lingkungan pengembangan yang tidak digunakan saat menjalankan Composer dengan flag `--no-dev`, +Jika Anda membutuhkan autoloading khusus lingkungan pengembangan yang tidak +digunakan saat menjalankan Composer dengan flag `--no-dev`, tambahkan ke bagian `autoload-dev` alih-alih `autoload`. ## Referensi - [PSR-4: Autoloader](https://www.php-fig.org/psr/psr-4/). -- [Panduan Composer tentang autoloading](https://getcomposer.org/doc/01-basic-usage.md#autoloading). +- [Panduan Composer tentang + autoloading](https://getcomposer.org/doc/01-basic-usage.md#autoloading). diff --git a/guide/id/glossary.md b/guide/id/glossary.md deleted file mode 100644 index be99ef00..00000000 --- a/guide/id/glossary.md +++ /dev/null @@ -1,76 +0,0 @@ -# A - -## alias - -Alias adalah sebuah string yang digunakan oleh Yii untuk merujuk ke kelas atau direktori, misalnya `@app/vendor`. -Baca lebih lanjut di ["Aliases"](concept/aliases.md). - -## asset - -Aset merujuk pada berkas sumber daya. Biasanya berisi kode JavaScript atau CSS, tetapi bisa berupa konten statis apa pun yang diakses melalui HTTP. - -# C - -## configuration - -Konfigurasi dapat merujuk pada proses mengatur properti suatu objek atau pada berkas konfigurasi yang menyimpan -pengaturan untuk sebuah objek atau kelas objek. Baca lebih lanjut di ["Configuration"](concept/configuration.md). - -# D - -## DI - -Dependency Injection (Injeksi Dependensi) adalah teknik pemrograman di mana dependensi sebuah objek disediakan (disuntikkan) dari luar. ["DI"](concept/di-container.md) - -# I - -## installation - -Instalasi adalah proses menyiapkan sesuatu agar dapat bekerja, baik dengan mengikuti berkas readme maupun menjalankan skrip -yang disiapkan khusus. Dalam konteks Yii, ini mencakup pengaturan izin dan pemenuhan persyaratan perangkat lunak. - -# M - -## middleware - -Middleware adalah pemroses dalam tumpukan pemrosesan permintaan (request). Diberikan sebuah request, ia dapat menghasilkan response -atau melakukan suatu aksi dan meneruskan pemrosesan ke middleware berikutnya. Baca lebih lanjut di ["Middleware"](structure/middleware.md). - -## module - -Modul adalah sub-aplikasi yang mengelompokkan sejumlah kode berdasarkan suatu kasus penggunaan. Biasanya digunakan di dalam aplikasi utama -dan dapat berisi handler URL atau perintah konsol. - -# N - -## namespace - -Namespace merujuk pada [fitur bahasa PHP](https://www.php.net/manual/en/language.namespaces.php). - -# P - -## package - -Paket biasanya merujuk pada [paket Composer](https://getcomposer.org/doc/). Ini adalah kode yang siap digunakan ulang dan -didistribusikan, yang dapat diinstal secara otomatis melalui manajer paket. - -# R - -## rule - -Aturan biasanya merujuk pada aturan validasi dari paket [yiisoft/validator](https://github.com/yiisoft/validator). -Aturan menyimpan serangkaian parameter untuk memeriksa apakah sebuah himpunan data valid. -"Rule handler" melakukan pemrosesan sebenarnya. - -# Q - -## queue - -Antrian mirip dengan tumpukan (stack), tetapi mengikuti metodologi First-In-First-Out. - -# V - -## vendor - -Vendor adalah organisasi atau pengembang individu yang menyediakan kode dalam bentuk paket. Istilah ini juga dapat merujuk pada -direktori `vendor` milik [Composer](https://getcomposer.org/doc/). diff --git a/guide/id/tutorial/console-applications.md b/guide/id/tutorial/console-applications.md new file mode 100644 index 00000000..14f55028 --- /dev/null +++ b/guide/id/tutorial/console-applications.md @@ -0,0 +1,85 @@ +# Console applications + +Console applications are mainly used to create utility, background +processing and maintenance tasks. + +To get support for console application in your project, get +`yiisoft/yii-console` via composer: + + +``` +composer require yiisoft/yii-console +``` + +After it's installed, you can access the entry point as + +``` +./yii +``` + +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 [ + 'console' => [ + 'commands' => [ + 'demo/hello' => App\Demo\HelloCommand::class, + ], + ], +]; +``` + +After it's done, the command could be executed as + +``` +./yii demo:hello Alice +``` + + +## Referensi + +- [Symfony Console component + guide](https://symfony.com/doc/current/components/console.html) diff --git a/guide/po4a.cfg b/guide/po4a.cfg deleted file mode 100644 index a23a33ea..00000000 --- a/guide/po4a.cfg +++ /dev/null @@ -1,69 +0,0 @@ -[po4a_langs] ru - - - -[po4a_paths] po/$master/$master.pot $lang:po/$master/$lang/$master.$lang.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" -[po4a_alias:markdown] text opt:"--option markdown" opt:"--option keyvalue" opt:"--option yfm_keys=title,description,menu_title" opt:"--addendum-charset=UTF-8" opt:"--localized-charset=UTF-8" opt:"--master-charset=UTF-8" opt:"--keep=5" - - -[type: markdown] en/README.md $lang:$lang/README.md - -[type: markdown] en/caching/data.md $lang:$lang/caching/data.md pot=caching_data.md -[type: markdown] en/caching/overview.md $lang:$lang/caching/overview.md pot=caching_overview.md - -[type: markdown] en/concept/aliases.md $lang:$lang/concept/aliases.md pot=concept_aliases.md -[type: markdown] en/concept/autoloading.md $lang:$lang/concept/autoloading.md pot=concept_autoloading.md -[type: markdown] en/concept/configuration.md $lang:$lang/concept/configuration.md pot=concept_configuration.md -[type: markdown] en/concept/di-container.md $lang:$lang/concept/di-container.md pot=concept_di-container.md -[type: markdown] en/concept/events.md $lang:$lang/concept/events.md pot=concept_events.md -[type: markdown] en/concept/immutability.md $lang:$lang/concept/immutability.md pot=concept_immutability.md - -[type: markdown] en/databases/db-migrations.md $lang:$lang/databases/db-migrations.md pot=databases_db-migrations.md - -[type: markdown] en/intro/upgrade-from-v2.md $lang:$lang/intro/upgrade-from-v2.md pot=intro_upgrade-from-v2.md -[type: markdown] en/intro/what-is-yii.md $lang:$lang/intro/what-is-yii.md pot=intro_what-is-yii.md - -[type: markdown] en/runtime/cookies.md $lang:$lang/runtime/cookies.md pot=runtime_cookies.md -[type: markdown] en/runtime/handling-errors.md $lang:$lang/runtime/handling-errors.md pot=runtime_handling-errors.md -[type: markdown] en/runtime/logging.md $lang:$lang/runtime/logging.md pot=runtime_logging.md -[type: markdown] en/runtime/request.md $lang:$lang/runtime/request.md pot=runtime_request.md -[type: markdown] en/runtime/response.md $lang:$lang/runtime/response.md pot=runtime_response.md -[type: markdown] en/runtime/routing.md $lang:$lang/runtime/routing.md pot=runtime_routing.md -[type: markdown] en/runtime/sessions.md $lang:$lang/runtime/sessions.md pot=runtime_sessions.md - -[type: markdown] en/security/authentication.md $lang:$lang/security/authentication.md pot=security_authentication.md -[type: markdown] en/security/authorization.md $lang:$lang/security/authorization.md pot=security_authorization.md -[type: markdown] en/security/best-practices.md $lang:$lang/security/best-practices.md pot=security_best-practices.md -[type: markdown] en/security/cryptography.md $lang:$lang/security/cryptography.md pot=security_cryptography.md -[type: markdown] en/security/overview.md $lang:$lang/security/overview.md pot=security_overview.md -[type: markdown] en/security/passwords.md $lang:$lang/security/passwords.md pot=security_passwords.md -[type: markdown] en/security/trusted-request.md $lang:$lang/security/trusted-request.md pot=security_trusted-request.md - -[type: markdown] en/start/creating-project.md $lang:$lang/start/creating-project.md pot=start_creating-project.md -[type: markdown] en/start/databases.md $lang:$lang/start/databases.md pot=start_databases.md -[type: markdown] en/start/forms.md $lang:$lang/start/forms.md pot=start_forms.md -[type: markdown] en/start/gii.md $lang:$lang/start/gii.md pot=start_gii.md -[type: markdown] en/start/hello.md $lang:$lang/start/hello.md pot=start_hello.md -[type: markdown] en/start/looking-ahead.md $lang:$lang/start/looking-ahead.md pot=start_looking-ahead.md -[type: markdown] en/start/prerequisites.md $lang:$lang/start/prerequisites.md pot=start_prerequisites.md -[type: markdown] en/start/workflow.md $lang:$lang/start/workflow.md pot=start_workflow.md - -[type: markdown] en/structure/action.md $lang:$lang/structure/action.md pot=structure_action.md -[type: markdown] en/structure/application.md $lang:$lang/structure/application.md pot=structure_application.md -[type: markdown] en/structure/domain.md $lang:$lang/structure/domain.md pot=structure_domain.md -[type: markdown] en/structure/entry-script.md $lang:$lang/structure/entry-script.md pot=structure_entry-script.md -[type: markdown] en/structure/handler.md $lang:$lang/structure/handler.md pot=structure_handler.md -[type: markdown] en/structure/middleware.md $lang:$lang/structure/middleware.md pot=structure_middleware.md -[type: markdown] en/structure/overview.md $lang:$lang/structure/overview.md pot=structure_overview.md -[type: markdown] en/structure/package.md $lang:$lang/structure/package.md pot=structure_package.md -[type: markdown] en/structure/service.md $lang:$lang/structure/service.md pot=structure_service.md - -[type: markdown] en/tutorial/console-applications.md $lang:$lang/tutorial/console-applications.md pot=tutorial_console-applications.md -[type: markdown] en/tutorial/mailing.md $lang:$lang/tutorial/mailing.md pot=tutorial_mailing.md -[type: markdown] en/tutorial/performance-tuning.md $lang:$lang/tutorial/performance-tuning.md pot=tutorial_performance-tuning.md -[type: markdown] en/tutorial/using-with-event-loop.md $lang:$lang/tutorial/using-with-event-loop.md pot=tutorial_using-with-event-loop.md -[type: markdown] en/tutorial/using-yii-with-roadrunner.md $lang:$lang/tutorial/using-yii-with-roadrunner.md pot=tutorial_using-yii-with-roadrunner.md -[type: markdown] en/tutorial/using-yii-with-swoole.md $lang:$lang/tutorial/using-yii-with-swoole.md pot=tutorial_using-yii-with-swoole.md - -[type: markdown] en/views/view-injections.md $lang:$lang/views/view-injections.md pot=views_view-injections.md diff --git a/guide/ru/concept/di-container.md b/guide/ru/concept/di-container.md index 64315183..3152c6c0 100644 --- a/guide/ru/concept/di-container.md +++ b/guide/ru/concept/di-container.md @@ -29,8 +29,8 @@ class CachedWidget extends Cache } ``` -Проблема здесь в том, что эти два класса становятся излишне сопряженными или -взаимозависимыми, что делает их более хрупкими. +The issue here is that these two are becoming unnecessarily coupled or +inter-dependent, making them more fragile. Есть способ справиться с этой проблемой — композиция: diff --git a/guide/ru/intro/what-is-yii.md b/guide/ru/intro/what-is-yii.md index b44fdd6c..3e80a59e 100644 --- a/guide/ru/intro/what-is-yii.md +++ b/guide/ru/intro/what-is-yii.md @@ -59,8 +59,8 @@ OpenCollective](https://opencollective.com/yiisoft), и большим сооб ## Требования к ПО и знаниям -Yii3 требует PHP 8.2 или выше, но некоторые пакеты также поддерживают PHP -7.4. +Yii3 требует PHP 8.2 или выше, но некоторые пакеты работают со старыми +версиями PHP, такими как PHP 7.4. Для разработки на Yii потребуется общее понимание объектно-ориентированного программирования (ООП), так как фреймворк