Implement localization for API responses and error messages
- Added localization support for API responses in English and Spanish. - Introduced a middleware to set the API locale based on the Accept-Language header. - Updated various exception messages and validation responses to use localized strings. - Created new language files for English and Spanish translations. - Refactored existing code to replace hardcoded messages with localized strings. - Added tests to verify localization functionality and response correctness.
This commit is contained in:
104
lang/en/api.php
Normal file
104
lang/en/api.php
Normal file
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'auth' => [
|
||||
'unauthenticated' => 'Unauthenticated.',
|
||||
'invalid_credentials' => 'Email or password is incorrect.',
|
||||
'login_success' => 'Signed in successfully.',
|
||||
'logout_success' => 'Signed out successfully.',
|
||||
'register_success' => 'User registered successfully.',
|
||||
'password_reset_requested' => 'If the email is registered, you will receive a code to reset your password.',
|
||||
'password_reset_invalid' => 'The password recovery request is invalid or has already been used.',
|
||||
'password_updated' => 'Password updated successfully.',
|
||||
'reset_code_invalid' => 'The code you entered is invalid.',
|
||||
'reset_code_valid' => 'Code validated successfully.',
|
||||
'invalid_tenant_or_return_url' => 'The tenant or return URL is invalid.',
|
||||
'request_expired' => 'The authentication request expired. Please try again.',
|
||||
'invalid_return_url' => 'The return URL is invalid.',
|
||||
'oauth_code_expired' => 'The authentication code expired or has already been used.',
|
||||
'tenant_mismatch' => 'The tenant does not match the authentication request.',
|
||||
'google_email_required' => 'Google did not return an email for the account.',
|
||||
'google_email_unverified' => 'The Google account must have a verified email.',
|
||||
],
|
||||
'cart' => [
|
||||
'item_added' => 'Product added to cart.',
|
||||
'quantity_updated' => 'Product quantity updated.',
|
||||
'item_removed' => 'Product removed from cart.',
|
||||
'positive_quantity' => 'The quantity must be greater than zero.',
|
||||
'insufficient_stock' => 'There is not enough stock for the requested product. Maximum available: :max.',
|
||||
'max_quantity' => 'You can add a maximum of :max.',
|
||||
'bundle_variant_forbidden' => 'A bundle cannot have a variant.',
|
||||
'empty_bundle' => 'The bundle has no components.',
|
||||
'variant_required' => 'You must select a variant for this item.',
|
||||
],
|
||||
'purchase' => [
|
||||
'source_required' => 'A cart or direct item is required.',
|
||||
'payment_method_required' => 'The purchase payment method must be selected before finalizing.',
|
||||
'not_editable' => 'The purchase is no longer editable.',
|
||||
'item_not_editable' => 'The purchase item is no longer editable.',
|
||||
'insufficient_stock' => 'There is not enough stock available.',
|
||||
'cannot_confirm' => 'A cancelled, rejected, or expired purchase cannot be confirmed.',
|
||||
'inconsistent_reservation' => 'The purchase has an inconsistent stock reservation.',
|
||||
'paid_cannot_cancel' => 'A paid purchase cannot be cancelled.',
|
||||
'direct_item_max_stock' => 'There is not enough stock. Maximum available: :max.',
|
||||
'empty_cart' => 'The selected cart does not contain items.',
|
||||
'catalog_item_missing' => 'One or more catalog items could not be loaded.',
|
||||
'catalog_item_wrong_tenant' => 'One or more catalog items do not belong to the tenant.',
|
||||
'inactive_cart' => 'The selected cart is no longer active.',
|
||||
'not_available_for_payment' => 'The purchase is no longer available for payment.',
|
||||
],
|
||||
'ticket' => [
|
||||
'not_available' => 'One or more tickets are not available.',
|
||||
'positive_quantity' => 'The number of tickets to generate must be greater than zero.',
|
||||
'empty_bundle' => 'Bundle :bundle has no components.',
|
||||
'disabled' => 'Product :product does not have tickets enabled.',
|
||||
'expired' => 'Product :product has reached its maximum usage date.',
|
||||
'invalid_variant' => 'Variant :variant does not belong to product :product.',
|
||||
'purchase_without_user' => 'Purchase :purchase does not have an associated user.',
|
||||
'product_not_found' => 'The product for purchase item :purchase_item was not found.',
|
||||
],
|
||||
'integration' => [
|
||||
'not_configured' => 'The integration is not configured for this tenant.',
|
||||
'configured' => 'Integration configured successfully.',
|
||||
'validation_failed' => 'Configuration validation failed: :error',
|
||||
'invalid_payment_method' => 'Invalid payment method.',
|
||||
'account_info_failed' => 'Could not retrieve account information.',
|
||||
'qr_generation_failed' => 'Could not generate the QR code.',
|
||||
'webhook_failed' => 'The webhook could not be processed.',
|
||||
],
|
||||
'mail' => [
|
||||
'test_sent' => 'Test email sent successfully.',
|
||||
],
|
||||
'catalog' => [
|
||||
'standard_with_components' => 'A standard item cannot have components.',
|
||||
'duplicate_component' => 'The component is duplicated.',
|
||||
'component_wrong_tenant' => 'The item does not belong to the bundle tenant.',
|
||||
'invalid_component' => 'The component must be a standard item other than the bundle.',
|
||||
'component_variant_required' => 'You must select a variant for this component.',
|
||||
'component_variant_forbidden' => 'A component with direct inventory cannot have a variant.',
|
||||
'component_variant_invalid' => 'The variant does not belong to the selected component.',
|
||||
'bundle_component_required' => 'A bundle must have at least one component.',
|
||||
'bundle_field_forbidden' => ':field is not allowed for a bundle.',
|
||||
'attachment_not_found' => 'The specified attachment does not exist.',
|
||||
'attribute_not_found' => 'Attribute :attribute does not exist for the item tenant.',
|
||||
'managed_inventory_fields' => 'inventory_id, reserved_stock, and sold_units are managed internally.',
|
||||
'attribute_not_on_item' => 'The attribute does not belong to the catalog item.',
|
||||
'invalid_effective_date_range' => 'The effective maximum date must be after or equal to the effective minimum date.',
|
||||
'variants_required' => 'An item with attribute_codes must have variants.',
|
||||
'variants_forbidden' => 'An item without attribute_codes cannot have variants.',
|
||||
'direct_inventory_forbidden' => 'An item with variants cannot have direct inventory.',
|
||||
],
|
||||
'menu' => [
|
||||
'schema_required' => 'The schema is required for static menus.',
|
||||
'not_found' => 'The specified menu does not exist.',
|
||||
],
|
||||
'tenant' => [
|
||||
'invalid_carousel_image' => 'The specified image does not exist or is not an image attachment.',
|
||||
],
|
||||
'errors' => [
|
||||
'forbidden' => 'You do not have permission to perform this action.',
|
||||
'not_found' => 'The requested resource was not found.',
|
||||
'method_not_allowed' => 'The HTTP method is not allowed for this route.',
|
||||
'request_failed' => 'The request could not be processed.',
|
||||
],
|
||||
];
|
||||
57
lang/en/validation.php
Normal file
57
lang/en/validation.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'after_or_equal' => 'The :attribute must be a date after or equal to :date.',
|
||||
'array' => 'The :attribute must be an array.',
|
||||
'boolean' => 'The :attribute field must be true or false.',
|
||||
'confirmed' => 'The :attribute confirmation does not match.',
|
||||
'date' => 'The :attribute must be a valid date.',
|
||||
'distinct' => 'The :attribute field has a duplicate value.',
|
||||
'email' => 'The :attribute must be a valid email address.',
|
||||
'exists' => 'The selected :attribute is invalid.',
|
||||
'file' => 'The :attribute must be a file.',
|
||||
'integer' => 'The :attribute must be an integer.',
|
||||
'max' => [
|
||||
'array' => 'The :attribute must not have more than :max items.',
|
||||
'file' => 'The :attribute must not be greater than :max kilobytes.',
|
||||
'numeric' => 'The :attribute must not be greater than :max.',
|
||||
'string' => 'The :attribute must not be greater than :max characters.',
|
||||
],
|
||||
'min' => [
|
||||
'array' => 'The :attribute must have at least :min items.',
|
||||
'file' => 'The :attribute must be at least :min kilobytes.',
|
||||
'numeric' => 'The :attribute must be at least :min.',
|
||||
'string' => 'The :attribute must be at least :min characters.',
|
||||
],
|
||||
'numeric' => 'The :attribute must be a number.',
|
||||
'password' => [
|
||||
'letters' => 'The :attribute must contain at least one letter.',
|
||||
'mixed' => 'The :attribute must contain at least one uppercase and one lowercase letter.',
|
||||
'numbers' => 'The :attribute must contain at least one number.',
|
||||
'symbols' => 'The :attribute must contain at least one symbol.',
|
||||
'uncompromised' => 'The given :attribute has appeared in a data leak. Please choose a different one.',
|
||||
],
|
||||
'prohibited' => 'The :attribute field is prohibited.',
|
||||
'regex' => 'The :attribute format is invalid.',
|
||||
'required' => 'The :attribute field is required.',
|
||||
'required_with' => 'The :attribute field is required when :values is present.',
|
||||
'required_without' => 'The :attribute field is required when :values is not present.',
|
||||
'string' => 'The :attribute must be a string.',
|
||||
'unique' => 'The :attribute has already been taken.',
|
||||
'url' => 'The :attribute must be a valid URL.',
|
||||
'uuid' => 'The :attribute must be a valid UUID.',
|
||||
'attributes' => [
|
||||
'cantidad' => 'quantity',
|
||||
'catalog_item_id' => 'product',
|
||||
'codigo' => 'code',
|
||||
'dni' => 'ID number',
|
||||
'email' => 'email',
|
||||
'nombre_apellido' => 'full name',
|
||||
'oauth_code' => 'authentication code',
|
||||
'password' => 'password',
|
||||
'password_confirmation' => 'password confirmation',
|
||||
'telefono' => 'phone number',
|
||||
'tenant_codigo' => 'tenant',
|
||||
'variant_id' => 'variant',
|
||||
],
|
||||
];
|
||||
104
lang/es/api.php
Normal file
104
lang/es/api.php
Normal file
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'auth' => [
|
||||
'unauthenticated' => 'No autenticado.',
|
||||
'invalid_credentials' => 'Email o contraseña incorrectos.',
|
||||
'login_success' => 'Sesión iniciada correctamente.',
|
||||
'logout_success' => 'Sesión cerrada correctamente.',
|
||||
'register_success' => 'Usuario registrado correctamente.',
|
||||
'password_reset_requested' => 'Si el email está registrado, recibirás un código para recuperar tu contraseña.',
|
||||
'password_reset_invalid' => 'La solicitud de recuperación es inválida o ya fue utilizada.',
|
||||
'password_updated' => 'Contraseña modificada correctamente.',
|
||||
'reset_code_invalid' => 'El código ingresado es inválido.',
|
||||
'reset_code_valid' => 'Código validado correctamente.',
|
||||
'invalid_tenant_or_return_url' => 'El tenant o la URL de retorno no son válidos.',
|
||||
'request_expired' => 'La solicitud de autenticación expiró. Intenta nuevamente.',
|
||||
'invalid_return_url' => 'La URL de retorno no es válida.',
|
||||
'oauth_code_expired' => 'El código de autenticación expiró o ya fue utilizado.',
|
||||
'tenant_mismatch' => 'El tenant no coincide con la solicitud de autenticación.',
|
||||
'google_email_required' => 'Google no devolvió un email para la cuenta.',
|
||||
'google_email_unverified' => 'La cuenta de Google debe tener el email verificado.',
|
||||
],
|
||||
'cart' => [
|
||||
'item_added' => 'Producto agregado al carrito.',
|
||||
'quantity_updated' => 'Cantidad de producto actualizada.',
|
||||
'item_removed' => 'Producto eliminado del carrito.',
|
||||
'positive_quantity' => 'La cantidad debe ser mayor a cero.',
|
||||
'insufficient_stock' => 'Stock insuficiente para el producto solicitado. Máximo disponible: :max.',
|
||||
'max_quantity' => 'El máximo que se puede agregar es :max.',
|
||||
'bundle_variant_forbidden' => 'Un bundle no admite una variante.',
|
||||
'empty_bundle' => 'El bundle no tiene componentes.',
|
||||
'variant_required' => 'Debe seleccionar una variante para este ítem.',
|
||||
],
|
||||
'purchase' => [
|
||||
'source_required' => 'Se requiere un carrito o un producto directo.',
|
||||
'payment_method_required' => 'Debes seleccionar el método de pago antes de finalizar la compra.',
|
||||
'not_editable' => 'La compra ya no se puede modificar.',
|
||||
'item_not_editable' => 'El producto de la compra ya no se puede modificar.',
|
||||
'insufficient_stock' => 'No hay suficiente stock disponible.',
|
||||
'cannot_confirm' => 'Una compra cancelada, rechazada o vencida no se puede confirmar.',
|
||||
'inconsistent_reservation' => 'La compra tiene una reserva de stock inconsistente.',
|
||||
'paid_cannot_cancel' => 'Una compra pagada no se puede cancelar.',
|
||||
'direct_item_max_stock' => 'Stock insuficiente. Máximo disponible: :max.',
|
||||
'empty_cart' => 'El carrito seleccionado no contiene productos.',
|
||||
'catalog_item_missing' => 'No se pudieron cargar uno o más productos del catálogo.',
|
||||
'catalog_item_wrong_tenant' => 'Uno o más productos no pertenecen al tenant.',
|
||||
'inactive_cart' => 'El carrito seleccionado ya no está activo.',
|
||||
'not_available_for_payment' => 'La compra ya no está disponible para el pago.',
|
||||
],
|
||||
'ticket' => [
|
||||
'not_available' => 'Uno o más tickets no están disponibles.',
|
||||
'positive_quantity' => 'La cantidad de tickets a generar debe ser mayor a cero.',
|
||||
'empty_bundle' => 'El bundle :bundle no tiene componentes.',
|
||||
'disabled' => 'El producto :product no tiene tickets habilitados.',
|
||||
'expired' => 'El producto :product alcanzó su fecha máxima de uso.',
|
||||
'invalid_variant' => 'La variante :variant no pertenece al producto :product.',
|
||||
'purchase_without_user' => 'La compra :purchase no tiene un usuario asociado.',
|
||||
'product_not_found' => 'No se encontró el producto de la línea de compra :purchase_item.',
|
||||
],
|
||||
'integration' => [
|
||||
'not_configured' => 'La integración no está configurada para este tenant.',
|
||||
'configured' => 'Integración configurada correctamente.',
|
||||
'validation_failed' => 'Error validando la configuración: :error',
|
||||
'invalid_payment_method' => 'Método de pago inválido.',
|
||||
'account_info_failed' => 'No se pudo obtener la información de la cuenta.',
|
||||
'qr_generation_failed' => 'No se pudo generar el código QR.',
|
||||
'webhook_failed' => 'No se pudo procesar el webhook.',
|
||||
],
|
||||
'mail' => [
|
||||
'test_sent' => 'Correo de prueba enviado correctamente.',
|
||||
],
|
||||
'catalog' => [
|
||||
'standard_with_components' => 'Un ítem standard no puede tener componentes.',
|
||||
'duplicate_component' => 'El componente está duplicado.',
|
||||
'component_wrong_tenant' => 'El ítem no pertenece al tenant del bundle.',
|
||||
'invalid_component' => 'El componente debe ser un ítem standard distinto del bundle.',
|
||||
'component_variant_required' => 'Debe seleccionar una variante para este componente.',
|
||||
'component_variant_forbidden' => 'El componente con inventario directo no admite una variante.',
|
||||
'component_variant_invalid' => 'La variante no pertenece al componente indicado.',
|
||||
'bundle_component_required' => 'Un bundle debe tener al menos un componente.',
|
||||
'bundle_field_forbidden' => ':field no se admite para un bundle.',
|
||||
'attachment_not_found' => 'El attachment indicado no existe.',
|
||||
'attribute_not_found' => 'El atributo :attribute no existe para el tenant del ítem.',
|
||||
'managed_inventory_fields' => 'inventory_id, reserved_stock y sold_units son administrados internamente.',
|
||||
'attribute_not_on_item' => 'El atributo no pertenece al ítem de catálogo.',
|
||||
'invalid_effective_date_range' => 'La fecha máxima efectiva debe ser posterior o igual a la fecha mínima efectiva.',
|
||||
'variants_required' => 'Un ítem con attribute_codes debe tener variantes.',
|
||||
'variants_forbidden' => 'Un ítem sin attribute_codes no puede tener variantes.',
|
||||
'direct_inventory_forbidden' => 'Un ítem con variantes no puede tener inventario directo.',
|
||||
],
|
||||
'menu' => [
|
||||
'schema_required' => 'El schema es obligatorio para los menús estáticos.',
|
||||
'not_found' => 'El menú indicado no existe.',
|
||||
],
|
||||
'tenant' => [
|
||||
'invalid_carousel_image' => 'La imagen indicada no existe o no es un attachment de tipo imagen.',
|
||||
],
|
||||
'errors' => [
|
||||
'forbidden' => 'No tienes permiso para realizar esta acción.',
|
||||
'not_found' => 'El recurso solicitado no fue encontrado.',
|
||||
'method_not_allowed' => 'El método HTTP no está permitido para esta ruta.',
|
||||
'request_failed' => 'No se pudo procesar la solicitud.',
|
||||
],
|
||||
];
|
||||
57
lang/es/validation.php
Normal file
57
lang/es/validation.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'after_or_equal' => ':Attribute debe ser una fecha posterior o igual a :date.',
|
||||
'array' => ':Attribute debe ser un arreglo.',
|
||||
'boolean' => 'El campo :attribute debe ser verdadero o falso.',
|
||||
'confirmed' => 'La confirmación de :attribute no coincide.',
|
||||
'date' => ':Attribute no es una fecha válida.',
|
||||
'distinct' => 'El campo :attribute tiene un valor duplicado.',
|
||||
'email' => ':Attribute debe ser una dirección de email válida.',
|
||||
'exists' => 'El valor seleccionado para :attribute no es válido.',
|
||||
'file' => ':Attribute debe ser un archivo.',
|
||||
'integer' => ':Attribute debe ser un número entero.',
|
||||
'max' => [
|
||||
'array' => ':Attribute no debe tener más de :max elementos.',
|
||||
'file' => ':Attribute no debe superar los :max kilobytes.',
|
||||
'numeric' => ':Attribute no debe ser mayor que :max.',
|
||||
'string' => ':Attribute no debe tener más de :max caracteres.',
|
||||
],
|
||||
'min' => [
|
||||
'array' => ':Attribute debe tener al menos :min elementos.',
|
||||
'file' => ':Attribute debe pesar al menos :min kilobytes.',
|
||||
'numeric' => ':Attribute debe ser al menos :min.',
|
||||
'string' => ':Attribute debe tener al menos :min caracteres.',
|
||||
],
|
||||
'numeric' => ':Attribute debe ser un número.',
|
||||
'password' => [
|
||||
'letters' => ':Attribute debe contener al menos una letra.',
|
||||
'mixed' => ':Attribute debe contener al menos una letra mayúscula y una minúscula.',
|
||||
'numbers' => ':Attribute debe contener al menos un número.',
|
||||
'symbols' => ':Attribute debe contener al menos un símbolo.',
|
||||
'uncompromised' => ':Attribute aparece en una filtración de datos. Elige una contraseña diferente.',
|
||||
],
|
||||
'prohibited' => 'El campo :attribute está prohibido.',
|
||||
'regex' => 'El formato de :attribute no es válido.',
|
||||
'required' => 'El campo :attribute es obligatorio.',
|
||||
'required_with' => 'El campo :attribute es obligatorio cuando :values está presente.',
|
||||
'required_without' => 'El campo :attribute es obligatorio cuando :values no está presente.',
|
||||
'string' => ':Attribute debe ser texto.',
|
||||
'unique' => 'El valor de :attribute ya está en uso.',
|
||||
'url' => ':Attribute debe ser una URL válida.',
|
||||
'uuid' => ':Attribute debe ser un UUID válido.',
|
||||
'attributes' => [
|
||||
'cantidad' => 'cantidad',
|
||||
'catalog_item_id' => 'producto',
|
||||
'codigo' => 'código',
|
||||
'dni' => 'DNI',
|
||||
'email' => 'email',
|
||||
'nombre_apellido' => 'nombre y apellido',
|
||||
'oauth_code' => 'código de autenticación',
|
||||
'password' => 'contraseña',
|
||||
'password_confirmation' => 'confirmación de contraseña',
|
||||
'telefono' => 'teléfono',
|
||||
'tenant_codigo' => 'tenant',
|
||||
'variant_id' => 'variante',
|
||||
],
|
||||
];
|
||||
Reference in New Issue
Block a user