Product keyword search in ProductsModel::getListQuery() currently checks only the original Joomla content fields (a.title, a.introtext) together with the product SKU and UPC.
As a result, products cannot be found using titles or descriptions translated by Falang. For example, a product whose original title contains “srebro” but whose English translation contains “silver” cannot be found by searching for “silver”.
Would it be possible to add either:
-
Optional Falang support controlled through the J2Commerce configuration, or
-
An event allowing plugins to extend the product keyword search condition?
An extension event would keep J2Commerce completely independent from Falang. However, direct optional support could also be implemented safely and remain disabled by default.
The integration should search only the currently active language, not every available translation.
Suggested behaviour-
Falang search is disabled by default.
-
Existing J2Commerce search behaviour remains unchanged when disabled.
-
When enabled, the search checks the original product content and the active Falang translation.
-
Only translated
titleandintrotextfields are searched. -
If Falang is unavailable, J2Commerce falls back to its native search without an error.
-
The same behaviour applies to normal product lists and tag-based product lists.
1. Add a configuration option
File:
administrator/components/com_j2commerce/config.xml
Add the field to the appropriate product or search configuration fieldset:
<field
name="enable_falang_search"
type="radio"
layout="joomla.form.field.radio.switcher"
default="0"
label="COM_J2COMMERCE_CONFIG_FALANG_SEARCH_LABEL"
description="COM_J2COMMERCE_CONFIG_FALANG_SEARCH_DESC"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
2. Add language strings
COM_J2COMMERCE_CONFIG_FALANG_SEARCH_LABEL="Search Falang translations"
COM_J2COMMERCE_CONFIG_FALANG_SEARCH_DESC="Include product titles and short descriptions translated by Falang in keyword search. Only translations for the active site language are searched."
3. Update both product list models
The change is required in both files:
components/com_j2commerce/src/Model/ProductsModel.php
components/com_j2commerce/src/Model/ProducttagsModel.php
ProductModel.php does not need to be changed because it loads a single product and does not build the product search query.
In both list models, replace the current search block:
// Search filter - searches title, SKU, UPC, and description
$search = $this->getState('filter.search');
if (!empty($search)) {
$search = '%' . str_replace(' ', '%', trim($search)) . '%';
$query->where(
'(' . $db->quoteName('a.title') . ' LIKE :search1'
. ' OR ' . $db->quoteName('v.sku') . ' LIKE :search2'
. ' OR ' . $db->quoteName('v.upc') . ' LIKE :search3'
. ' OR ' . $db->quoteName('a.introtext') . ' LIKE :search4)'
)
->bind(':search1', $search)
->bind(':search2', $search)
->bind(':search3', $search)
->bind(':search4', $search);
}
with:
// Search native product data and optionally the active Falang translation.
$search = trim((string) $this->getState('filter.search'));
if ($search !== '') {
$searchPattern = '%' . str_replace(' ', '%', $search) . '%';
$conditions = [
$db->quoteName('a.title') . ' LIKE :search1',
$db->quoteName('v.sku') . ' LIKE :search2',
$db->quoteName('v.upc') . ' LIKE :search3',
$db->quoteName('a.introtext') . ' LIKE :search4',
];
$params = $this->getState('params');
$falangEnabled = \is_object($params)
&& method_exists($params, 'get')
&& (bool) $params->get('enable_falang_search', 0);
if ($falangEnabled && $this->isFalangAvailable()) {
$languageTag = Factory::getApplication()
->getLanguage()
->getTag();
$falangQuery = $db->getQuery(true)
->select('1')
->from($db->quoteName('#__falang_content', 'fc'))
->join(
'INNER',
$db->quoteName('#__languages', 'fl')
. ' ON ' . $db->quoteName('fl.lang_id')
. ' = ' . $db->quoteName('fc.language_id')
)
->where(
$db->quoteName('fc.reference_id')
. ' = ' . $db->quoteName('a.id')
)
->where(
$db->quoteName('fc.reference_table')
. ' = ' . $db->quote('content')
)
->where(
$db->quoteName('fc.reference_field')
. ' IN ('
. $db->quote('title')
. ', '
. $db->quote('introtext')
. ')'
)
->where($db->quoteName('fc.published') . ' = 1')
->where(
$db->quoteName('fl.lang_code')
. ' = :falangLanguage'
)
->where(
$db->quoteName('fc.value')
. ' LIKE :falangSearch'
);
$conditions[] = 'EXISTS (' . $falangQuery . ')';
// The Falang subquery is embedded in the parent query as SQL,
// therefore its placeholders are bound on the parent query.
$query
->bind(
':falangLanguage',
$languageTag,
ParameterType::STRING
)
->bind(
':falangSearch',
$searchPattern,
ParameterType::STRING
);
}
$query
->where('(' . implode(' OR ', $conditions) . ')')
->bind(':search1', $searchPattern, ParameterType::STRING)
->bind(':search2', $searchPattern, ParameterType::STRING)
->bind(':search3', $searchPattern, ParameterType::STRING)
->bind(':search4', $searchPattern, ParameterType::STRING);
}
Both models already import Factory and ParameterType, so no additional imports should be required.
Add the following method near the end of both list model classes:
/**
* Check whether the Falang content table is available.
*
* The result is cached for the duration of the request because
* getListQuery() can be called more than once when filters are built.
*/
private function isFalangAvailable(): bool
{
static $available;
if ($available !== null) {
return $available;
}
$db = $this->getDatabase();
$tableName = $db->replacePrefix('#__falang_content');
$available = \in_array(
$tableName,
$db->getTableList(),
true
);
return $available;
}
This prevents SQL errors if Falang is removed while the configuration option remains enabled.
5. Include the option in the model cache keyIn getStoreId() in both models, add the Falang setting before:
return parent::getStoreId($id);
Suggested code:
$params = $this->getState('params');
$falangSearchEnabled = \is_object($params)
&& method_exists($params, 'get')
? (int) $params->get('enable_falang_search', 0)
: 0;
$id .= ':' . $falangSearchEnabled;
This ensures that cached model results cannot be shared between requests using different Falang search settings.
Possible alternativeInstead of implementing Falang-specific SQL in both models, J2Commerce could dispatch an event while building the search condition. A Falang integration plugin could then append the translated-content condition and required query bindings.
That would avoid a direct Falang dependency and could later support other translation extensions. If direct support is preferred, the configuration-controlled implementation above keeps the feature optional and preserves the current search behaviour for stores that do not use Falang.
best regards
KK