PHP code example of alex-no / field-lingo

1. Go to this page and download the library: Download alex-no/field-lingo library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

alex-no / field-lingo example snippets


'params' => [
    'LingoActive' => [
        // Global defaults for adapters
        \FieldLingo\Adapters\Yii2\LingoActiveRecord::class => [
            'localizedPrefixes' => '@@',   // or ['@@', '##']
            'isStrict' => true,            // throw on missing localized attribute
            'defaultLanguage' => 'en',     // fallback language code
        ],
        \FieldLingo\Adapters\Yii2\LingoActiveQuery::class => [
            'localizedPrefixes' => '@@',
        ],
        // Optional per-model override example:
        // \app\models\PetType::class => [
        //     'localizedPrefixes' => '##',
        //     'isStrict' => false,
        //     'defaultLanguage' => 'uk',
        // ],
    ],
],

use FieldLingo\Adapters\Yii3\LingoActiveRecord;
use FieldLingo\Adapters\Yii3\LingoActiveQuery;

class Post extends LingoActiveRecord
{
    public static function tableName(): string
    {
        return '{{%post}}';
    }

    /**
     * IMPORTANT: Override find() to return LingoActiveQuery
     */
    public static function find(): LingoActiveQuery
    {
        return new LingoActiveQuery(static::class);
    }
}

// Create
$post = new Post();
$post->setLocale('uk');  // Set current locale
$post->setAttribute('@@title', 'Новина дня');
$post->setAttribute('@@content', 'Текст новини');
$post->save();

// Read
$post->setLocale('en');
echo $post->getAttribute('@@title');

// Query
$posts = Post::find()
    ->setLocale('uk')
    ->select(['id', '@@title', '@@content'])
    ->where(['like', '@@title', 'Новини'])
    ->orderBy(['@@title' => SORT_ASC])
    ->all();

// Query with pagination
$posts = Post::find()
    ->setLocale('uk')
    ->select(['id', '@@title', '@@content'])
    ->where(['like', '@@title', 'Новини'])
    ->orderBy(['@@title' => SORT_ASC])
    ->limit(10)
    ->offset(20)
    ->all();

// Count records
$count = Post::find()
    ->setLocale('uk')
    ->where(['like', '@@title', 'Новини'])
    ->count();

use Yiisoft\ActiveRecord\ActiveRecord;

// In your DI container
$container->set(\PDO::class, function() {
    $dsn = "mysql:host=localhost;dbname=mydb;charset=utf8mb4";
    return new \PDO($dsn, 'username', 'password');
});

// Set in your models
ActiveRecord::setDb($container->get(\PDO::class));

use Yiisoft\Translator\TranslatorInterface;

// In your DI container configuration
$container->set(Post::class, function ($container) {
    $post = new Post();
    $post->setTranslator($container->get(TranslatorInterface::class));
    return $post;
});

// Now locale is automatically taken from translator
$post = $container->get(Post::class);
echo $post->getAttribute('@@title'); // Uses translator's current locale

class Post extends LingoActiveRecord
{
    public function getCategory(): ActiveQueryInterface
    {
        return $this->hasOne(Category::class, ['id' => 'category_id']);
    }

    public function getComments(): ActiveQueryInterface
    {
        return $this->hasMany(Comment::class, ['post_id' => 'id']);
    }
}

// Usage
$post = Post::findOne(1);
$post->setLocale('uk');
echo $post->category->getAttribute('@@name');  // Localized category name

$comments = $post->comments;

use FieldLingo\Adapters\Laravel\LingoModel;

class Product extends LingoModel
{
    protected $table = 'products';

    protected $fillable = ['name_en', 'name_uk', 'description_en', 'description_uk', 'price'];
}

// Create
$product = new Product();
$product->setAttribute('@@name', 'Laptop');
$product->setAttribute('@@description', 'High-performance laptop');
$product->save();

// Read
echo $product->getAttribute('@@name');

// Query
$products = Product::where('@@name', 'LIKE', '%Laptop%')
    ->orderBy('@@name', 'asc')
    ->get();

use FieldLingo\Adapters\Symfony\LingoEntity;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity(repositoryClass: ProductRepository::class)]
class Product extends LingoEntity
{
    #[ORM\Column(type: 'string')]
    private ?string $name_en = null;

    #[ORM\Column(type: 'string', nullable: true)]
    private ?string $name_uk = null;

    // Getters and setters...
}

use FieldLingo\Adapters\Symfony\LingoRepository;

class ProductRepository extends LingoRepository
{
    public function findByName(string $name, string $locale = 'en'): array
    {
        return $this->setLocale($locale)
            ->createQueryBuilder('p')
            ->where('p.@@name LIKE :name')
            ->setParameter('name', '%' . $name . '%')
            ->getQuery()
            ->getResult();
    }
}

$product = new Product();
$product->setCurrentLocale($request->getLocale());
$product->{'@@name'} = 'Laptop';
$product->{'@@description'} = 'High-performance laptop';

$entityManager->persist($product);
$entityManager->flush();

use FieldLingo\Adapters\Yii2\LingoActiveRecord;

/**
 * Example Post model
 * Table columns: id, title_en, title_uk, title_ru, content_en, content_uk, content_ru, created_at
 */
class Post extends LingoActiveRecord
{
    public static function tableName()
    {
        return 'post';
    }

    public function rules()
    {
        return [
            [['title_en', 'title_uk'], 's content_uk value

// ===== Creating and saving records =====
$post = new Post();
$post->setAttribute('@@title', 'Новина дня');  // Sets title_uk
$post->setAttribute('@@content', 'Текст новини');  // Sets content_uk
$post->save();

// ===== Property-style access =====
echo $post->{'@@title'};  // Same as getAttribute('@@title')

// ===== Array export with localized fields =====
$data = $post->toArray(['id', '@@title', '@@content', 'created_at']);
// Result: ['id' => 1, 'title_uk' => 'Новина дня', 'content_uk' => 'Текст новини', 'created_at' => '...']

use FieldLingo\Adapters\Yii2\LingoActiveRecord;
use FieldLingo\Adapters\Yii2\LingoActiveQuery;

class Post extends LingoActiveRecord
{
    public static function tableName()
    {
        return 'post';
    }

    /**
     * IMPORTANT: Override find() to return LingoActiveQuery
     * @return LingoActiveQuery
     */
    public static function find()
    {
        return new LingoActiveQuery(get_called_class());
    }
}

// ===== Simple select =====
// Assuming Yii::$app->language = 'en'
$posts = Post::find()
    ->select(['id', '@@title', '@@content'])  // Selects: id, title_en, content_en
    ->all();

// ===== Where conditions =====
$posts = Post::find()
    ->where(['@@title' => 'Hello World'])  // WHERE title_en = 'Hello World'
    ->all();

$posts = Post::find()
    ->where(['like', '@@title', 'News'])  // WHERE title_en LIKE '%News%'
    ->all();

// ===== Order by localized field =====
$posts = Post::find()
    ->orderBy(['@@title' => SORT_ASC])  // ORDER BY title_en ASC
    ->all();

// ===== Complex query example =====
$posts = Post::find()
    ->select(['id', '@@title', '@@content'])
    ->where(['like', '@@title', 'News'])
    ->andWhere(['>', 'created_at', '2024-01-01'])
    ->orderBy(['@@title' => SORT_DESC])
    ->limit(10)
    ->all();

// ===== Group by localized field =====
$stats = Post::find()
    ->select(['@@category', 'COUNT(*) as count'])
    ->groupBy(['@@category'])  // GROUP BY category_en
    ->asArray()
    ->all();

// ===== FilterWhere with dynamic params =====
$posts = Post::find()
    ->filterWhere([
        '@@title' => $_GET['title'] ?? null,  // Only adds to WHERE if title is provided
        '@@category' => $_GET['category'] ?? null,
    ])
    ->all();

use FieldLingo\Adapters\Yii2\LingoActiveDataProvider;

$dataProvider = new LingoActiveDataProvider([
    'query' => Post::find(),
    'pagination' => [
        'pageSize' => 20,
    ],
    'sort' => [
        'attributes' => [
            'id',
            '@@title',    // Enables sorting by title_{lang}
            '@@category', // Enables sorting by category_{lang}
            'created_at',
        ],
    ],
]);

use yii\grid\GridView;

echo GridView::widget([
    'dataProvider' => $dataProvider,
    'columns' => [
        'id',
        [
            'attribute' => '@@title',
            'label' => 'Title',
            'value' => function ($model) {
                return $model->getAttribute('@@title');
            },
        ],
        [
            'attribute' => '@@category',
            'label' => 'Category',
            'filter' => ['news' => 'News', 'blog' => 'Blog'],
            'value' => function ($model) {
                return $model->getAttribute('@@category');
            },
        ],
        'created_at:datetime',
        ['class' => 'yii\grid\ActionColumn'],
    ],
]);

$dataProvider = new LingoActiveDataProvider([
    'query' => Post::find()->where(['status' => 'published']),
    'sort' => [
        'attributes' => [
            '@@title' => [
                'asc' => ['@@title' => SORT_ASC],
                'desc' => ['@@title' => SORT_DESC],
                'default' => SORT_ASC,
                'label' => 'Title',
            ],
        ],
        'defaultOrder' => [
            '@@title' => SORT_ASC,
        ],
    ],
]);

'LingoActive' => [
    \FieldLingo\Adapters\Yii2\LingoActiveRecord::class => [
        'isStrict' => true,        // Throw exception on missing localized column
        'defaultLanguage' => 'en',
    ],
],

'LingoActive' => [
    \FieldLingo\Adapters\Yii2\LingoActiveRecord::class => [
        'isStrict' => false,       // Use fallback language
        'defaultLanguage' => 'en', // Fallback to English
    ],
],

// Database table has: id, title_en, title_uk (no title_ru)
// Config: isStrict = false, defaultLanguage = 'en'

// When Yii::$app->language = 'en'
$post->getAttribute('@@title');  // Returns title_en ✅

// When Yii::$app->language = 'uk'
$post->getAttribute('@@title');  // Returns title_uk ✅

// When Yii::$app->language = 'ru'
$post->getAttribute('@@title');  // Returns title_en (fallback) ✅

// --- With isStrict = true ---
// When Yii::$app->language = 'ru'
$post->getAttribute('@@title');  // Throws MissingLocalizedAttributeException 🚫

'LingoActive' => [
    // Global strict mode
    \FieldLingo\Adapters\Yii2\LingoActiveRecord::class => [
        'isStrict' => true,
        'defaultLanguage' => 'en',
    ],

    // But allow fallback for Product model
    \app\models\Product::class => [
        'isStrict' => false,
        'defaultLanguage' => 'uk',  // Fallback to Ukrainian for products
    ],
],

// config/params.php
return [
    'LingoActive' => [
        \FieldLingo\Adapters\Yii2\LingoActiveRecord::class => [
            'localizedPrefixes' => '@@',
            'isStrict' => false,       // Use fallback during migration
            'defaultLanguage' => 'en',
        ],
        \FieldLingo\Adapters\Yii2\LingoActiveQuery::class => [
            'localizedPrefixes' => '@@',
        ],
    ],
    // ... other params
];

use yii\db\ActiveRecord;

class Post extends ActiveRecord
{
    public static function tableName()
    {
        return 'post';
    }
}

use FieldLingo\Adapters\Yii2\LingoActiveRecord;
use FieldLingo\Adapters\Yii2\LingoActiveQuery;

class Post extends LingoActiveRecord  // Changed parent class
{
    public static function tableName()
    {
        return 'post';
    }

    /**
     * Override find() to use LingoActiveQuery
     */
    public static function find()
    {
        return new LingoActiveQuery(get_called_class());
    }
}

// Controller
$post = Post::findOne($id);
$post->title = 'New Title';
$post->save();

// View
echo $post->title;

// Controller
$post = Post::findOne($id);
$post->setAttribute('@@title', 'New Title');  // Sets title_en or title_uk
$post->save();

// View
echo $post->getAttribute('@@title');  // Gets title_en or title_uk

use yii\data\ActiveDataProvider;

$dataProvider = new ActiveDataProvider([
    'query' => Post::find(),
]);

use FieldLingo\Adapters\Yii2\LingoActiveDataProvider;

$dataProvider = new LingoActiveDataProvider([
    'query' => Post::find(),
    'sort' => [
        'attributes' => ['id', '@@title', '@@category', 'created_at'],
    ],
]);

echo GridView::widget([
    'dataProvider' => $dataProvider,
    'columns' => [
        'id',
        'title',
        'created_at:datetime',
    ],
]);

echo GridView::widget([
    'dataProvider' => $dataProvider,
    'columns' => [
        'id',
        [
            'attribute' => '@@title',
            'value' => function($model) {
                return $model->getAttribute('@@title');
            },
        ],
        'created_at:datetime',
    ],
]);

// Test 1: Check attribute access
$post = Post::findOne(1);
var_dump($post->getAttribute('@@title'));

// Test 2: Check query conversion
$query = Post::find()->select(['@@title'])->where(['@@title' => 'Test']);
echo $query->createCommand()->getRawSql();

// Test 3: Check GridView sorting
// Click on column headers in GridView to test sorting

// Test 4: Test fallback (if using isStrict = false)
Yii::$app->language = 'ru';  // Language without columns
echo $post->getAttribute('@@title');  // Should return fallback language

'LingoActive' => [
    // Global defaults
    \FieldLingo\Adapters\Yii2\LingoActiveRecord::class => [
        'isStrict' => false,
        'defaultLanguage' => 'en',
    ],

    // Already migrated models (strict mode)
    \app\models\Post::class => [
        'isStrict' => true,
    ],

    // Still migrating (very permissive)
    \app\models\Category::class => [
        'isStrict' => false,
        'defaultLanguage' => 'uk',
    ],
],

public static function find()
{
    return new LingoActiveQuery(get_called_class());
}

use FieldLingo\Adapters\Yii2\LingoActiveQuery;

use FieldLingo\Adapters\Yii2\LingoActiveDataProvider;

$dataProvider = new LingoActiveDataProvider([
    'query' => Post::find(),
]);

'sort' => [
    'attributes' => ['id', '@@title', '@@category'],
],

// 1. Check current language
echo Yii::$app->language; // e.g., "uk" or "en-US"

// 2. Check config
print_r(Yii::$app->params['LingoActive']);

// 3. Test attribute resolution
$post = Post::findOne(1);
echo $post->getAttribute('@@title'); // Should return title_uk or title_en

// 4. Check what column was actually used
$query = Post::find()->select(['@@title']);
echo $query->createCommand()->getRawSql();
// Should show: SELECT `title_uk` FROM `post` or similar

'LingoActive' => [
    \FieldLingo\Adapters\Yii2\LingoActiveRecord::class => [
        'isStrict' => false,  // Enable fallback to defaultLanguage
        'defaultLanguage' => 'en',
    ],
],

'localizedPrefixes' => ['@@', '##'],

Yii::$app->language = 'en';
echo $post->getAttribute('@@title'); // Returns title_en

Yii::$app->language = 'uk';
echo $post->getAttribute('@@title'); // Returns title_uk

$post = Post::find()->with('category')->one();
echo $post->category->getAttribute('@@name'); // Works!

public function rules()
{
    return [
        [['title_en', 'title_uk'], '

<?= $form->field($model, 'title_' . Yii::$app->language)->textInput()