### Manual Installation - Configure Autoload Source: https://github.com/michalsn/codeigniter-translatable/blob/develop/docs/installation.md After downloading the project, add the library's namespace to your `app/Config/Autoload.php` file. This example assumes the library is placed in `app/ThirdParty/translatable`. ```php APPPATH, // For custom app namespace 'Michalsn\CodeIgniterTranslatable' => APPPATH . 'ThirdParty/translatable/src', ]; // ... ``` -------------------------------- ### Install via Composer Source: https://github.com/michalsn/codeigniter-translatable/blob/develop/docs/installation.md Run this command in your project's root directory to install the library using Composer. ```bash composer require michalsn/codeigniter-translatable ``` -------------------------------- ### Translation Model Setup Source: https://context7.com/michalsn/codeigniter-translatable/llms.txt Standard CodeIgniter model setup for translation models, without needing a specific trait. ```php initTranslations(ArticleTranslationModel::class); } } ``` -------------------------------- ### List Loaded Translation Keys Source: https://context7.com/michalsn/codeigniter-translatable/llms.txt Get a list of locale codes for which translations have been loaded for an entity using the `getTranslationKeys()` method. ```php $article = model(ArticleModel::class)->withAllTranslations()->find(1); $article->getTranslationKeys(); // ['en', 'pl'] — all supported locales that have data ``` -------------------------------- ### TranslatableEntity Trait Setup Source: https://context7.com/michalsn/codeigniter-translatable/llms.txt Attach the TranslatableEntity trait to your primary entity class to enable translation functionality. Ensure it is not attached to the translation entity itself. ```APIDOC ## `TranslatableEntity` Trait — Entity Setup Attach the trait to the primary entity only (not the translation entity): ```php withAllTranslations()->find(1); // will return: ['en', 'pl'] $article->getTranslationKeys(); ``` -------------------------------- ### Get Translation for Specific Locale Source: https://github.com/michalsn/codeigniter-translatable/blob/develop/docs/entity.md Use the translate() method to retrieve the translated property for a given locale. If no locale is specified, it defaults to the current request locale. ```php $article = model(ArticleModel::class)->withAllTranslations()->find(1); // will return title for "en" locale $article->translate()->title; // will return title for "pl" locale $article->translate('pl')->title; ``` -------------------------------- ### Publish Configuration File Source: https://github.com/michalsn/codeigniter-translatable/blob/develop/docs/configuration.md Run this command to publish the translatable configuration file to app/Config/Translatable.php for customization. ```bash php spark translatable:publish ``` -------------------------------- ### Generate Translatable Model Skeleton Source: https://github.com/michalsn/codeigniter-translatable/blob/develop/docs/configuration.md Use this command to generate the necessary migration, model, and entity files for a translatable resource. Provide the main table name as a parameter. ```bash php spark translatable:generate articles ``` -------------------------------- ### Translatable Configuration Class Source: https://context7.com/michalsn/codeigniter-translatable/llms.txt Configuration class for controlling fallback and empty-fill behavior globally. ```php withAllTranslations() ->find(1); // $article->translations is keyed by locale code: // [ // 'en' => (object)['id'=>'1','title'=>'Sample title 1','content'=>'Sample content 1'], // 'pl' => (object)['id'=>'2','title'=>'Przykładowy tytuł 1','content'=>'Przykładowa treść 1'], // ] echo $article->translate()->title; // current request locale → "Sample title 1" echo $article->translate('pl')->title; // explicit locale → "Przykładowy tytuł 1" ``` -------------------------------- ### Select Data with All Translations Source: https://github.com/michalsn/codeigniter-translatable/blob/develop/docs/basic_usage.md Fetch an article along with all its available translations, allowing access to specific locales. ```php $article = model(ArticleModel::class)->withAllTranslations()->find(1); // will print author echo $article->author; // will print "en" title echo $article->translate()->title; // will print "en" title echo $article->translate('en')->title; // will print "pl" title echo $article->translate('pl')->title; // will print "de" title echo $article->translate('de')->title; ``` -------------------------------- ### Working with Array Results Source: https://context7.com/michalsn/codeigniter-translatable/llms.txt Illustrates the structure of results when using the `asArray()` method, particularly how translations are organized. ```APIDOC ## Working with Array Results ### Description When the `asArray()` method is used, the `translations` key in the result will contain locale-keyed arrays of `stdClass` objects, representing the translations for each locale. ### Method - `asArray()` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```php $article = model(ArticleModel::class) ->asArray() ->withAllTranslations() ->find(1); // Result structure: // [ // 'id' => '1', // 'author' => 'Test User 1', // 'created_at' => '...', // 'updated_at' => '...', // 'translations' => [ // 'en' => (object)['id'=>'1', 'title'=>'Sample title 1', 'content'=>'Sample content 1'], // 'pl' => (object)['id'=>'2', 'title'=>'Przykładowy tytuł 1', 'content'=>'Przykładowa treść 1'], // ], // ] $articles = model(ArticleModel::class) ->asArray() ->withAllTranslations() ->findAll(); foreach ($articles as $row) { echo $row['author']; echo $row['translations']['en']->title; } ``` ### Response #### Success Response (200) Returns results as arrays, with translations nested under the 'translations' key. #### Response Example (See Request Example for context) ``` -------------------------------- ### Select Data for Current Locale Source: https://github.com/michalsn/codeigniter-translatable/blob/develop/docs/basic_usage.md Retrieve an article and access its default translated fields for the current request locale. ```php $article = model(ArticleModel::class)->find(1); // will print author echo $article->author; // will print "en" title echo $article->translate()->title; ``` -------------------------------- ### Define Article Model with Translations Source: https://github.com/michalsn/codeigniter-translatable/blob/develop/docs/basic_usage.md Configure the main model to use the HasTranslations trait and initialize translation models. ```php initTranslations(ArticleTranslationModel::class); } // ... } ``` -------------------------------- ### Load all translations for a model Source: https://github.com/michalsn/codeigniter-translatable/blob/develop/docs/model.md Use `withAllTranslations()` to load all available translations for a model instance. This is useful when you need access to all language versions of a record. ```php model(ArticleModel::class)->withAllTranslations()->find(1); ``` -------------------------------- ### Define Article Translation Model Source: https://github.com/michalsn/codeigniter-translatable/blob/develop/docs/basic_usage.md Set up the model for handling translated content, specifying its table and fields. ```php useFallbackLocale() ->withTranslations(['pl']) ->find(3); echo $article->translate('pl')->title; // "Sample title 3" (fallback from 'en') ``` -------------------------------- ### Query Methods Source: https://github.com/michalsn/codeigniter-translatable/blob/develop/docs/model.md Methods for querying and loading translations for model data. ```APIDOC ## withAllTranslations() ### Description Loads all available translations for the model. ### Method `withAllTranslations()` ### Example ```php model(ArticleModel::class)->withAllTranslations()->find(1); ``` ``` ```APIDOC ## withTranslations() ### Description Loads only the specified translations for the model. ### Method `withTranslations(array $locales)` ### Parameters #### Path Parameters - **locales** (array) - Required - An array of locale codes to load. ### Example ```php model(ArticleModel::class)->withTranslations(['en', 'pl'])->find(1); ``` ``` ```APIDOC ## useFallbackLocale() ### Description Enables fallback locale behavior for the query. If a requested translation is not found, it will fall back to the locale recognized in the request. ### Method `useFallbackLocale()` ### Example ```php // if no "pl" translation is found, it will fall back // to the locale recognized in the request model(ArticleModel::class) ->useFallbackLocale() ->withTranslations(['pl']) ->find(1); ``` ``` ```APIDOC ## setFallbackLocale() ### Description Sets a specific locale to be used as a fallback when a requested translation is not found. ### Method `setFallbackLocale(string $locale)` ### Parameters #### Path Parameters - **locale** (string) - Required - The locale code to use as a fallback. ### Example ```php // if no "pl" translation is found, it will fall back to "en" model(ArticleModel::class) ->setFallbackLocale('en') ->withTranslations(['pl']) ->find(1); ``` ``` ```APIDOC ## useFillOnEmpty() ### Description Configures the query to return an empty object with properties when a translation is not found, instead of null. ### Method `useFillOnEmpty()` ### Example ```php // if no "pl" translation is found, it will fall back to an empty object model(ArticleModel::class) ->useFillOnEmpty() ->withTranslations(['pl']) ->find(1); ``` ``` -------------------------------- ### Insert Record with Translations Source: https://context7.com/michalsn/codeigniter-translatable/llms.txt Insert a new record with translations for multiple locales. Only locales present in `App::$supportedLocales` are persisted. ```php $data = [ 'author' => 'Jane Doe', 'translations' => [ 'en' => [ 'title' => 'My first article', 'content' => 'Hello world!', ], 'pl' => [ 'title' => 'Mój pierwszy artykuł', 'content' => 'Witaj świecie!', ], 'de' => [ // ignored if 'de' is not in supportedLocales 'title' => 'Mein erster Artikel', 'content' => 'Hallo Welt!', ], ], ]; $articleModel = model(ArticleModel::class); $articleModel->insert($data); // Inserts one row in 'articles' and one row per supported locale in 'article_translations' ``` -------------------------------- ### Inserting Records with Translations Source: https://context7.com/michalsn/codeigniter-translatable/llms.txt Explains how to insert new records along with their translations for multiple locales. Only supported locales are persisted. ```APIDOC ## Inserting Records ### `insert()` — create with translations ### Description Inserts a new record into the database, including translations for specified locales. The `translations` key in the data array should be keyed by locale code. Unsupported locales are ignored. ### Method - `insert(array $data)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **author** (string) - The author of the article. - **translations** (array) - An associative array where keys are locale codes (e.g., 'en', 'pl') and values are arrays containing the translated fields ('title', 'content'). ### Request Example ```php $data = [ 'author' => 'Jane Doe', 'translations' => [ 'en' => [ 'title' => 'My first article', 'content' => 'Hello world!', ], 'pl' => [ 'title' => 'Mój pierwszy artykuł', 'content' => 'Witaj świecie!', ], 'de' => [ // ignored if 'de' is not in supportedLocales 'title' => 'Mein erster Artikel', 'content' => 'Hallo Welt!', ], ], ]; $articleModel = model(ArticleModel::class); $articleModel->insert($data); ``` ### Response #### Success Response (200) Inserts one row in the main table and one row per supported locale in the translation table. #### Response Example (See Request Example for context) ``` -------------------------------- ### Fill Missing Translations with useFillOnEmpty() Source: https://context7.com/michalsn/codeigniter-translatable/llms.txt Instead of omitting missing locale keys, `useFillOnEmpty()` inserts an object or array with empty string values for missing translations. ```php $article = model(ArticleModel::class) ->useFillOnEmpty() ->withTranslations(['pl']) ->asArray() ->find(3); // Article 3 has no 'pl' translation // $article['translations']['pl'] is now: // ['id' => null, 'title' => '', 'content' => ''] echo $article['translations']['pl']['title']; // "" ``` -------------------------------- ### Search Methods Source: https://github.com/michalsn/codeigniter-translatable/blob/develop/docs/model.md Methods for searching translated content within models. ```APIDOC ## whereTranslation() ### Description Filters results based on a translated field's value. This method functions similarly to the standard `where()` method but operates on translated content. ### Method `whereTranslation(string $key, mixed $value)` ### Parameters #### Path Parameters - **key** (string) - Required - The translation key (field name) to filter on. - **value** (mixed) - Required - The value to match in the translated field. ### Example ```php model(ArticleModel::class) ->whereTranslation('title', 'Sample 1') ->find(1); ``` ``` ```APIDOC ## orWhereTranslation() ### Description Adds an OR condition to the translation filter. This method functions similarly to the standard `orWhere()` method. ### Method `orWhereTranslation(string $key, mixed $value)` ### Parameters #### Path Parameters - **key** (string) - Required - The translation key (field name) to filter on. - **value** (mixed) - Required - The value to match in the translated field. ### Example ```php model(ArticleModel::class) ->whereTranslation('title', 'Sample 1') ->orWhereTranslation('title', 'Sample 2') ->find(1); ``` ``` ```APIDOC ## whereInTranslation() ### Description Filters results where a translated field's value is within a given array of values. This method functions similarly to the standard `whereIn()` method. ### Method `whereInTranslation(string $key, array $values)` ### Parameters #### Path Parameters - **key** (string) - Required - The translation key (field name) to filter on. - **values** (array) - Required - An array of values to match. ### Example ```php model(ArticleModel::class) ->whereInTranslation('title', ['Sample 1', 'Sample 2']) ->find(1); ``` ``` ```APIDOC ## whereNotInTranslation() ### Description Filters results where a translated field's value is not within a given array of values. This method functions similarly to the standard `whereNotIn()` method. ### Method `whereNotInTranslation(string $key, array $values)` ### Parameters #### Path Parameters - **key** (string) - Required - The translation key (field name) to filter on. - **values** (array) - Required - An array of values to exclude. ### Example ```php model(ArticleModel::class) ->whereNotInTranslation('title', ['Sample 1', 'Sample 2']) ->find(1); ``` ``` ```APIDOC ## likeTranslation() ### Description Filters results based on a partial match in a translated field. This method functions similarly to the standard `like()` method. ### Method `likeTranslation(string $key, string $value, string $direction = 'both')` ### Parameters #### Path Parameters - **key** (string) - Required - The translation key (field name) to filter on. - **value** (string) - Required - The string to search for. - **direction** (string) - Optional - The direction of the like search ('before', 'after', 'both'). Defaults to 'both'. ### Example ```php model(ArticleModel::class) ->likeTranslation('title', 'Sample', 'after') ->find(1); ``` ``` ```APIDOC ## orLikeTranslation() ### Description Adds an OR condition for a partial match in a translated field. This method functions similarly to the standard `orLike()` method. ### Method `orLikeTranslation(string $key, string $value, string $direction = 'both')` ### Parameters #### Path Parameters - **key** (string) - Required - The translation key (field name) to filter on. - **value** (string) - Required - The string to search for. - **direction** (string) - Optional - The direction of the like search ('before', 'after', 'both'). Defaults to 'both'. ### Example ```php model(ArticleModel::class) ->likeTranslation('title', 'Sample 1') ->orLikeTranslation('title', 'Sample 2') ->find(1); ``` ``` ```APIDOC ## notLikeTranslation() ### Description Filters results where a translated field does not match a partial string. This method functions similarly to the standard `notLike()` method. ### Method `notLikeTranslation(string $key, string $value, string $direction = 'both')` ### Parameters #### Path Parameters - **key** (string) - Required - The translation key (field name) to filter on. - **value** (string) - Required - The string to exclude. - **direction** (string) - Optional - The direction of the not like search ('before', 'after', 'both'). Defaults to 'both'. ### Example ```php model(ArticleModel::class) ->notLikeTranslation('title', 'Sample 1') ->find(1); ``` ``` ```APIDOC ## orNotLikeTranslation() ### Description Adds an OR condition where a translated field does not match a partial string. This method functions similarly to the standard `orNotLike()` method. ### Method `orNotLikeTranslation(string $key, string $value, string $direction = 'both')` ### Parameters #### Path Parameters - **key** (string) - Required - The translation key (field name) to filter on. - **value** (string) - Required - The string to exclude. - **direction** (string) - Optional - The direction of the not like search ('before', 'after', 'both'). Defaults to 'both'. ### Example ```php model(ArticleModel::class) ->notLikeTranslation('title', 'Sample 1') ->orNotLikeTranslation('title', 'Sample 2') ->find(1); ``` ``` -------------------------------- ### Translation Search Methods Source: https://context7.com/michalsn/codeigniter-translatable/llms.txt Demonstrates how to use `likeTranslation`, `orLikeTranslation`, `notLikeTranslation`, and `orNotLikeTranslation` for searching translated fields. The `$type` parameter controls the matching behavior ('both', 'before', 'after'). ```APIDOC ## `likeTranslation()` / `orLikeTranslation()` / `notLikeTranslation()` / `orNotLikeTranslation()` ### Description These methods allow for searching within translated fields using LIKE, OR LIKE, NOT LIKE, and OR NOT LIKE conditions. The `$type` parameter accepts 'both' (default), 'before', or 'after' to specify the matching behavior. ### Method - `likeTranslation(string $field, string $term, string $type = 'both')` - `orLikeTranslation(string $field, string $term, string $type = 'both')` - `notLikeTranslation(string $field, string $term, string $type = 'both')` - `orNotLikeTranslation(string $field, string $term, string $type = 'both')` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```php // LIKE search: titles containing '2' OR '3' $articles = model(ArticleModel::class) ->likeTranslation('title', '2') ->orLikeTranslation('title', '3') ->asArray() ->findAll(); // NOT LIKE: exclude specific patterns $articles = model(ArticleModel::class) ->notLikeTranslation('title', '2') ->notLikeTranslation('title', '3') ->asArray() ->findAll(); // 'after' type — title starts with 'Sample' $articles = model(ArticleModel::class) ->likeTranslation('title', 'Sample', 'after') ->findAll(); ``` ### Response #### Success Response (200) Returns an array of model instances or arrays, depending on the result type. #### Response Example (See Request Example for context) ``` -------------------------------- ### Load Specific Locales with withTranslations() Source: https://context7.com/michalsn/codeigniter-translatable/llms.txt Use `withTranslations()` to load only the specified locales. It throws a `TranslatableException` if a requested locale is not in `supportedLocales`. ```php $article = model(ArticleModel::class) ->withTranslations(['en', 'pl']) ->find(1); // Only 'en' and 'pl' keys are present in $article->translations echo $article->translate('en')->title; // "Sample title 1" echo $article->translate('pl')->title; // "Przykładowy tytuł 1" ``` -------------------------------- ### Use empty object for missing translations Source: https://github.com/michalsn/codeigniter-translatable/blob/develop/docs/model.md The `useFillOnEmpty()` method returns an empty object with properties when a translation is not found, instead of null. This can simplify handling missing data. ```php model(ArticleModel::class) ->useFillOnEmpty() ->withTranslations(['pl']) ->find(1); ``` -------------------------------- ### Load specific translations for a model Source: https://github.com/michalsn/codeigniter-translatable/blob/develop/docs/model.md Use `withTranslations()` to load only the translations specified in the array parameter. This is efficient when you only need a subset of languages. ```php model(ArticleModel::class)->withTranslations(['en', 'pl'])->find(1); ``` -------------------------------- ### Inserting / Updating Data Source: https://github.com/michalsn/codeigniter-translatable/blob/develop/docs/model.md Methods for saving translated data. ```APIDOC ## Saving Translated Data ### Description Models can be saved with updated translations. Ensure that the locale keys are listed in `Config\App::supportedLocales`. The structure of the retrieved data can be directly used for saving. ### Method `save(array $data)` ### Parameters #### Request Body - **data** (array) - Required - The model data including the `translations` array with updated values. ### Example ```php $articleModel = model(ArticleModel::class); $article = $articleModel ->asArray() ->withAllTranslations() ->find(1); $article['translations']['en']->title = 'Updated sample'; $articleModel->save($article); ``` ``` -------------------------------- ### getTranslationKeys() Source: https://github.com/michalsn/codeigniter-translatable/blob/develop/docs/entity.md Returns an array of all available translation keys (locales) for the entity. ```APIDOC ## getTranslationKeys() ### Description Returns available translations keys. ### Usage ```php $article = model(ArticleModel::class)->withAllTranslations()->find(1); // will return: ['en', 'pl'] $article->getTranslationKeys(); ``` ``` -------------------------------- ### translate() Source: https://github.com/michalsn/codeigniter-translatable/blob/develop/docs/entity.md Retrieves the translation for a specific locale. Defaults to the current request locale. ```APIDOC ## translate() ### Description By default, will return the translation for the current request locale. ### Usage ```php $article = model(ArticleModel::class)->withAllTranslations()->find(1); // will return title for "en" locale $article->translate()->title; // will return title for "pl" locale $article->translate('pl')->title; ``` ``` -------------------------------- ### Use fallback locale for translations Source: https://github.com/michalsn/codeigniter-translatable/blob/develop/docs/model.md The `useFallbackLocale()` method enables fallback to the `$fallbackLocale` if a requested translation is not found. This can be set globally or per query. ```php model(ArticleModel::class) ->useFallbackLocale() ->withTranslations(['pl']) ->find(1); ``` -------------------------------- ### LIKE Search with Translations Source: https://context7.com/michalsn/codeigniter-translatable/llms.txt Perform LIKE searches on translated fields. The `$type` parameter controls the matching behavior ('both', 'before', 'after'). ```php // LIKE search: titles containing '2' OR '3' $articles = model(ArticleModel::class) ->likeTranslation('title', '2') ->orLikeTranslation('title', '3') ->asArray() ->findAll(); // Returns articles with "Sample title 2" and "Sample title 3" ``` ```php // NOT LIKE: exclude specific patterns $articles = model(ArticleModel::class) ->notLikeTranslation('title', '2') ->notLikeTranslation('title', '3') ->asArray() ->findAll(); // Returns only "Sample title 1" ``` ```php // 'after' type — title starts with 'Sample' $articles = model(ArticleModel::class) ->likeTranslation('title', 'Sample', 'after') ->findAll(); ``` -------------------------------- ### Like search on translated field Source: https://github.com/michalsn/codeigniter-translatable/blob/develop/docs/model.md Use `likeTranslation()` for pattern matching on translated fields. This method functions like the standard `like()` query builder method. ```php model(ArticleModel::class) ->likeTranslation('title', 'Sample', 'after') ->find(1); ``` -------------------------------- ### Entity Translation Access Methods Source: https://context7.com/michalsn/codeigniter-translatable/llms.txt Provides methods for accessing and manipulating translations directly on entity objects. ```APIDOC ## Entity Methods (`TranslatableEntity`) ### `translate(?string $locale = null)` — access a locale's translated object ### Description Retrieves the translation object for a specified locale. If no locale is provided, it defaults to the current request locale. Throws a `TranslatableException` if the requested locale is not supported. ### Method - `translate(?string $locale = null)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```php $article = model(ArticleModel::class)->withAllTranslations()->find(1); // Current request locale (e.g. 'en' from HTTP header) echo $article->translate()->title; // "Sample title 1" // Explicit locale echo $article->translate('pl')->title; // "Przykładowy tytuł 1" // Writable — mutate then save $article->translate()->title = 'New English title'; $article->translate('pl')->title = 'Nowy polski tytuł'; model(ArticleModel::class)->save($article); // Throws TranslatableException for unsupported locale: $article->translate('jp'); // "The "jp" locale is not in the list of supported locales." ``` ### Response #### Success Response (200) Returns the translation object for the specified locale. #### Response Example (See Request Example for context) --- ### `hasTranslation(string $locale)` — check locale availability ### Description Checks if a translation for the given locale has been loaded for the entity. ### Method - `hasTranslation(string $locale)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```php $article = model(ArticleModel::class)->find(1); // loads only current locale $article->hasTranslation('en'); // true — translation was loaded $article->hasTranslation('pl'); // false — 'pl' was not requested/loaded ``` ### Response #### Success Response (200) Returns `true` if the translation is loaded, `false` otherwise. #### Response Example (See Request Example for context) --- ### `getTranslationKeys()` — list loaded locale codes ### Description Returns an array of locale codes for which translations are currently loaded for the entity. ### Method - `getTranslationKeys()` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```php $article = model(ArticleModel::class)->withAllTranslations()->find(1); $article->getTranslationKeys(); // ['en', 'pl'] — all supported locales that have data ``` ### Response #### Success Response (200) Returns an array of loaded locale codes. #### Response Example (See Request Example for context) ``` -------------------------------- ### Update Record with Translations (Array Style) Source: https://context7.com/michalsn/codeigniter-translatable/llms.txt Update an existing record and its translations using an array-based data structure. Existing translation rows are updated, missing ones are inserted. ```php $articleModel = model(ArticleModel::class); // Array style $article = $articleModel->asArray()->withAllTranslations()->find(1); $article['translations']['en']->title = 'Updated English title'; $article['translations']['pl']->content = 'Zaktualizowana treść'; $articleModel->save($article); ``` -------------------------------- ### Primary Table Schema Source: https://context7.com/michalsn/codeigniter-translatable/llms.txt Schema for the primary table storing non-translatable columns. ```sql -- Primary table (non-translatable columns only) CREATE TABLE articles ( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, author VARCHAR(255), created_at DATETIME, updated_at DATETIME ); ``` -------------------------------- ### Query Methods for Translations Source: https://context7.com/michalsn/codeigniter-translatable/llms.txt These methods allow you to load and query entities with their translations. They can be chained with standard CodeIgniter query builder methods. ```APIDOC ## Query Methods (`HasTranslations`) ### `withAllTranslations()` — load every supported locale Loads translations for all locales listed in `App::$supportedLocales`. ```php $article = model(ArticleModel::class) ->withAllTranslations() ->find(1); // $article->translations is keyed by locale code: // [ // 'en' => (object)['id'=>'1','title'=>'Sample title 1','content'=>'Sample content 1'], // 'pl' => (object)['id'=>'2','title'=>'Przykładowy tytuł 1','content'=>'Przykładowa treść 1'], // ] echo $article->translate()->title; // current request locale → "Sample title 1" echo $article->translate('pl')->title; // explicit locale → "Przykładowy tytuł 1" ``` --- ### `withTranslations(array $locales)` — load specific locales only Loads only the listed locales. Throws `TranslatableException` if a locale is not in `supportedLocales`. ```php $article = model(ArticleModel::class) ->withTranslations(['en', 'pl']) ->find(1); // Only 'en' and 'pl' keys are present in $article->translations echo $article->translate('en')->title; // "Sample title 1" echo $article->translate('pl')->title; // "Przykładowy tytuł 1" ``` --- ### `useFallbackLocale(bool $fallback = true)` — per-query fallback toggle When a translation for the requested locale is missing, falls back to `$fallbackLocale` (defaults to `App::$defaultLocale`). ```php // Article 3 has only an 'en' translation; requesting 'pl' falls back to 'en' $article = model(ArticleModel::class) ->useFallbackLocale() ->withTranslations(['pl']) ->find(3); echo $article->translate('pl')->title; // "Sample title 3" (fallback from 'en') ``` --- ### `setFallbackLocale(string $locale)` — per-query explicit fallback locale Sets a specific fallback locale for one query and implicitly enables fallback. Throws `TranslatableException` for unsupported locales. ```php // If 'pl' is missing, fall back to 'en' explicitly $article = model(ArticleModel::class) ->setFallbackLocale('en') ->withTranslations(['pl']) ->find(3); echo $article->translate('pl')->title; // "Sample title 3" (fell back to 'en') // Throws TranslatableException: model(ArticleModel::class)->setFallbackLocale('jp')->find(1); // "The "jp" locale is not in the list of supported locales." ``` --- ### `useFillOnEmpty(bool $fill = true)` — return empty object when translation missing Instead of omitting a missing locale key entirely, inserts an object/array with empty string values. ```php $article = model(ArticleModel::class) ->useFillOnEmpty() ->withTranslations(['pl']) ->asArray() ->find(3); // Article 3 has no 'pl' translation // $article['translations']['pl'] is now: // ['id' => null, 'title' => '', 'content' => ''] echo $article['translations']['pl']['title']; // "" ``` --- ## Search Methods (`HasTranslations`) All search methods join the translations table and add a `DISTINCT` select automatically. They can be chained freely with each other and with standard CodeIgniter query builder methods. ### `whereTranslation()` / `orWhereTranslation()` ```php // Exact match on a translated field $articles = model(ArticleModel::class) ->whereTranslation('title', 'Sample title 1') ->orWhereTranslation('content', 'Przykładowa treść 2') ->asArray() ->findAll(); // Returns all records whose 'title' is 'Sample title 1' // OR whose 'content' is 'Przykładowa treść 2' in any loaded locale ``` --- ### `whereInTranslation()` / `whereNotInTranslation()` ```php // IN / NOT IN on translated fields $articles = model(ArticleModel::class) ->whereInTranslation('title', ['Sample title 1', 'Sample title 2']) ->asArray() ->findAll(); $others = model(ArticleModel::class) ->whereNotInTranslation('title', ['Sample title 2']) ->asArray() ->findAll(); ``` --- ``` -------------------------------- ### Working with Result Data Source: https://github.com/michalsn/codeigniter-translatable/blob/develop/docs/model.md Accessing and manipulating translated data after retrieval. ```APIDOC ## Accessing Translations ### Description Translated content is available via the `translations` property or array key on the retrieved model data. ### Example ```php $article = model(ArticleModel::class) ->asArray() ->withAllTranslations() ->find(1); // $article['translations'] will contain an array of translations keyed by locale. // Example structure: // [ // 'en' => (object) [ // 'title' => 'Sample 1', // 'content' => 'Content 1', // ], // 'pl' => (object) [ // 'title' => 'Przykład 1', // 'content' => 'Treść 1', // ], // ] ``` ``` -------------------------------- ### Set fallback locale for translations Source: https://github.com/michalsn/codeigniter-translatable/blob/develop/docs/model.md Manually set the fallback locale using `setFallbackLocale()` for queries where the primary translation is missing. This ensures a default language is used. ```php model(ArticleModel::class) ->setFallbackLocale('en') ->withTranslations(['pl']) ->find(1); ``` -------------------------------- ### Updating model data with translations Source: https://github.com/michalsn/codeigniter-translatable/blob/develop/docs/model.md You can update or insert model data, including translations, by modifying the returned structure and using the `save()` method. Ensure locales are listed in `Config\App::supportedLocales`. ```php $articleModel = model(ArticleModel::class); $article = $articleModel ->asArray() ->withAllTranslations() ->find(1); $article['translations']['en']->title = 'Updated sample'; $articleModel->save($article); ``` -------------------------------- ### Define Translatable Entity Source: https://github.com/michalsn/codeigniter-translatable/blob/develop/docs/basic_usage.md Implement the TranslatableEntity trait in your main model's entity for easier translation management. ```php find(1); // loads only current locale $article->hasTranslation('en'); // true — translation was loaded $article->hasTranslation('pl'); // false — 'pl' was not requested/loaded ``` -------------------------------- ### Accessing and structuring translated data Source: https://github.com/michalsn/codeigniter-translatable/blob/develop/docs/model.md Translated content is accessible via the `translations` property or array key. The structure includes language codes as keys, with translation objects as values. ```php $article = model(ArticleModel::class) ->asArray() ->withAllTranslations() ->find(1); // will return: [ 'id' => '1', 'author' => 'Sample user 1', 'created_at' => '...', 'updated_at' => '...', 'translations' => [ 'en' => (object) [ 'title' => 'Sample 1', 'content' => 'Content 1', ], 'pl' => (object) [ 'title' => 'Przykład 1', 'content' => 'Treść 1', ], ] ]; ``` -------------------------------- ### Working with Array Results and Translations Source: https://context7.com/michalsn/codeigniter-translatable/llms.txt Access translated content when results are returned as arrays. The `translations` key contains locale-keyed `stdClass` objects. ```php $article = model(ArticleModel::class) ->asArray() ->withAllTranslations() ->find(1); // Result structure: // [ // 'id' => '1', // 'author' => 'Test User 1', // 'created_at' => '...', // 'updated_at' => '...', // 'translations' => [ // 'en' => (object)['id'=>'1', 'title'=>'Sample title 1', 'content'=>'Sample content 1'], // 'pl' => (object)['id'=>'2', 'title'=>'Przykładowy tytuł 1', 'content'=>'Przykładowa treść 1'], // ], // ] $articles = model(ArticleModel::class) ->asArray() ->withAllTranslations() ->findAll(); foreach ($articles as $row) { echo $row['author']; echo $row['translations']['en']->title; } ``` -------------------------------- ### Update Record with Translations (Entity Style) Source: https://context7.com/michalsn/codeigniter-translatable/llms.txt Update an existing record and its translations using an entity object. Requires the `TranslatableEntity` trait on the entity. Existing translation rows are updated, missing ones are inserted. ```php // Entity style (requires TranslatableEntity trait on the entity) /** @var Article $article */ $article = $articleModel->withAllTranslations()->find(1); $article->translate()->title = 'Updated English title'; $article->translate('pl')->title = 'Zaktualizowany tytuł'; $articleModel->save($article); ``` -------------------------------- ### Translations Table Schema Source: https://context7.com/michalsn/codeigniter-translatable/llms.txt Schema for the translations table, storing locale-specific content. ```sql -- Translations table (one row per locale per record) CREATE TABLE article_translations ( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, article_id INT UNSIGNED NOT NULL, locale VARCHAR(10) NOT NULL, title VARCHAR(255), content TEXT ); ``` -------------------------------- ### Updating Records with Translations Source: https://context7.com/michalsn/codeigniter-translatable/llms.txt Details how to update existing records and their translations. If a translation row exists, it's updated; otherwise, it's inserted. ```APIDOC ## Updating Records ### `update()` / `save()` — update with translations ### Description Updates an existing record and its translations. If a translation for a given locale already exists, it will be updated. If it does not exist, it will be inserted automatically. This method can be used with both array and entity styles. ### Method - `update(int|array $id, array $data)` - `save(array $data)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **data** (array) - An associative array representing the record to update. For entities, this is the entity object itself. The `translations` key should contain locale-keyed translation data. ### Request Example ```php $articleModel = model(ArticleModel::class); // Array style $article = $articleModel->asArray()->withAllTranslations()->find(1); $article['translations']['en']->title = 'Updated English title'; $article['translations']['pl']->content = 'Zaktualizowana treść'; $articleModel->save($article); // Entity style (requires TranslatableEntity trait on the entity) /** @var Article $article */ $article = $articleModel->withAllTranslations()->find(1); $article->translate()->title = 'Updated English title'; $article->translate('pl')->title = 'Zaktualizowany tytuł'; $articleModel->save($article); ``` ### Response #### Success Response (200) Updates the existing record and its translations. Inserts new translations if they don't exist. #### Response Example (See Request Example for context) ``` -------------------------------- ### hasTranslation() Source: https://github.com/michalsn/codeigniter-translatable/blob/develop/docs/entity.md Checks if a translation exists for a given locale. ```APIDOC ## hasTranslation() ### Description Checks if given locale is available. ### Usage ```php $article = model(ArticleModel::class)->withAllTranslations()->find(1); // will return: true $article->hasTranslation('en'); ``` ``` -------------------------------- ### Filter by Translated Field with whereTranslation() Source: https://context7.com/michalsn/codeigniter-translatable/llms.txt Use `whereTranslation()` and `orWhereTranslation()` for exact matches on translated fields across any loaded locale. These methods automatically join the translations table and add `DISTINCT`. ```php // Exact match on a translated field $articles = model(ArticleModel::class) ->whereTranslation('title', 'Sample title 1') ->orWhereTranslation('content', 'Przykładowa treść 2') ->asArray() ->findAll(); // Returns all records whose 'title' is 'Sample title 1' // OR whose 'content' is 'Przykładowa treść 2' in any loaded locale ``` -------------------------------- ### Attach TranslatableEntity Trait to Primary Entity Source: https://context7.com/michalsn/codeigniter-translatable/llms.txt Attach the TranslatableEntity trait to your primary entity class. Do not attach it to the translation entity itself. ```php withAllTranslations()->find(1); // will return: true $article->hasTranslation('en'); ```