| Current Path : /home/jeromecohp/www/administrator/components/com_conditions/src/Helper/ |
| Current File : /home/jeromecohp/www/administrator/components/com_conditions/src/Helper/ConvertAssignments.php |
<?php
/**
* @package Conditions
* @version 25.1.10755
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2025 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Helper;
use Joomla\CMS\Factory as JFactory;
use RegularLabs\Component\Conditions\Administrator\Model\ItemModel;
use RegularLabs\Library\DB as RL_DB;
use RegularLabs\Library\Language as RL_Language;
use RegularLabs\Library\StringHelper as RL_String;
class ConvertAssignments
{
static $article_group_id = 0;
static $conditions_by_hash = [];
static $conditions_by_item = [];
static $field_ids = [];
static $mirrors = [];
public static function convert(
$extension,
$params_table,
$name_table = '',
$name_column = 'name',
$id_column = 'id',
$excludes = []
): bool
{
$name_table = $name_table ?: $params_table;
$db = JFactory::getDbo();
$query = $db->getQuery(true)
// Select the required fields from the table.
->select('a.*')
->from($db->quoteName('#__' . $params_table, 'a'))
->where(RL_DB::like($db->quoteName('a.params'), '*"assignto_*'));
$db->setQuery($query);
$items = $db->loadObjectList();
if (empty($items))
{
return true;
}
foreach ($items as $item)
{
if ( ! self::handleItem($item, $extension, $params_table, $name_table, $name_column, $id_column, $excludes))
{
return false;
}
}
foreach (self::$mirrors as $source_id => $mirrored_ids)
{
if ($source_id < 0)
{
self::createAndMapReverseCondition($source_id * -1, $mirrored_ids, $extension, $params_table, $name_table, $name_column, $id_column);
continue;
}
self::mapFromSourceCondition($source_id, $mirrored_ids, $extension, $params_table, $name_table, $name_column, $id_column);
}
return true;
}
public static function getCondition(
object $item,
string $extension,
string $table,
string $name_column = 'name',
array $excludes = []
)
{
RL_Language::load('com_conditions');
$name = Helper::getForItemText($extension, $item->id, $table, $name_column);
$condition = (object) [
'name' => $name,
'match_all' => ($item->params->match_method ?? 'and') === 'and' ? 1 : 0,
'published' => 1,
'groups' => [
(object) [
'match_all' => ($item->params->match_method ?? 'and') === 'and' ? 1 : 0,
'rules' => [],
],
(object) [
'match_all' => 1,
'rules' => [],
],
],
];
self::$article_group_id = $condition->match_all ? 0 : 1;
self::addRules($item->params, $condition->groups, $excludes);
if (empty($condition->groups[0]->rules))
{
unset($condition->groups[0]);
}
if (empty($condition->groups[1]->rules))
{
unset($condition->groups[1]);
}
$condition->hash = md5(json_encode([$condition->match_all, $condition->groups]));
return $condition;
}
public static function saveConditionByItem(
object $item,
string $extension,
string $name_table,
string $name_column = 'name',
array $excludes = []
): bool
{
$condition = self::getCondition($item, $extension, $name_table, $name_column, $excludes);
if (empty($condition->groups))
{
return true;
}
$model = new ItemModel;
if (isset(self::$conditions_by_hash[$condition->hash]))
{
$condition_id = self::$conditions_by_hash[$condition->hash];
$model->map(
$condition_id,
$extension,
$item->id,
$name_table,
$name_column
);
self::$conditions_by_item[$item->id] = $condition_id;
return true;
}
$condition_saved = $model->saveByObject(
$condition,
$extension,
$item->id,
$name_table,
$name_column
);
if ( ! $condition_saved)
{
return false;
}
self::$conditions_by_item[$item->id] = $condition->id;
self::$conditions_by_hash[$condition->hash] = $condition->id;
return true;
}
private static function addRule(
array &$groups,
string $type,
bool|int $exclude,
object|array $params = [],
int $id = 0
): void
{
$groups[$id]->rules[] = (object) [
'type' => $type,
'exclude' => $exclude ? 1 : 0,
'params' => (object) $params,
];
}
private static function addRuleAgentBrowser(object $params, array &$groups): void
{
if (
empty($params->assignto_browsers)
|| empty($params->assignto_browsers_selection)
)
{
return;
}
self::addRule($groups,
'agent__browser',
$params->assignto_browsers == 2,
[
'selection' => $params->assignto_browsers_selection ?? [],
]
);
}
private static function addRuleAgentBrowserMobile(object $params, array &$groups): void
{
if (
empty($params->assignto_browsers)
|| empty($params->assignto_mobile_selection)
)
{
return;
}
self::addRule($groups,
'agent__browser_mobile',
$params->assignto_browsers == 2,
[
'selection' => $params->assignto_mobile_selection ?? [],
]
);
}
private static function addRuleBasic(
string $new_name,
string $old_name,
object $params,
array &$groups,
int $id = 0
): void
{
if (empty($params->{$old_name}))
{
return;
}
self::addRule($groups,
$new_name,
$params->{$old_name} == 2,
[
'selection' => $params->{$old_name . '_selection'} ?? [],
],
$id
);
}
private static function addRuleCategory(
string $new_name,
string $old_name,
object $params,
array &$groups
): void
{
if (empty($params->{$old_name}))
{
return;
}
self::addRule($groups,
$new_name,
$params->{$old_name} == 2,
[
'selection' => $params->{$old_name . '_selection'} ?? [],
'include_children' => $params->{$old_name . '_inc_children'} ?? 0,
'page_types' => self::correctPageTypeValues($params->{$old_name . '_inc'} ?? []),
]
);
}
private static function addRuleContentArticleAuthor(object $params, array &$groups): void
{
if (
empty($params->assignto_articles)
|| empty($params->assignto_articles_authors)
)
{
return;
}
self::addRule($groups,
'content__article__author',
$params->assignto_articles == 2,
[
'selection' => $params->assignto_articles_authors ?? [],
],
self::$article_group_id
);
}
private static function addRuleContentArticleContentKeyword(
object $params,
array &$groups
): void
{
if (
empty($params->assignto_articles)
|| empty($params->assignto_articles_authors)
)
{
return;
}
self::addRule($groups,
'content__article__content_keyword',
$params->assignto_articles == 2,
[
'selection' => $params->assignto_articles_content_keywords ?? '',
],
self::$article_group_id
);
}
private static function addRuleContentArticleDate(object $params, array &$groups): void
{
if (
empty($params->assignto_articles)
|| ! isset($params->assignto_articles_date)
|| $params->assignto_articles_date == ''
)
{
return;
}
$comparison = $params->assignto_articles_date_comparison ?? 'between';
if ($comparison == 'fromto')
{
$comparison = 'between';
}
self::addRule($groups,
'content__article__date',
$params->assignto_articles == 2,
[
'selection' => $params->assignto_articles_date ?? '',
'comparison' => $comparison,
'date' => $params->assignto_articles_date_date ?? '',
'from' => $params->assignto_articles_date_from ?? '',
'to' => $params->assignto_articles_date_to ?? '',
'recurring' => 0,
],
self::$article_group_id
);
}
private static function addRuleContentArticleFeatured(object $params, array &$groups): void
{
if (
empty($params->assignto_articles)
|| ! isset($params->assignto_articles_featured)
|| $params->assignto_articles_featured == ''
)
{
return;
}
$exclude = $params->assignto_articles == 2
? $params->assignto_articles_featured
: ! $params->assignto_articles_featured;
self::addRule($groups,
'content__article__featured',
$exclude,
[],
self::$article_group_id
);
}
private static function addRuleContentArticleField(object $params, array &$groups): void
{
if (
empty($params->assignto_articles)
|| empty($params->assignto_articles_fields)
)
{
return;
}
foreach ($params->assignto_articles_fields as $field)
{
$field_id = self::getFieldIdByName($field->field);
if ( ! $field_id)
{
continue;
}
self::addRule($groups,
'content__article__field',
$params->assignto_articles == 2,
[
'field' => $field_id,
'comparison' => $field->field_comparison ?? '',
'value' => $field->field_value ?? '',
],
self::$article_group_id
);
}
}
private static function addRuleContentArticleMetaKeyword(object $params, array &$groups): void
{
if (
empty($params->assignto_articles)
|| empty($params->assignto_articles_keywords)
)
{
return;
}
self::addRule($groups,
'content__article__meta_keyword',
$params->assignto_articles == 2,
[
'selection' => $params->assignto_articles_keywords ?? '',
],
self::$article_group_id
);
}
private static function addRuleDateDate(object $params, array &$groups): void
{
if (empty($params->assignto_date))
{
return;
}
self::addRule($groups,
'date__date',
$params->assignto_date == 2,
[
'comparison' => 'between',
'from' => $params->assignto_date_publish_up ?? '',
'to' => $params->assignto_date_publish_down ?? '',
'recurring' => $params->assignto_date_recurring ?? 0,
]
);
}
private static function addRuleDateSeason(object $params, array &$groups): void
{
if (empty($params->assignto_seasons))
{
return;
}
self::addRule($groups,
'date__season',
$params->assignto_seasons == 2,
[
'selection' => $params->assignto_seasons_selection ?? [],
'hemisphere' => $params->assignto_seasons_hemisphere ?? 'northern',
]
);
}
private static function addRuleDateTime(object $params, array &$groups): void
{
if (empty($params->assignto_time))
{
return;
}
self::addRule($groups,
'date__time',
$params->assignto_time == 2,
[
'comparison' => 'between',
'from' => $params->assignto_time_publish_up ?? '',
'to' => $params->assignto_time_publish_down ?? '',
]
);
}
private static function addRuleMenuHomePage(object $params, array &$groups): void
{
if (empty($params->assignto_homepage))
{
return;
}
self::addRule($groups,
'menu__home_page',
$params->assignto_homepage == 2
);
}
private static function addRuleMenuMenuItem(object $params, array &$groups): void
{
if (empty($params->assignto_menuitems))
{
return;
}
self::addRule($groups,
'menu__menu_item',
$params->assignto_menuitems == 2,
[
'selection' => $params->assignto_menuitems_selection ?? [],
'include_children' => $params->assignto_menuitems_inc_children ?? 0,
]
);
}
private static function addRuleOtherTag(object $params, array &$groups): void
{
if (empty($params->assignto_tags))
{
return;
}
self::addRule($groups,
'other__tag',
$params->assignto_tags == 2,
[
'selection' => $params->assignto_tags_selection ?? [],
'match_all' => $params->assignto_tags_match_all ?? 0,
'include_children' => $params->assignto_tags_inc_children ?? 0,
]
);
}
private static function addRuleOtherUrl(object $params, array &$groups): void
{
if (empty($params->assignto_urls))
{
return;
}
self::addRule($groups,
'other__url',
$params->assignto_urls == 2,
[
'selection' => $params->assignto_urls_selection ?? [],
'case_sensitive' => $params->assignto_urls_casesensitive ?? 0,
'regex' => $params->assignto_urls_regex ?? 0,
]
);
}
private static function addRuleVisitorUserGroup(object $params, array &$groups): void
{
if (empty($params->assignto_usergrouplevels))
{
return;
}
self::addRule($groups,
'visitor__user_group',
$params->assignto_usergrouplevels == 2,
[
'selection' => $params->assignto_usergrouplevels_selection ?? [],
'match_all' => $params->assignto_usergrouplevels_match_all ?? 0,
'include_children' => $params->assignto_usergrouplevels_inc_children ?? 0,
]
);
}
private static function addRules(object $params, array &$groups, array $excludes = []): void
{
self::addRuleMenuMenuItem($params, $groups);
empty($excludes['homepage']) && self::addRuleMenuHomepage($params, $groups);
if (empty($excludes['date']))
{
self::addRuleDateDate($params, $groups);
self::addRuleDateSeason($params, $groups);
self::addRuleBasic('date__month', 'assignto_months', $params, $groups);
self::addRuleBasic('date__day', 'assignto_days', $params, $groups);
self::addRuleDateTime($params, $groups);
}
if (empty($excludes['content']))
{
self::addRuleBasic('content__page_type', 'assignto_contentpagetypes', $params, $groups);
self::addRuleCategory('content__category', 'assignto_cats', $params, $groups);
self::addRuleBasic('content__article__id', 'assignto_articles', $params, $groups, self::$article_group_id);
self::addRuleContentArticleFeatured($params, $groups);
self::addRuleContentArticleDate($params, $groups);
self::addRuleContentArticleAuthor($params, $groups);
self::addRuleContentArticleContentKeyword($params, $groups);
self::addRuleContentArticleMetaKeyword($params, $groups);
self::addRuleContentArticleField($params, $groups);
}
empty($excludes['users']) && self::addRuleBasic('visitor__user', 'assignto_users', $params, $groups);
empty($excludes['usergrouplevels']) && self::addRuleVisitorUserGroup($params, $groups);
empty($excludes['languages']) && self::addRuleBasic('visitor__language', 'assignto_languages', $params, $groups);
empty($excludes['ips']) && self::addRuleBasic('visitor__ip', 'assignto_ips', $params, $groups);
empty($excludes['devices']) && self::addRuleBasic('agent__device', 'assignto_devices', $params, $groups);
empty($excludes['os']) && self::addRuleBasic('agent__os', 'assignto_os', $params, $groups);
if (empty($excludes['browsers']))
{
self::addRuleAgentBrowser($params, $groups);
self::addRuleAgentBrowserMobile($params, $groups);
}
if (empty($excludes['geo']))
{
self::addRuleBasic('geo__continent', 'assignto_geocontinents', $params, $groups);
self::addRuleBasic('geo__country', 'assignto_geocountries', $params, $groups);
self::addRuleBasic('geo__region', 'assignto_georegions', $params, $groups);
self::addRuleBasic('geo__postal_code', 'assignto_geopostalcodes', $params, $groups);
}
empty($excludes['tags']) && self::addRuleOtherTag($params, $groups);
empty($excludes['components']) && self::addRuleBasic('other__component', 'assignto_components', $params, $groups);
empty($excludes['templates']) && self::addRuleBasic('other__template', 'assignto_templates', $params, $groups);
empty($excludes['urls']) && self::addRuleOtherUrl($params, $groups);
empty($excludes['php']) && self::addRuleBasic('other__php', 'assignto_php', $params, $groups);
if (empty($excludes['flexicontent']))
{
self::addRuleBasic('flexicontent__page_type', 'assignto_flexicontentpagetypes', $params, $groups);
self::addRuleCategory('flexicontent__tag', 'assignto_flexicontenttags', $params, $groups);
self::addRuleBasic('flexicontent__type', 'assignto_flexicontenttypes', $params, $groups);
}
if (empty($excludes['hikashop']))
{
self::addRuleBasic('hikashop__page_type', 'assignto_hikashoppagetypes', $params, $groups);
self::addRuleCategory('hikashop__category', 'assignto_hikashopcats', $params, $groups);
self::addRuleBasic('hikashop__item', 'assignto_hikashopproducts', $params, $groups);
}
if (empty($excludes['zoo']))
{
self::addRuleBasic('zoo__page_type', 'assignto_zoopagetypes', $params, $groups);
self::addRuleCategory('zoo__category', 'assignto_flexicontentcats', $params, $groups);
self::addRuleBasic('zoo__item', 'assignto_zooitems', $params, $groups);
}
}
private static function correctPageTypeValues(?array $values = []): array
{
if (empty($values))
{
return [];
}
$aliases = [
'inc_cats' => 'categories',
'inc_arts' => 'articles',
'inc_others' => 'others',
'inc_tags' => 'tags',
'inc_items' => 'items',
];
$page_types = [];
foreach ($values as $page_type)
{
if ($page_type === 'x')
{
continue;
}
$page_types[] = $aliases[$page_type] ?? $page_type;
}
return $page_types;
}
private static function createAndMapReverseCondition(
int $source_id,
array $items,
string $extension,
string $params_table,
string $name_table,
string $name_column = 'name',
string $id_column = 'id'
): void
{
if ( ! isset(self::$conditions_by_item[$source_id]))
{
return;
}
$model = new ItemModel;
$first_item = array_shift($items);
$condition = $model->getConditionById(self::$conditions_by_item[$source_id]);
$reverse_condition = self::getReverseCondition($condition);
$condition_saved = $model->saveByObject(
$reverse_condition,
$extension,
$first_item->id,
$name_table,
$name_column
);
if ( ! $condition_saved)
{
return;
}
self::removeAssignments($first_item, $params_table, $id_column);
foreach ($items as $item)
{
$model->map(
$reverse_condition->id,
$extension,
$item->id,
$name_table,
$name_column
);
self::removeAssignments($item, $params_table, $id_column);
}
}
private static function getFieldIdByName(string $name): int
{
if (isset(static::$field_ids[$name]))
{
return static::$field_ids[$name];
}
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('a.id')
->from('#__fields AS a')
->where(RL_DB::is('a.name', $name));
$db->setQuery($query, 0, 1);
static::$field_ids[$name] = (int) $db->loadResult();
return static::$field_ids[$name];
}
private static function getReverseCondition(object $source_condition): object
{
RL_Language::load('com_conditions');
$reverse_condition = (object) [
'name' => 'Reverse: ' . RL_String::escape($source_condition->name),
'match_all' => 1,
'published' => 1,
'groups' => [
(object) [
'match_all' => 1,
'rules' => [],
],
],
];
self::addRule($reverse_condition->groups, 'other__condition', true, (object) [
'selection' => $source_condition->id,
]);
return $reverse_condition;
}
private static function handleItem(
object $item,
string $extension,
string $params_table,
string $name_table,
string $name_column = 'name',
string $id_column = 'id',
array $excludes = []
): bool
{
if (empty($item->params))
{
return true;
}
$item->id = $item->{$id_column};
$item->params = json_decode($item->params);
if ( ! empty($item->mirror_id) && ! empty($item->mirror_id))
{
if ( ! isset(self::$mirrors[$item->mirror_id]))
{
self::$mirrors[$item->mirror_id] = [];
}
self::$mirrors[$item->mirror_id][] = $item;
return true;
}
if ( ! self::saveConditionByItem($item, $extension, $name_table, $name_column, $excludes))
{
return false;
}
self::removeAssignments($item, $params_table, $id_column);
return true;
}
private static function mapFromSourceCondition(
int $source_id,
array $items,
string $extension,
string $params_table,
string $name_table,
string $name_column = 'name',
string $id_column = 'id'
): void
{
if ( ! isset(self::$conditions_by_item[$source_id]))
{
return;
}
$condition_id = self::$conditions_by_item[$source_id];
$model = new ItemModel;
foreach ($items as $item)
{
$model->map(
$condition_id,
$extension,
$item->id,
$name_table,
$name_column
);
self::removeAssignments($item, $params_table, $id_column);
}
}
private static function removeAssignments(
object $item,
string $table,
string $id_column = 'id'
): void
{
foreach ($item->params as $key => $value)
{
if (
in_array($key, [
'mirror_module',
'mirror_moduleid',
'match_method',
'show_assignments',
'has_geoip_library',
])
|| str_starts_with($key, 'assignto_')
)
{
unset($item->params->{$key});
}
}
$params = json_encode(($item->params));
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->update($db->quoteName('#__' . $table))
->set($db->quoteName('params') . ' = ' . $db->quote($params))
->where($db->quoteName($id_column) . ' = ' . (int) $item->id);
$db->setQuery($query)->execute();
}
}