# Global Language System

This document explains the implementation and usage of the global language system that automatically sets user language based on their access token and program configuration.

## Overview

The global language system eliminates the need to manually set language in every API method by automatically determining and setting the user's language based on their program configuration when they make authenticated requests.

## Components

### 1. LanguageService (`app/Services/LanguageService.php`)

Central service for language-related operations:

```php
// Get user's language based on their program
$language = $languageService->getUserLanguage($userId);

// Set application locale
$languageService->setLocale($language);

// Get current locale
$currentLocale = $languageService->getCurrentLocale();
```

### 2. SetUserLanguageMiddleware (`app/Http/Middleware/SetUserLanguageMiddleware.php`)

Middleware that automatically:
- Runs after authentication middleware
- Fetches user's program language
- Sets application locale globally
- Stores language in request attributes for easy access

### 3. HasUserLanguage Trait (`app/Traits/HasUserLanguage.php`)

Helper trait for controllers to easily access user language:

```php
use App\Traits\HasUserLanguage;

class YourController extends Controller
{
    use HasUserLanguage;
    
    public function someMethod(Request $request)
    {
        $userLanguage = $this->getUserLanguage($request);
        $currentLocale = $this->getCurrentLocale();
    }
}
```

## How It Works

1. **Authentication**: User makes API request with valid access token
2. **ApiAuthMiddleware**: Validates token and adds userId to request attributes
3. **SetUserLanguageMiddleware**: 
   - Gets userId from request attributes
   - Fetches user's program language via LanguageService
   - Sets application locale globally
   - Stores language in request attributes
4. **Controller/Service**: Language is already set, no manual intervention needed

## Configuration

### Middleware Registration

The middleware is registered in `app/Http/Kernel.php`:

```php
protected $routeMiddleware = [
    // ... other middleware
    'user.language' => \App\Http\Middleware\SetUserLanguageMiddleware::class,
];
```

### Route Configuration

Applied to authenticated routes in `routes/api.php`:

```php
Route::middleware(['api.auth', 'user.language'])->prefix('User')->group(function () {
    // Your authenticated routes here
});
```

## Language Determination Logic

1. **User Program**: Language is determined by user's `iProgramID`
2. **Program Language**: Fetched from `tbl_Programs.vLanguage` field
3. **Fallback**: Defaults to 'eng' if:
   - User has no program (iProgramID <= 0)
   - Program has no language set
   - Any error occurs during language fetching

## Benefits

### Before (Manual Language Setting)
```php
// In every service method
$language = "eng";
if ($user->iProgramID > 0) {
    $programLanguage = $this->programQuery->getProgramLanguage($user->iProgramID);
    $language = $programLanguage ? strtolower($programLanguage) : "eng";
}
app('translator')->setLocale($language);
```

### After (Automatic Global Setting)
```php
// Language is already set automatically
// Just use trans() functions directly
return trans('form_lang.recordSaveSuccess');
```

## Usage Examples

### In Controllers
```php
use App\Traits\HasUserLanguage;

class UserController extends Controller
{
    use HasUserLanguage;
    
    public function profile(Request $request)
    {
        // Language is already set by middleware
        $message = trans('form_lang.profileLoaded');
        
        // Optional: Get language info if needed
        $userLanguage = $this->getUserLanguage($request);
        
        return response()->json([
            'message' => $message,
            'language' => $userLanguage
        ]);
    }
}
```

### In Services
```php
class SomeService
{
    public function someMethod()
    {
        // Language is already set globally
        $successMessage = trans('form_lang.operationSuccess');
        $errorMessage = trans('form_lang.operationFailed');
        
        // Use translations directly without manual language setting
        return [
            'success' => $successMessage,
            'error' => $errorMessage
        ];
    }
}
```

## Error Handling

The middleware includes comprehensive error handling:

- **Database Errors**: Falls back to 'eng' if user lookup fails
- **Missing Program**: Uses 'eng' for users without programs
- **Invalid Program**: Uses 'eng' if program language is null/empty
- **Logging**: All errors are logged for debugging

## Performance Considerations

- **Single Query**: Language is fetched once per request, not per method
- **Caching**: Consider implementing caching for frequently accessed user languages
- **Minimal Overhead**: Middleware adds minimal processing time to requests

## Migration from Old System

### Step 1: Remove Manual Language Setting
Remove these patterns from your services:
```php
// Remove these lines
$language = $this->programQuery->getProgramLanguage($user->iProgramID);
$language = $language ? strtolower($language) : "eng";
app('translator')->setLocale($language);
```

### Step 2: Apply Middleware to Routes
Ensure your authenticated routes use both middlewares:
```php
Route::middleware(['api.auth', 'user.language'])->group(function () {
    // Your routes
});
```

### Step 3: Use Trait in Controllers (Optional)
Add the trait to controllers that need language info:
```php
use App\Traits\HasUserLanguage;
```

## Testing

### Test Language Setting
```php
// Test that language is set correctly for different users
$response = $this->withHeaders([
    'accesstoken' => $userToken,
    'userid' => $userId
])->get('/api/User/Profile/' . $userId);

// Verify response uses correct language
$this->assertEquals('expected_translated_message', $response->json('message'));
```

### Test Fallback Behavior
```php
// Test with user having no program
// Should fall back to 'eng'
```

## Troubleshooting

### Common Issues

1. **Language Not Set**: Ensure middleware is applied to route
2. **Wrong Language**: Check user's program language configuration
3. **Fallback to English**: Check logs for errors in language fetching

### Debug Information

The middleware logs language setting for each request:
```
User language set: userId=123, language=spa
```

Check application logs for debugging language-related issues.

## Future Enhancements

1. **Caching**: Implement Redis/Memcached for user language caching
2. **User Preferences**: Allow users to override program language
3. **Header Override**: Support language override via request headers
4. **Locale Fallback Chain**: Implement fallback chain (user -> program -> default)
