primo commit

This commit is contained in:
2024-12-17 17:34:10 +01:00
commit e650f8df99
16435 changed files with 2451012 additions and 0 deletions

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8" ?>
<access component="com_conditions">
<section name="component">
<action name="core.admin" title="JACTION_ADMIN" />
<action name="core.options" title="JACTION_OPTIONS" />
<action name="core.manage" title="JACTION_MANAGE" />
<action name="core.create" title="JACTION_CREATE" />
<action name="core.delete" title="JACTION_DELETE" />
<action name="core.edit" title="JACTION_EDIT" />
<action name="core.edit.state" title="JACTION_EDITSTATE" />
</section>
</access>

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<extension version="4" type="component" method="upgrade">
<name>COM_CONDITIONS</name>
<description>COM_CONDITIONS_DESC</description>
<version>24.11.1459</version>
<creationDate>November 2024</creationDate>
<author>Regular Labs (Peter van Westen)</author>
<authorEmail>info@regularlabs.com</authorEmail>
<authorUrl>https://regularlabs.com</authorUrl>
<copyright>Copyright © 2024 Regular Labs - All Rights Reserved</copyright>
<license>GNU General Public License version 2 or later</license>
<namespace path="src">RegularLabs\Component\Conditions</namespace>
<scriptfile>script.install.php</scriptfile>
<administration>
<menu link="option=com_conditions" img="class:regularlabs-conditions">COM_CONDITIONS</menu>
<files folder="admin">
<file>access.xml</file>
<file>config.xml</file>
<file>conditions.xml</file>
<folder>forms</folder>
<folder>language</folder>
<folder>services</folder>
<folder>src</folder>
<folder>tmpl</folder>
</files>
</administration>
<media folder="media" destination="conditions">
<folder>js</folder>
</media>
</extension>

View File

@ -0,0 +1,128 @@
<?xml version="1.0" encoding="utf-8"?>
<config addfieldprefix="RegularLabs\Library\Form\Field">
<fieldset name="options"
label="JOPTIONS">
<field name="@load_script_admin-form" type="LoadMedia"
filetype="script" file="regularlabs.admin-form" />
<field name="@load_script_descriptions" type="LoadMedia"
filetype="script" file="regularlabs.admin-form-descriptions" />
<field name="@load_language_regularlabs" type="LoadLanguage" extension="plg_system_regularlabs" />
<field name="use_categories" type="Radio"
default="1" class="btn-group rl-btn-group btn-group-md btn-group-yesno"
label="RL_USE_CATEGORIES"
description="RL_USE_CATEGORIES_DESC">
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field name="use_colors" type="Radio"
default="1" class="btn-group rl-btn-group btn-group-md btn-group-yesno"
label="RL_USE_COLORS"
description="RL_USE_COLORS_DESC">
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field name="main_colors" type="TextArea"
rows="4"
default="none,#c0c6cf,#000000,#dc2a28,#fb6b14,#ffa813,#eac90a,#18a047,#0f9aa4,#115dda,#761bda,#d319a4"
label="RL_COLORS"
description="RL_COLORS_DESC"
showon="use_colors:1" />
<field name="disabled_rule_types" type="Checkboxes"
default="0"
class="rl-form-checkboxes-not-inline rl-form-checkboxes-set-parent-classes rl-form-checkboxes-style-disabled"
label="CON_DISABLED_RULE_TYPES"
description="CON_DISABLED_RULE_TYPES_DESC">
<group label="CON_MENU_ITEMS">
<option value="menu__menu_item">CON_MENU_ITEMS</option>
<option value="menu__home_page">CON_HOME_PAGE</option>
</group>
<group label="CON_DATE_TIME">
<option value="date__date">CON_DATE</option>
<option value="date__season">CON_SEASONS</option>
<option value="date__month">CON_MONTHS</option>
<option value="date__day">CON_DAYS</option>
<option value="date__time">CON_TIME</option>
</group>
<group label="CON_JOOMLA_CONTENT">
<option value="content__page_type">CON_PAGE_TYPES</option>
<option value="content__category">CON_CATEGORIES</option>
<option value="content__article__id">CON_ARTICLES</option>
<option value="content__article__featured">CON_ARTICLE_FEATURED</option>
<option value="content__article__status">CON_ARTICLE_STATUS</option>
<option value="content__article__date">CON_ARTICLE_DATE</option>
<option value="content__article__author">CON_ARTICLE_AUTHORS</option>
<option value="content__article__content_keyword">CON_ARTICLE_CONTENT_KEYWORDS</option>
<option value="content__article__meta_keyword">CON_ARTICLE_META_KEYWORDS</option>
<option value="content__article__field">CON_ARTICLE_FIELD</option>
</group>
<group label="CON_VISITORS">
<option value="visitor__user">CON_USERS</option>
<option value="visitor__access_level">CON_ACCESS_LEVELS</option>
<option value="visitor__user_group">CON_USER_GROUPS</option>
<option value="visitor__language">CON_LANGUAGES</option>
<option value="agent__device">CON_DEVICES</option>
<option value="agent__os">CON_OS</option>
<option value="agent__browser">CON_BROWSERS</option>
<option value="agent__browser_mobile">CON_MOBILE_BROWSERS</option>
<option value="visitor__ip">CON_IPS</option>
</group>
<group label="CON_GEOLOCATION">
<option value="geo__continent">CON_CONTINENTS</option>
<option value="geo__country">CON_COUNTRIES</option>
<option value="geo__region">CON_REGIONS</option>
<option value="geo__postal_code">CON_POSTAL_CODES</option>
</group>
<group label="CON_MISCELLANEOUS">
<option value="other__tag">CON_TAGS</option>
<option value="other__component">CON_COMPONENTS</option>
<option value="other__template">CON_TEMPLATES</option>
<option value="other__url">CON_URLS</option>
<option value="other__php">CON_PHP</option>
<option value="other__condition">CON_OTHER_CONDITION</option>
</group>
<group label="CON_3RD_PARTY_EXTENSIONS">
<option value="hikashop">CON_HIKASHOP</option>
<option value="flexicontent">CON_FLEXICONTENT</option>
<option value="zoo">CON_ZOO</option>
</group>
</field>
</fieldset>
<fieldset name="action_logs"
label="RL_USER_ACTION_LOGS">
<field name="enable_actionlog" type="Radio"
default="1" class="btn-group rl-btn-group btn-group-md btn-group-yesno"
label="RL_ENABLE_ACTIONLOG"
description="RL_ENABLE_ACTIONLOG_DESC">
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field name="actionlog_events" type="Checkboxes"
multiple="true" default="create,update,delete,change_state"
checked="create,update,delete,change_state" class="rl-form-checkboxes-not-inline"
label="RL_ACTIONLOG_EVENTS"
description="RL_ACTIONLOG_EVENTS_DESC"
showon="enable_actionlog:1">
<option value="create">RL_ACTION_CREATE</option>
<option value="update">RL_ACTION_UPDATE</option>
<option value="delete">RL_ACTION_DELETE</option>
<option value="change_state">RL_ACTION_CHANGE_STATE</option>
</field>
</fieldset>
<fieldset name="permissions"
label="JCONFIG_PERMISSIONS_LABEL"
description="JCONFIG_PERMISSIONS_DESC">
<field name="rules" type="Rules"
label="JCONFIG_PERMISSIONS_LABEL" filter="rules" validate="rules"
component="com_conditions" section="component" />
</fieldset>
</config>

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<form addfieldprefix="RegularLabs\Library\Form\Field">
<fields name="filter">
<field name="search" type="Text"
label="JSEARCH_FILTER_LABEL" hint="JSEARCH_FILTER" />
<field name="state" type="Status" optionsFilter="-2,1,*"
label="JPUBLISHED" onchange="this.form.submit();">
<option value="">JOPTION_SELECT_PUBLISHED</option>
</field>
<field name="category" type="SimpleCategory"
table="conditions" show_none="0" show_new="0"
label="JCATEGORY"
onchange="this.form.submit();">
<option value="">RL_SELECT_A_CATEGORY</option>
</field>
</fields>
<fields name="list">
<field name="fullordering" type="List"
label="RL_LIST_FULL_ORDERING" onchange="this.form.submit();"
default="a.name ASC">
<option value="">JGLOBAL_SORT_BY</option>
<option value="a.alias ASC">RL_HEADING_ALIAS_ASC</option>
<option value="a.alias DESC">RL_HEADING_ALIAS_DESC</option>
<option value="a.name ASC">JGLOBAL_TITLE_ASC</option>
<option value="a.name DESC">JGLOBAL_TITLE_DESC</option>
<option value="a.description ASC">RL_HEADING_DESCRIPTION_ASC</option>
<option value="a.description DESC">RL_HEADING_DESCRIPTION_DESC</option>
<option value="a.color ASC">RL_HEADING_COLOR_ASC</option>
<option value="a.color DESC">RL_HEADING_COLOR_DESC</option>
<option value="a.category ASC">RL_HEADING_CATEGORY_ASC</option>
<option value="a.category DESC">RL_HEADING_CATEGORY_DESC</option>
<option value="a.id ASC">JGRID_HEADING_ID_ASC</option>
<option value="a.id DESC">JGRID_HEADING_ID_DESC</option>
</field>
<field name="limit" type="Limitbox"
label="JGLOBAL_LIST_LIMIT" default="25" onchange="this.form.submit();" />
</fields>
</form>

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<form addfieldprefix="RegularLabs\Library\Form\Field">
<fieldset>
<field name="id" type="Number"
default="0" class="readonly" readonly="true"
label="JGLOBAL_FIELD_ID_LABEL" />
<field name="name" type="Text"
default="" required="true"
label="JGLOBAL_TITLE" />
<field name="alias" type="Text"
size="45" default="" hint="JFIELD_ALIAS_PLACEHOLDER"
label="JFIELD_ALIAS_LABEL" />
</fieldset>
<fieldset name="details">
<field name="published" type="List"
default="1" size="1" class="form-select-color-state"
label="JSTATUS">
<option value="1">JPUBLISHED</option>
<option value="-2">JTRASHED</option>
</field>
<field name="description" type="Textarea"
height="160" default=""
label="JGLOBAL_DESCRIPTION" />
<field name="category" type="SimpleCategory"
default="" table="conditions"
label="JCATEGORY" />
</fieldset>
<fieldset name="rules">
<field name="has_multiple_groups" type="Hidden" default="0" />
<field name="match_all" type="Radio"
default="1" class="btn-group rl-btn-group"
label="RL_MATCHING_METHOD"
description="CON_MATCHING_METHOD_DESC,CON_ALL,CON_ALL_DESC,CON_ANY,CON_ANY_DESC"
showon="has_multiple_groups:1">
<option value="1" class="btn btn-outline-info">CON_ALL</option>
<option value="0" class="btn btn-outline-info">CON_ANY</option>
</field>
<field name="groups" type="Subform"
formsource="/administrator/components/com_conditions/forms/item_group.xml" multiple="true"
buttons="move,add,remove" add_button_text="CON_ADD_GROUP"
class="rl-subform rl-hide-main-buttons rl-move-add-button" />
</fieldset>
</form>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<form addfieldprefix="RegularLabs\Library\Form\Field">
<fieldset addfieldprefix="RegularLabs\Component\Conditions\Administrator\Form\Field">
<field name="has_multiple_rules" type="Hidden" value="0" />
<field name="match_all" type="Radio"
default="1" class="btn-group rl-btn-group"
label="RL_MATCHING_METHOD"
description="CON_MATCHING_METHOD_DESC,CON_ALL,CON_ALL_DESC,CON_ANY,CON_ANY_DESC"
showon="has_multiple_rules:1">
<option value="1" class="btn btn-outline-info">CON_ALL</option>
<option value="0" class="btn btn-outline-info">CON_ANY</option>
</field>
<field name="rules" type="ConditionRules"
formsource="/administrator/components/com_conditions/forms/item_rule.xml" multiple="true"
buttons="move,add,remove" add_button_text="CON_ADD_RULE"
class="rl-subform rl-hide-main-buttons rl-move-add-button" />
</fieldset>
</form>

View File

@ -0,0 +1,912 @@
<?xml version="1.0" encoding="utf-8"?>
<form addfieldprefix="RegularLabs\Library\Form\Field">
<fieldset name="types" addfieldprefix="RegularLabs\Component\Conditions\Administrator\Form\Field">
<field name="type" type="Groupedlist"
default=""
label="CON_SELECT_A_RULE_TYPE" hiddenLabel="true">
<option value="">- %s -,CON_SELECT_A_RULE_TYPE</option>
<option value="-1" disabled="true">&amp;nbsp;</option>
<group label="CON_MENU_ITEMS">
<option value="menu__menu_item" class="check_enabled">CON_MENU_ITEMS</option>
<option value="menu__home_page" class="check_enabled">CON_HOME_PAGE</option>
</group>
<group label="CON_DATE_TIME">
<option value="date__date" class="check_enabled">CON_DATE</option>
<option value="date__season" class="check_enabled">CON_SEASONS</option>
<option value="date__month" class="check_enabled">CON_MONTHS</option>
<option value="date__day" class="check_enabled">CON_DAYS</option>
<option value="date__time" class="check_enabled">CON_TIME</option>
</group>
<group label="CON_JOOMLA_CONTENT">
<option value="content__page_type" class="check_enabled">CON_PAGE_TYPES</option>
<option value="content__category" class="check_enabled">CON_CATEGORIES</option>
<option value="content__article__id" class="check_enabled">CON_ARTICLES</option>
<option value="content__article__featured" class="check_enabled">CON_ARTICLE_FEATURED</option>
<option value="content__article__status" class="check_enabled">CON_ARTICLE_STATUS</option>
<option value="content__article__date" class="check_enabled">CON_ARTICLE_DATE</option>
<option value="content__article__author" class="check_enabled">CON_ARTICLE_AUTHORS</option>
<option value="content__article__content_keyword" class="check_enabled">CON_ARTICLE_CONTENT_KEYWORDS
</option>
<option value="content__article__meta_keyword" class="check_enabled">CON_ARTICLE_META_KEYWORDS</option>
<option value="content__article__field" class="check_enabled">CON_ARTICLE_FIELD</option>
</group>
<group label="CON_VISITORS">
<option value="visitor__user" class="check_enabled">CON_USERS</option>
<option value="visitor__access_level" class="check_enabled">CON_ACCESS_LEVELS</option>
<option value="visitor__user_group" class="check_enabled">CON_USER_GROUPS</option>
<option value="visitor__language" class="check_enabled">CON_LANGUAGES</option>
<option value="agent__device" class="check_enabled">CON_DEVICES</option>
<option value="agent__os" class="check_enabled">CON_OS</option>
<option value="agent__browser" class="check_enabled">CON_BROWSERS</option>
<option value="agent__browser_mobile" class="check_enabled">CON_MOBILE_BROWSERS</option>
<option value="visitor__ip" class="check_enabled">CON_IPS</option>
</group>
<group label="CON_GEOLOCATION">
<option value="geo__continent" class="check_enabled">CON_CONTINENTS</option>
<option value="geo__country" class="check_enabled">CON_COUNTRIES</option>
<option value="geo__region" class="check_enabled">CON_REGIONS</option>
<option value="geo__postal_code" class="check_enabled">CON_POSTAL_CODES</option>
</group>
<group label="CON_MISCELLANEOUS">
<option value="other__tag" class="check_enabled">CON_TAGS</option>
<option value="other__component" class="check_enabled">CON_COMPONENTS</option>
<option value="other__template" class="check_enabled">CON_TEMPLATES</option>
<option value="other__url" class="check_enabled">CON_URLS</option>
<option value="other__php" class="check_enabled">CON_PHP</option>
<option value="other__condition" class="check_enabled">CON_OTHER_CONDITION</option>
</group>
<!-- <group label="CON_EASYBLOG">-->
<!-- <option value="easyblog__page_type" class="check_enabled" group_name="CON_EASYBLOG">CON_PAGE_TYPES</option>-->
<!-- <option value="easyblog__tag" class="check_enabled" group_name="CON_EASYBLOG">CON_TAGS</option>-->
<!-- <option value="easyblog__item" class="check_enabled" group_name="CON_EASYBLOG">CON_ITEMS</option>-->
<!-- <option value="easyblog__tag" class="check_enabled" group_name="CON_EASYBLOG">CON_TAGS</option>-->
<!-- <option value="easyblog__keyword" class="check_enabled" group_name="CON_EASYBLOG">CON_KEYWORDS</option>-->
<!-- </group>-->
<group label="CON_FLEXICONTENT">
<option value="flexicontent__page_type" class="check_enabled" group_name="CON_FLEXICONTENT">CON_PAGE_TYPES</option>
<option value="flexicontent__tag" class="check_enabled" group_name="CON_FLEXICONTENT">CON_TAGS</option>
<option value="flexicontent__type" class="check_enabled" group_name="CON_FLEXICONTENT">CON_TYPES</option>
</group>
<group label="CON_HIKASHOP">
<option value="hikashop__page_type" class="check_enabled" group_name="CON_HIKASHOP">CON_PAGE_TYPES</option>
<option value="hikashop__category" class="check_enabled" group_name="CON_HIKASHOP">CON_CATEGORIES</option>
<option value="hikashop__item" class="check_enabled" group_name="CON_HIKASHOP">CON_PRODUCTS</option>
</group>
<group label="CON_ZOO">
<option value="zoo__page_type" class="check_enabled" group_name="CON_ZOO">CON_PAGE_TYPES</option>
<option value="zoo__category" class="check_enabled" group_name="CON_ZOO">CON_CATEGORIES</option>
<option value="zoo__item" class="check_enabled" group_name="CON_ZOO">RL_ITEMS</option>
</group>
</field>
<field name="@showon__exclude__a" type="ShowOn" value="type!:" />
<field name="exclude" type="Radio"
default="0" class="btn-group rl-btn-group btn-group-md rl-exclude-field"
label="">
<option value="0" class="btn btn-outline-success">CON_INCLUDE</option>
<option value="1" class="btn btn-outline-danger">CON_EXCLUDE</option>
</field>
<field name="@showon__exclude__b" type="ShowOn" />
<!-- MENU ITEMS -->
<field name="@showon__menu__menu_item__a" type="ShowOn" value="type:menu__menu_item" />
<field name="menu__menu_item" type="MenuItems"
multiple="true" default=""
label="CON_MENU_ITEMS"
hiddenLabel="true" />
<field name="menu__menu_item__include_children" type="Radio"
default="0" class="btn-group rl-btn-group btn-group-md btn-group-yesno"
label="CON_INCLUDE_CHILD_ITEMS">
<option value="0">JNO</option>
<option value="1">JYES</option>
<option value="2" class="btn btn-outline-info">CON_ONLY</option>
</field>
<field name="@showon__menu__menu_item__include_children__a" type="ShowOn"
value="menu__menu_item__include_children:1,2" />
<field name="@note__menu__menu_item__include_children" type="Note"
class="rl-alert alert alert-warning"
text="CON_INCLUDE_CHILD_ITEMS_MENU_ITEMS_DESC" />
<field name="@showon__menu__menu_item__include_children__b" type="ShowOn" />
<field name="@showon__menu__menu_item__b" type="ShowOn" />
<!-- HOMEPAGE -->
<field name="@showon__menu__home_page__a" type="ShowOn" value="type:menu__home_page" />
<field name="menu__home_page" type="Hidden" value="1" />
<field name="@note__menu__home_page" type="Note"
class="rl-alert alert alert-info rl-alert-light"
text="CON_HOME_PAGE_DESC" />
<field name="@showon__menu__home_page__b" type="ShowOn" />
<!-- DATE -->
<!-- DATE :: DATE -->
<field name="@showon__date__date__a" type="ShowOn" value="type:date__date" />
<field name="date__date" type="Hidden" value="1" />
<field name="date__date__comparison" type="Radio"
default="after" class="btn-group rl-btn-group btn-group-md"
label="">
<option value="before" class="btn btn-outline-info">CON_DATE_BEFORE</option>
<option value="after" class="btn btn-outline-info">CON_DATE_AFTER</option>
<option value="between" class="btn btn-outline-info">CON_DATE_BETWEEN</option>
</field>
<field name="@showon__date__date__before_after__a" type="ShowOn" value="date__date__comparison!:between" />
<field name="date__date__date" type="Calendar"
showtime="true" filter="none" format="%Y-%m-%d %H:%M"
default=""
label="" />
<field name="@showon__date__date__before_after__b" type="ShowOn" />
<field name="@showon__date__date__between__a" type="ShowOn" value="date__date__comparison:between" />
<field name="date__date__from" type="Calendar"
showtime="true" filter="none" format="%Y-%m-%d %H:%M"
default=""
label="CON_DATE_FROM" />
<field name="date__date__to" type="Calendar"
showtime="true" filter="none" format="%Y-%m-%d %H:%M"
default=""
label="CON_DATE_TO" />
<field name="date__date__recurring" type="Radio"
default="0" class="btn-group rl-btn-group btn-group-md btn-group-yesno"
label="CON_DATE_RECURRING"
description="CON_DATE_RECURRING_DESC">
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field name="@showon__date__date__between__b" type="ShowOn" />
<field name="@showon__date__date__b" type="ShowOn" />
<!-- DATE :: SEASONS -->
<field name="@showon__date__season__a" type="ShowOn" value="type:date__season" />
<field name="date__season" type="List"
multiple="true" default="" layout="joomla.form.field.list-fancy-select"
label="CON_SEASONS" hiddenLabel="true">
<option value="winter">CON_WINTER</option>
<option value="spring">CON_SPRING</option>
<option value="summer">CON_SUMMER</option>
<option value="fall">CON_FALL</option>
</field>
<field name="date__season__hemisphere" type="Radio"
default="northern" class="btn-group rl-btn-group btn-group-md"
label="CON_HEMISPHERE">
<option value="northern">CON_NORTHERN</option>
<option value="southern">CON_SOUTHERN</option>
<option value="australia">CON_AUSTRALIA</option>
</field>
<field name="@showon__date__season__b" type="ShowOn" />
<!-- DATE :: MONTHS -->
<field name="@showon__date__month__a" type="ShowOn" value="type:date__month" />
<field name="date__month" type="List"
multiple="true" default="" layout="joomla.form.field.list-fancy-select"
label="CON_MONTHS" hiddenLabel="true">
<option value="1">JANUARY</option>
<option value="2">FEBRUARY</option>
<option value="3">MARCH</option>
<option value="4">APRIL</option>
<option value="5">MAY</option>
<option value="6">JUNE</option>
<option value="7">JULY</option>
<option value="8">AUGUST</option>
<option value="9">SEPTEMBER</option>
<option value="10">OCTOBER</option>
<option value="11">NOVEMBER</option>
<option value="12">DECEMBER</option>
</field>
<field name="@showon__date__month__b" type="ShowOn" />
<!-- DATE :: DAYS -->
<field name="@showon__date__day__a" type="ShowOn" value="type:date__day" />
<field name="date__day" type="List"
multiple="true" default="" layout="joomla.form.field.list-fancy-select"
label="CON_DAYS" hiddenLabel="true">
<option value="1">MONDAY</option>
<option value="2">TUESDAY</option>
<option value="3">WEDNESDAY</option>
<option value="4">THURSDAY</option>
<option value="5">FRIDAY</option>
<option value="6">SATURDAY</option>
<option value="7">SUNDAY</option>
</field>
<field name="@showon__date__day__b" type="ShowOn" />
<!-- DATE :: TIME -->
<field name="@showon__date__time__a" type="ShowOn" value="type:date__time" />
<field name="date__time" type="Hidden" value="1" />
<field name="date__time__comparison" type="Radio"
default="after" class="btn-group rl-btn-group btn-group-md"
label="">
<option value="before" class="btn btn-outline-info">CON_DATE_BEFORE</option>
<option value="after" class="btn btn-outline-info">CON_DATE_AFTER</option>
<option value="between" class="btn btn-outline-info">CON_DATE_BETWEEN</option>
</field>
<field name="@showon__date__time__before_after__a" type="ShowOn" value="date__time__comparison!:between" />
<field name="date__time__time" type="Text"
size="10" default="0:00" class="rl-w-5em text-right"
label="" />
<field name="@showon__date__time__before_after__b" type="ShowOn" />
<field name="@showon__date__time__between__a" type="ShowOn" value="date__time__comparison:between" />
<field name="date__time__from" type="Text"
size="10" default="0:00" class="rl-w-5em text-right"
label="CON_DATE_FROM" />
<field name="date__time__to" type="Text"
size="10" default="0:00" class="rl-w-5em text-right"
label="CON_DATE_TO" />
<field name="@showon__date__time__between__b" type="ShowOn" />
<field name="@showon__date__time__b" type="ShowOn" />
<!-- DATE (footer) -->
<field name="@showon__date__a" type="ShowOn"
value="type:date__date[OR]type:date__season[OR]type:date__month[OR]type:date__day[OR]type:date__time" />
<field name="@note__date" type="Note"
class="rl-alert alert alert-warning"
text="CON_DATE_TIME_DESC" />
<field name="@note__date__current" type="Note"
class="rl-alert alert alert-info rl-alert-light"
text="CON_CURRENT_DATE,[date:Y-m-d H:i]" />
<field name="@showon__date__b" type="ShowOn" />
<!-- JOOMLA CONTENT -->
<field name="@load_language_content" type="LoadLanguage" extension="com_content" />
<field name="@load_language_content_sys" type="LoadLanguage" extension="com_content.sys" />
<!-- JOOMLA CONTENT :: PAGE TYPES -->
<field name="@showon__content__page_type__a" type="ShowOn" value="type:content__page_type" />
<field name="content__page_type" type="List"
multiple="true" default=""
layout="joomla.form.field.list-fancy-select"
label="CON_PAGE_TYPES" hiddenLabel="true">
<option value="archive">COM_CONTENT_ARCHIVE_VIEW_DEFAULT_TITLE</option>
<option value="article">COM_CONTENT_ARTICLE_VIEW_DEFAULT_TITLE</option>
<option value="categories">COM_CONTENT_CATEGORIES_VIEW_DEFAULT_TITLE</option>
<option value="categoryblog">COM_CONTENT_CATEGORY_VIEW_BLOG_TITLE</option>
<option value="category">COM_CONTENT_CATEGORY_VIEW_DEFAULT_TITLE</option>
<option value="featured">COM_CONTENT_FEATURED_VIEW_DEFAULT_TITLE</option>
<option value="form">COM_CONTENT_FORM_VIEW_DEFAULT_TITLE</option>
</field>
<field name="@showon__content__page_type__b" type="ShowOn" />
<!-- JOOMLA CONTENT :: CATEGORIES -->
<field name="@showon__content__category__a" type="ShowOn" value="type:content__category" />
<field name="content__category" type="ContentCategories"
multiple="true" default=""
label="CON_CATEGORIES"
hiddenLabel="true" />
<field name="content__category__include_children" type="Radio"
default="0" class="btn-group rl-btn-group btn-group-md btn-group-yesno"
label="CON_INCLUDE_CHILD_ITEMS">
<option value="0">JNO</option>
<option value="1">JYES</option>
<option value="2" class="btn btn-outline-info">CON_ONLY</option>
</field>
<field name="content__category__page_types" type="Checkboxes"
default="categories,articles"
label="CON_PAGE_TYPES">
<option value="categories">RL_CATEGORIES</option>
<option value="articles">RL_ARTICLES</option>
<option value="others">RL_OTHERS</option>
</field>
<field name="@showon__content__category__b" type="ShowOn" />
<!-- JOOMLA CONTENT :: ARTICLES -->
<field name="@showon__content__article__id__a" type="ShowOn" value="type:content__article__id" />
<field name="content__article__id" type="ContentArticles"
multiple="true" default=""
label="CON_ARTICLES"
hiddenLabel="true" />
<field name="@showon__content__article__id__b" type="ShowOn" />
<!-- JOOMLA CONTENT :: ARTICLE FEATURED -->
<field name="@showon__content__article__featured__a" type="ShowOn" value="type:content__article__featured" />
<field name="content__article__featured" type="Hidden" value="1" />
<field name="@showon__content__article__featured__b" type="ShowOn" />
<!-- JOOMLA CONTENT :: ARTICLE PUBLISH STATE -->
<field name="@showon__content__article__status__a" type="ShowOn" value="type:content__article__status" />
<field name="content__article__status" type="List"
multiple="true" default="1"
layout="joomla.form.field.list-fancy-select"
label="CON_ARTICLE_STATUS" hiddenLabel="true">
<option value="1">JPUBLISHED</option>
<option value="0">JUNPUBLISHED</option>
<option value="2">JARCHIVED</option>
<option value="-2">JTRASHED</option>
</field>
<field name="@showon__content__article__status__b" type="ShowOn" />
<!-- JOOMLA CONTENT :: ARTICLE DATE -->
<field name="@showon__content__article__date__a" type="ShowOn" value="type:content__article__date" />
<field name="content__article__date" type="List"
default="created" layout="joomla.form.field.list-fancy-select"
label="CON_ARTICLE_DATE" hiddenLabel="true">
<option value="created">COM_CONTENT_FIELD_CREATED_LABEL</option>
<option value="modified">JGLOBAL_FIELD_MODIFIED_LABEL</option>
<option value="publish_up">COM_CONTENT_FIELD_PUBLISH_UP_LABEL</option>
<option value="publish_down">COM_CONTENT_FIELD_PUBLISH_DOWN_LABEL</option>
</field>
<field name="content__article__date__comparison" type="Radio"
default="after" class="btn-group rl-btn-group btn-group-md"
label="">
<option value="before" class="btn btn-outline-info">CON_DATE_BEFORE</option>
<option value="after" class="btn btn-outline-info">CON_DATE_AFTER</option>
<option value="between" class="btn btn-outline-info">CON_DATE_BETWEEN</option>
</field>
<field name="@showon__content__article__date__before_after__a" type="ShowOn"
value="content__article__date__comparison!:between" />
<field name="content__article__date__date" type="Calendar"
showtime="true" filter="none"
format="%Y-%m-%d %H:%M" default=""
label="" />
<field name="@showon__content__article__date__before_after__b" type="ShowOn" />
<field name="@showon__content__article__date__between__a" type="ShowOn"
value="content__article__date__comparison:between" />
<field name="content__article__date__from" type="Calendar"
showtime="true" filter="none"
format="%Y-%m-%d %H:%M" default=""
label="CON_DATE_FROM" />
<field name="content__article__date__to" type="Calendar"
showtime="true" filter="none"
format="%Y-%m-%d %H:%M" default=""
label="CON_DATE_TO" />
<field name="content__article__date__recurring" type="Radio"
default="0" class="btn-group rl-btn-group btn-group-md btn-group-yesno"
label="CON_DATE_RECURRING"
description="CON_DATE_RECURRING_DESC">
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field name="@showon__content__article__date__between__b" type="ShowOn" />
<field name="@showon__content__article__date__b" type="ShowOn" />
<!-- JOOMLA CONTENT :: ARTICLE AUTHORS -->
<field name="@showon__content__article__author__a" type="ShowOn" value="type:content__article__author" />
<field name="content__article__author" type="Users"
multiple="true" show_current="true" default=""
label="CON_ARTICLE_AUTHORS" hiddenLabel="true" />
<field name="@showon__content__article__author__b" type="ShowOn" />
<!-- JOOMLA CONTENT :: ARTICLE CONTENT KEYWORDS -->
<field name="@showon__content__article__content_keyword__a" type="ShowOn"
value="type:content__article__content_keyword" />
<field name="content__article__content_keyword" type="Textarea"
default=""
label="CON_ARTICLE_CONTENT_KEYWORDS"
hiddenLabel="true" />
<field name="@note__article_content_keywords" type="Note"
class="rl-alert alert alert-info rl-alert-light"
text="CON_COMMA_SEPARATED_DESC" />
<field name="content__article__content_keyword__case_sensitive" type="Radio"
default="0" class="btn-group rl-btn-group btn-group-md btn-group-yesno"
label="RL_CASE_SENSITIVE">
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field name="@showon__content__article__content_keyword__b" type="ShowOn" />
<!-- JOOMLA CONTENT :: ARTICLE META KEYWORDS -->
<field name="@showon__content__article__meta_keyword__a" type="ShowOn"
value="type:content__article__meta_keyword" />
<field name="content__article__meta_keyword" type="Textarea"
default=""
label="CON_ARTICLE_META_KEYWORDS"
hiddenLabel="true" />
<field name="@note__content__article__meta_keyword" type="Note"
class="rl-alert alert alert-info rl-alert-light"
text="CON_COMMA_SEPARATED_DESC" />
<field name="content__article__meta_keyword__case_sensitive" type="Radio"
default="0" class="btn-group rl-btn-group btn-group-md btn-group-yesno"
label="RL_CASE_SENSITIVE">
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field name="@showon__content__article__meta_keyword__b" type="ShowOn" />
<!-- JOOMLA CONTENT :: ARTICLE FIELDS -->
<field name="@showon__content__article__field__a" type="ShowOn" value="type:content__article__field" />
<field name="content__article__field" type="Hidden" value="1" />
<field name="content__article__field__field" type="Field"
label="CON_ARTICLE_FIELD" hiddenLabel="true" />
<field name="content__article__field__comparison" type="List"
default="equals" class="w-auto"
label="CON_COMPARISON" hiddenLabel="true">
<option value="equals">CON_COMPARISON_EQUALS</option>
<option value="not_equals">CON_COMPARISON_NOT_EQUALS</option>
<option value="contains">CON_COMPARISON_CONTAINS</option>
<option value="contains_one">CON_COMPARISON_CONTAINS_ONE</option>
<option value="not_contains">CON_COMPARISON_NOT_CONTAINS</option>
<option value="begins_with">CON_COMPARISON_BEGINS_WITH</option>
<option value="ends_with">CON_COMPARISON_ENDS_WITH</option>
<option value="less_than">CON_COMPARISON_LESS_THAN</option>
<option value="greater_than">CON_COMPARISON_GREATER_THAN</option>
<option value="regex">CON_COMPARISON_REGEX</option>
</field>
<field name="content__article__field__value" type="Text"
default=""
label="CON_FIELD_VALUE" hiddenLabel="true"
hint="CON_FIELD_VALUE" />
<field name="@showon__content__article__field__b" type="ShowOn" />
<!-- USERS -->
<field name="@showon__visitor__user__a" type="ShowOn" value="type:visitor__user" />
<field name="visitor__user" type="Users"
multiple="true" default=""
label="CON_USERS" hiddenLabel="true" />
<field name="@showon__visitor__user__b" type="ShowOn" />
<!-- ACCESS LEVEL -->
<field name="@showon__visitor__access_level__a" type="ShowOn" value="type:visitor__access_level" />
<field name="visitor__access_level" type="AccessLevels"
multiple="true" default=""
label="CON_ACCESS_LEVELS"
hiddenLabel="true" />
<field name="visitor__access_level__match_all" type="Radio"
default="0" class="btn-group rl-btn-group btn-group-md btn-group-yesno"
label="CON_MATCH_ALL"
description="CON_MATCH_ALL_DESC">
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field name="@showon__visitor__access_level__b" type="ShowOn" />
<!-- USER GROUPS -->
<field name="@showon__visitor__user_group__a" type="ShowOn" value="type:visitor__user_group" />
<field name="visitor__user_group" type="UserGroups"
multiple="true" notregistered="1" default=""
label="CON_USER_GROUPS" hiddenLabel="true" />
<field name="visitor__user_group__match_all" type="Radio"
default="0" class="btn-group rl-btn-group btn-group-md btn-group-yesno"
label="CON_MATCH_ALL"
description="CON_MATCH_ALL_DESC">
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field name="@showon__visitor__user_group__match_all__a" type="ShowOn"
value="visitor__user_group__match_all:0" />
<field name="visitor__user_group__include_children" type="Radio"
default="0" class="btn-group rl-btn-group btn-group-md btn-group-yesno"
label="CON_INCLUDE_CHILD_ITEMS">
<option value="0">JNO</option>
<option value="1">JYES</option>
<option value="2" class="btn btn-outline-info">CON_ONLY</option>
</field>
<field name="@showon__visitor__user_group__match_all__b" type="ShowOn" />
<field name="@showon__visitor__user_group__b" type="ShowOn" />
<!-- LANGUAGES -->
<field name="@showon__visitor__language__a" type="ShowOn" value="type:visitor__language" />
<field name="visitor__language" type="Languages"
multiple="true" default=""
label="CON_LANGUAGES"
hiddenLabel="true" />
<field name="@showon__visitor__language__b" type="ShowOn" />
<!-- DEVICES -->
<field name="@showon__agent__device__a" type="ShowOn" value="type:agent__device" />
<field name="agent__device" type="List"
multiple="true" default="" layout="joomla.form.field.list-fancy-select"
label="CON_DEVICES" hiddenLabel="true">
<option value="desktop">CON_DEVICES_DESKTOP</option>
<option value="tablet">CON_DEVICES_TABLET</option>
<option value="mobile">CON_DEVICES_MOBILE</option>
</field>
<field name="@note__agent__device" type="Note"
class="rl-alert alert alert-info rl-alert-light"
text="CON_DEVICES_DESC" />
<field name="@showon__agent__device__b" type="ShowOn" />
<!-- OPERATING SYSTEMS -->
<field name="@showon__agent__os__a" type="ShowOn" value="type:agent__os" />
<field name="agent__os" type="Agents"
group="os" multiple="true" default=""
label="CON_OS" hiddenLabel="true" />
<field name="@note__agent__os" type="Note"
class="rl-alert alert alert-info rl-alert-light"
text="CON_OS_DESC" />
<field name="@showon__agent__os__b" type="ShowOn" />
<!-- BROWSERS -->
<field name="@showon__agent__browser__a" type="ShowOn" value="type:agent__browser" />
<field name="agent__browser" type="Agents"
group="browser" multiple="true" default=""
label="CON_BROWSERS"
hiddenLabel="true" />
<field name="@note__agent__browser" type="Note"
class="rl-alert alert alert-info rl-alert-light"
text="CON_BROWSERS_DESC" />
<field name="@showon__agent__browser__b" type="ShowOn" />
<!-- MOBILE BROWSERS -->
<field name="@showon__agent__browser_mobile__a" type="ShowOn" value="type:agent__browser_mobile" />
<field name="agent__browser_mobile" type="Agents"
group="mobile" multiple="true" default=""
condition="Agent__Browser"
label="CON_MOBILE_BROWSERS" hiddenLabel="true" />
<field name="@note__agent__browser_mobile" type="Note"
class="rl-alert alert alert-info rl-alert-light"
text="CON_BROWSERS_DESC" />
<field name="@showon__agent__browser_mobile__b" type="ShowOn" />
<!-- GEO LOCATION -->
<field name="has_geoip_library" type="IsInstalled"
extension="geoip" extension_type="library" />
<field name="@showon__geo__1a" type="ShowOn"
value="type:geo__continent[OR]type:geo__country[OR]type:geo__region[OR]type:geo__postal_code" />
<field name="@note__geo__no_geoip_library" type="Note"
class="rl-alert alert alert-danger"
text="CON_GEO_NO_GEOIP_LIBRARY,&lt;a href=&quot;https://regularlabs.com/geoip&quot; class=&quot;btn btn-sm btn-success&quot; target=&quot;_blank&quot;&gt;,&lt;/a&gt;"
showon="has_geoip_library:0" />
<field name="@showon__geo__1b" type="ShowOn" />
<!-- IPS -->
<field name="@showon__visitor__ip__a" type="ShowOn" value="type:visitor__ip" />
<field name="visitor__ip" type="Textarea"
default=""
label="CON_IPS" hiddenLabel="true" />
<field name="@note__visitor__ip" type="Note"
class="rl-alert alert alert-info rl-alert-light"
text="CON_IPS_DESC" />
<field name="@showon__visitor__ip__b" type="ShowOn" />
<!-- GEO LOCATION :: CONTINENTS -->
<field name="@showon__geo__continent__a" type="ShowOn" value="type:geo__continent" />
<field name="geo__continent" type="Geo"
group="continents" multiple="true" default=""
label="CON_CONTINENTS"
hiddenLabel="true" />
<field name="@showon__geo__continent__b" type="ShowOn" />
<!-- GEO LOCATION :: COUNTRIES -->
<field name="@showon__geo__country__a" type="ShowOn" value="type:geo__country" />
<field name="geo__country" type="Geo"
group="countries" multiple="true" default=""
label="CON_COUNTRIES"
hiddenLabel="true" />
<field name="@showon__geo__country__b" type="ShowOn" />
<!-- GEO LOCATION :: REGIONS -->
<field name="@showon__geo__region__a" type="ShowOn" value="type:geo__region" />
<field name="geo__region" type="Geo"
group="regions" multiple="true" default=""
label="CON_REGIONS"
hiddenLabel="true" />
<field name="@showon__geo__region__b" type="ShowOn" />
<!-- GEO LOCATION :: POSTAL CODES -->
<field name="@showon__geo__postal_code__a" type="ShowOn" value="type:geo__postal_code" />
<field name="geo__postal_code" type="Textarea"
default=""
label="CON_POSTAL_CODES" hiddenLabel="true" />
<field name="@note__geogeo__postal_code" type="Note"
class="rl-alert alert alert-info rl-alert-light"
text="CON_POSTAL_CODES_DESC,&lt;a href=&quot;https://www.maxmind.com/en/locate-my-ip-address/&quot; target=&quot;_blank&quot;&gt;,&lt;/a&gt;" />
<field name="@showon__geo__postal_code__b" type="ShowOn" />
<!-- GEO LOCATION (footer) -->
<field name="@showon__geo__2a" type="ShowOn"
value="type:geo__continent[OR]type:geo__country[OR]type:geo__region[OR]type:geo__postal_code" />
<field name="@note__geo__info" type="GeoInformation"
showon="has_geoip_library:1" />
<field name="@note__geo" type="Note"
class="rl-alert alert alert-warning"
text="CON_GEO_DESC" />
<field name="@note__geo__has_geoip_library" type="Note"
class="text-muted"
text="CON_GEO_GEOIP_COPYRIGHT_DESC,&lt;a href=&quot;http://www.maxmind.com&quot; target=&quot;_blank&quot;&gt;http://www.maxmind.com&lt;/a&gt;"
showon="has_geoip_library:1" />
<field name="@showon__geo__2b" type="ShowOn" />
<!-- TAGS -->
<field name="@showon__other__tag__a" type="ShowOn" value="type:other__tag" />
<field name="other__tag" type="Tags"
multiple="true" default=""
label="CON_TAGS" hiddenLabel="true" />
<field name="other__tag__match_all" type="Radio"
default="0" class="btn-group rl-btn-group btn-group-md btn-group-yesno"
label="CON_MATCH_ALL"
description="CON_MATCH_ALL_DESC">
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field name="@showon__other__tag__match_all__a" type="ShowOn" value="other__tag__match_all:0" />
<field name="other__tag__include_children" type="Radio"
default="0" class="btn-group rl-btn-group btn-group-md btn-group-yesno"
label="CON_INCLUDE_CHILD_ITEMS">
<option value="0">JNO</option>
<option value="1">JYES</option>
<option value="2" class="btn btn-outline-info">CON_ONLY</option>
</field>
<field name="@showon__other__tag__match_all__b" type="ShowOn" />
<field name="@showon__other__tag__b" type="ShowOn" />
<!-- COMPONENTS -->
<field name="@showon__other__component__a" type="ShowOn" value="type:other__component" />
<field name="other__component" type="Components"
multiple="true" admin="true" show_content="true" default=""
label="CON_COMPONENTS" hiddenLabel="true" />
<field name="@showon__other__component__b" type="ShowOn" />
<!-- TEMPLATES -->
<field name="@showon__other__template__a" type="ShowOn" value="type:other__template" />
<field name="other__template" type="Templates"
multiple="true" default=""
label="CON_TEMPLATES"
hiddenLabel="true" />
<field name="@showon__other__template__b" type="ShowOn" />
<!-- URLS -->
<field name="@showon__other__url__a" type="ShowOn" value="type:other__url" />
<field name="other__url" type="Textarea"
default=""
label="CON_URLS" hiddenLabel="true" />
<field name="@note__other__url" type="Note"
class="rl-alert alert alert-info rl-alert-light"
text="CON_URLS_DESC" />
<field name="other__url__case_sensitive" type="Radio"
default="0" class="btn-group rl-btn-group btn-group-md btn-group-yesno"
label="RL_CASE_SENSITIVE">
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field name="other__url__regex" type="Radio"
default="0" class="btn-group rl-btn-group btn-group-md btn-group-yesno"
label="CON_REGULAR_EXPRESSIONS">
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field name="@showon__other__url__regex__a" type="ShowOn" value="other__url__regex:1" />
<field name="@note__other__url__regex" type="Note"
class="rl-alert alert alert-warning"
text="CON_URL_PARTS_REGEX" />
<field name="@showon__other__url__regex__b" type="ShowOn" />
<field name="@showon__other__url__b" type="ShowOn" />
<!-- PHP -->
<field name="@showon__other__php__a" type="ShowOn" value="type:other__php" />
<field name="other__php" type="Editor"
editor="codemirror" syntax="php"
height="120" default=""
label="CON_PHP"
hiddenLabel="true" />
<field name="@note__other__php" type="Note"
class="rl-alert alert alert-info rl-alert-light"
text="CON_PHP_DESC,&lt;pre>return ( $user->name == 'Peter van Westen' );&lt;/pre>" />
<field name="@showon__other__php__b" type="ShowOn" />
<!-- OTHER CONDITION SET -->
<field name="@showon__other__condition__a" type="ShowOn" value="type:other__condition" />
<field name="other__condition" type="ConditionSelection"
default=""
label="CON_OTHER_CONDITION"
hiddenLabel="true" />
<field name="@showon__other__condition__b" type="ShowOn" />
<!-- &lt;!&ndash; EASYBLOG &ndash;&gt;-->
<!-- <field name="@has_easyblog" type="IsInstalled" extension="easyblog" />-->
<!-- <field name="@showon__easyblog__a" type="ShowOn" value="@has_easyblog:1" />-->
<!-- <field name="@load_language_easyblog_sys" type="LoadLanguage" extension="com_easyblog.sys" />-->
<!-- &lt;!&ndash; EASYBLOG :: PAGE TYPES &ndash;&gt;-->
<!-- <field name="@showon__easyblog__page_type__a" type="ShowOn" value="type:easyblog__page_type" />-->
<!-- <field name="easyblog__page_type" type="List"-->
<!-- multiple="true" default=""-->
<!-- layout="joomla.form.field.list-fancy-select"-->
<!-- label="CON_PAGE_TYPES" hiddenLabel="true">-->
<!-- <option value="archive">COM_EASYBLOG_MENU_ARCHIVE_LAYOUT</option>-->
<!-- <option value="blogger">COM_EASYBLOG_MENU_BLOGGERS_LAYOUT</option>-->
<!-- <option value="categories">COM_EASYBLOG_MENU_CATEGORIES_LAYOUT</option>-->
<!-- <option value="dashboard">COM_EASYBLOG_MENU_DASHBOARD_LAYOUT</option>-->
<!-- <option value="entry">COM_EASYBLOG_MENU_ENTRY_LAYOUT</option>-->
<!-- <option value="featured">COM_EASYBLOG_MENU_FEATURED_LAYOUT</option>-->
<!-- <option value="grid">COM_EASYBLOG_GRID_MENU_LAYOUT</option>-->
<!-- <option value="latest">COM_EASYBLOG_MENU_FRONTPAGE_LAYOUT</option>-->
<!-- <option value="login">COM_EASYBLOG_MENU_LOGIN</option>-->
<!-- <option value="magazine">COM_EASYBLOG_MAGAZINE_MENU_LAYOUT</option>-->
<!-- <option value="myblog">COM_EASYBLOG_MENU_MYBLOG_LAYOUT</option>-->
<!-- <option value="search">COM_EASYBLOG_MENU_SEARCH_LAYOUT</option>-->
<!-- <option value="subscription">COM_EASYBLOG_MENU_SUBSCRIPTION_LAYOUT</option>-->
<!-- <option value="tags">COM_EASYBLOG_MENU_TAGS_LAYOUT</option>-->
<!-- <option value="teamblog">COM_EASYBLOG_MENU_TEAMBLOG_LAYOUT</option>-->
<!-- </field>-->
<!-- <field name="@showon__easyblog__page_type__b" type="ShowOn" />-->
<!-- &lt;!&ndash; EASYBLOG :: CATEGORIES &ndash;&gt;-->
<!-- <field name="@showon__easyblog__category__a" type="ShowOn" value="type:easyblog__category" />-->
<!-- <field name="easyblog__category" type="EasyblogCategories"-->
<!-- multiple="true" default=""-->
<!-- label="CON_CATEGORIES"-->
<!-- hiddenLabel="true" />-->
<!-- <field name="easyblog__category__include_children" type="Radio"-->
<!-- default="0" class="btn-group rl-btn-group btn-group-md btn-group-yesno"-->
<!-- label="CON_INCLUDE_CHILD_ITEMS">-->
<!-- <option value="0">JNO</option>-->
<!-- <option value="1">JYES</option>-->
<!-- <option value="2" class="btn btn-outline-info">CON_ONLY</option>-->
<!-- </field>-->
<!-- <field name="easyblog__category__page_types" type="Checkboxes"-->
<!-- default="categories,items"-->
<!-- label="CON_PAGE_TYPES">-->
<!-- <option value="categories">RL_CATEGORIES</option>-->
<!-- <option value="items">RL_PRODUCTS</option>-->
<!-- </field>-->
<!-- <field name="@showon__easyblog__category__b" type="ShowOn" />-->
<!-- &lt;!&ndash; EASYBLOG :: ITEMS &ndash;&gt;-->
<!-- <field name="@showon__easyblog__item__a" type="ShowOn" value="type:easyblog__item" />-->
<!-- <field name="easyblog__item" type="EasyblogItems"-->
<!-- multiple="true" default=""-->
<!-- label="CON_ARTICLES"-->
<!-- hiddenLabel="true" />-->
<!-- <field name="@showon__easyblog__item__b" type="ShowOn" />-->
<!-- <field name="@showon__easyblog__b" type="ShowOn" />-->
<!-- FLEXICONTENT -->
<field name="@has_flexicontent" type="IsInstalled" extension="flexicontent" />
<field name="@showon__flexicontent__a" type="ShowOn" value="@has_flexicontent:1" />
<field name="@load_language_flexicontent_sys" type="LoadLanguage" extension="com_flexicontent.sys" />
<!-- FLEXICONTENT :: PAGE TYPES -->
<field name="@showon__flexicontent__page_type__a" type="ShowOn" value="type:flexicontent__page_type" />
<field name="flexicontent__page_type" type="List"
multiple="true" default=""
layout="joomla.form.field.list-fancy-select"
label="CON_PAGE_TYPES" hiddenLabel="true">
<option value="category_author">FLEXICONTENT_AUTHORED_ITEMS</option>
<option value="category_mcats">FLEXICONTENT_MCATS</option>
<option value="category">FLEXICONTENT_CATEGORY</option>
<option value="item">FLEXICONTENT_ITEM</option>
<option value="category_favs">FLEXICONTENT_FAVOURED_CATVIEW</option>
<option value="favourites">FLEXICONTENT_FAVOURED_LEGACY_VIEW</option>
<option value="category_myitems">FLEXICONTENT_MYITEMS</option>
<option value="search">FLEXICONTENT_SEARCH_VIEW</option>
<option value="category_tags">FLEXICONTENT_TAGGED_CATVIEW</option>
<option value="tags">FLEXICONTENT_TAGGED_LEGACY_VIEW</option>
</field>
<field name="@showon__flexicontent__page_type__b" type="ShowOn" />
<!-- FLEXICONTENT :: TAGS -->
<field name="@showon__flexicontent__tag__a" type="ShowOn" value="type:flexicontent__tag" />
<field name="flexicontent__tag" type="FlexicontentTags"
multiple="true" default=""
label="CON_TAGS"
hiddenLabel="true" />
<field name="flexicontent__tag__page_types" type="Checkboxes"
default="tags,items"
label="CON_PAGE_TYPES">
<option value="tags">CON_TAGS</option>
<option value="items">CON_ITEMS</option>
</field>
<field name="@showon__flexicontent__tag__b" type="ShowOn" />
<!-- FLEXICONTENT :: TYPES -->
<field name="@showon__flexicontent__type__a" type="ShowOn" value="type:flexicontent__type" />
<field name="flexicontent__type" type="FlexicontentTypes"
multiple="true" default=""
label="CON_TYPES"
hiddenLabel="true" />
<field name="@showon__flexicontent__type__b" type="ShowOn" />
<field name="@showon__flexicontent__b" type="ShowOn" />
<!-- HIKASHOP -->
<field name="@has_hikashop" type="IsInstalled" extension="hikashop" />
<field name="@showon__hikashop__a" type="ShowOn" value="@has_hikashop:1" />
<field name="@load_language_hikashop_sys" type="LoadLanguage" extension="com_hikashop.sys" />
<!-- HIKASHOP :: PAGE TYPES -->
<field name="@showon__hikashop__page_type__a" type="ShowOn" value="type:hikashop__page_type" />
<field name="hikashop__page_type" type="List"
multiple="true" default=""
layout="joomla.form.field.list-fancy-select"
label="CON_PAGE_TYPES" hiddenLabel="true">
<option value="address">COM_HIKASHOP_ADDRESS_VIEW_DEFAULT_TITLE</option>
<option value="category">COM_HIKASHOP_CATEGORY_VIEW_DEFAULT_TITLE</option>
<option value="checkout">COM_HIKASHOP_CHECKOUT_VIEW_DEFAULT_TITLE</option>
<option value="order">COM_HIKASHOP_ORDER_VIEW_DEFAULT_TITLE</option>
<option value="product_contact">COM_HIKASHOP_CONTACT_VIEW_DEFAULT_TITLE</option>
<option value="product">COM_HIKASHOP_PRODUCT_VIEW_DEFAULT_TITLE</option>
<option value="product_show">COM_HIKASHOP_PRODUCT_FORM_VIEW_DEFAULT_TITLE</option>
<option value="user_cpanel">COM_HIKASHOP_USER_PANEL_VIEW_DEFAULT_TITLE</option>
<option value="user">COM_HIKASHOP_USER_VIEW_DEFAULT_TITLE</option>
<option value="user_downloads">COM_HIKASHOP_DOWNLOADS_VIEW_DEFAULT_TITLE</option>
</field>
<field name="@showon__hikashop__page_type__b" type="ShowOn" />
<!-- HIKASHOP :: CATEGORIES -->
<field name="@showon__hikashop__category__a" type="ShowOn" value="type:hikashop__category" />
<field name="hikashop__category" type="HikashopCategories"
multiple="true" default=""
label="CON_CATEGORIES"
hiddenLabel="true" />
<field name="hikashop__category__include_children" type="Radio"
default="0" class="btn-group rl-btn-group btn-group-md btn-group-yesno"
label="CON_INCLUDE_CHILD_ITEMS">
<option value="0">JNO</option>
<option value="1">JYES</option>
<option value="2" class="btn btn-outline-info">CON_ONLY</option>
</field>
<field name="hikashop__category__page_types" type="Checkboxes"
default="categories,items"
label="CON_PAGE_TYPES">
<option value="categories">RL_CATEGORIES</option>
<option value="items">RL_PRODUCTS</option>
</field>
<field name="@showon__hikashop__category__b" type="ShowOn" />
<!-- HIKASHOP :: PRODUCTS -->
<field name="@showon__hikashop__item__a" type="ShowOn" value="type:hikashop__item" />
<field name="hikashop__item" type="HikashopItems"
multiple="true" default=""
label="CON_ARTICLES"
hiddenLabel="true" />
<field name="@showon__hikashop__item__b" type="ShowOn" />
<field name="@showon__hikashop__b" type="ShowOn" />
<!-- ZOO -->
<field name="@has_zoo" type="IsInstalled" extension="zoo" />
<field name="@showon__zoo__a" type="ShowOn" value="@has_zoo:1" />
<field name="@load_language_zoo_sys" type="LoadLanguage" extension="com_zoo.sys" />
<!-- ZOO :: PAGE TYPES -->
<field name="@showon__zoo__page_type__a" type="ShowOn" value="type:zoo__page_type" />
<field name="zoo__page_type" type="List"
multiple="true" default=""
layout="joomla.form.field.list-fancy-select"
label="CON_PAGE_TYPES" hiddenLabel="true">
<option value="category">CATEGORY</option>
<option value="item">ITEM</option>
<option value="frontpage">FRONTPAGE</option>
<option value="mysubmissions">MY SUBMISSIONS</option>
<option value="submissions">SUBMISSION</option>
</field>
<field name="@showon__zoo__page_type__b" type="ShowOn" />
<!-- ZOO :: CATEGORIES -->
<field name="@showon__zoo__category__a" type="ShowOn" value="type:zoo__category" />
<field name="zoo__category" type="ZooCategories"
multiple="true" default=""
label="CON_CATEGORIES"
hiddenLabel="true" />
<field name="zoo__category__include_children" type="Radio"
default="0" class="btn-group rl-btn-group btn-group-md btn-group-yesno"
label="CON_INCLUDE_CHILD_ITEMS">
<option value="0">JNO</option>
<option value="1">JYES</option>
<option value="2" class="btn btn-outline-info">CON_ONLY</option>
</field>
<field name="zoo__category__page_types" type="Checkboxes"
default="categories,items"
label="CON_PAGE_TYPES">
<option value="categories">RL_CATEGORIES</option>
<option value="items">RL_ITEMS</option>
</field>
<field name="@showon__zoo__category__b" type="ShowOn" />
<!-- ZOO :: PRODUCTS -->
<field name="@showon__zoo__item__a" type="ShowOn" value="type:zoo__item" />
<field name="zoo__item" type="ZooItems"
multiple="true" default=""
label="RL_ITEMS"
hiddenLabel="true" />
<field name="@showon__zoo__item__b" type="ShowOn" />
<field name="@showon__zoo__b" type="ShowOn" />
</fieldset>
</form>

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<form>
<fieldset>
<field name="key" type="Text"
required="true"
label="CON_KEY"
description="CON_KEY_DESC" />
<field name="default" type="Text"
label="CON_DEFAULT_VALUE"
description="CON_DEFAULT_VALUE_DESC" />
<field name="insert_in_tag" type="Radio"
class="btn-group rl-btn-group btn-group-md btn-group-yesno" default="1"
label="CON_INSERT_IN_TAG"
description="CON_INSERT_IN_TAG_DESC">
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
</fieldset>
</form>

View File

@ -0,0 +1,186 @@
;; @package Conditions
;; @version 24.11.1459
;;
;; @author Peter van Westen <info@regularlabs.com>
;; @link https://regularlabs.com
;; @copyright Copyright © 2024 Regular Labs All Rights Reserved
;; @license GNU General Public License version 2 or later
;;
;; @translate Want to help with translations? See: https://regularlabs.com/translate
COM_CONDITIONS="Regular Labs - Conditions"
COM_CONDITIONS_DESC="Conditions - manage your conditions used in other extensions in Joomla!"
COM_CONDITIONS_CONFIGURATION="Conditions"
CONDITIONS="Conditions"
CON_EXTENSION_CAN_NOT_FUNCTION="[[%1:extension name%]] cannot function."
CON_REGULAR_LABS_LIBRARY_NOT_ENABLED="Regular Labs Library plugin is not enabled."
CON_REGULAR_LABS_LIBRARY_NOT_INSTALLED="Regular Labs Library plugin is not installed."
CON_3RD_PARTY_EXTENSIONS="3rd Party Extensions"
CON_ACCESS_LEVELS="Access Levels"
CON_ADD_GROUP="Add Group"
CON_ADD_RULE="Add Rule"
CON_ALL="ALL"
CON_ALL_DESC="<strong>All</strong> the condition rules below should pass."
CON_AND="AND"
CON_ANY="ANY"
CON_ANY_DESC="<strong>Only one</strong> (or more) of the condition rules below should pass."
CON_ARTICLE_AUTHORS="Article Authors"
CON_ARTICLE_CONTENT_KEYWORDS="Article Content Keywords"
CON_ARTICLE_DATE="Article Date"
CON_ARTICLE_FEATURED="Featured Articles"
CON_ARTICLE_FIELD="Article Field"
CON_ARTICLE_META_KEYWORDS="Article Meta Keywords"
CON_ARTICLE_STATUS="Article Publish State"
CON_ARTICLES="Articles"
CON_AUSTRALIA="Australia"
CON_AUTHORS="Authors"
CON_BETWEEN_A_AND_B="Between [[%1:first%]] and [[%2:second%]]"
CON_BETWEEN_A_AND_B_EVERY_YEAR="Between [[%1:first%]] and [[%2:second%]] every year"
CON_BROWSERS="Browsers"
CON_BROWSERS_DESC="Select the browsers to assign to. Keep in mind that browser detection is not always 100&#37; accurate. Users can setup their browser to mimic other browsers"
CON_BUTTON_CONFIRM_COPY="Make a copy<br><small>of the condition set for the current item[[%1:item name%]]</small>"
CON_BUTTON_CONFIRM_EDIT="Edit<br><small>condition set for <strong>ALL</strong> items</small>"
CON_BUTTON_CONFIRM_REMOVE_BUT_KEEP="Remove<br><small>condition set from item[[%1:item name%]]<br>but keep it available for others</small>"
CON_BUTTON_CONFIRM_REMOVE_COMPLETELY="Remove<br><small>condition set <strong>completely</strong></small>"
CON_BUTTON_COPY="Copy Condition Set"
CON_BUTTON_CREATE="Create New Condition Set"
CON_BUTTON_EDIT="Edit Condition Set"
CON_BUTTON_REMOVE="Remove Condition Set"
CON_BUTTON_SELECT="Select existing Condition Set"
CON_CATEGORIES="Categories"
CON_COMMA_SEPARATED_DESC="Use commas to separate the keywords."
CON_COMPARISON="Comparison"
CON_COMPARISON_BEGINS_WITH="Begins with"
CON_COMPARISON_CONTAINS="Contains"
CON_COMPARISON_CONTAINS_ONE="Contains one of"
CON_COMPARISON_ENDS_WITH="Ends with"
CON_COMPARISON_EQUALS="Is equal to"
CON_COMPARISON_GREATER_THAN="Is greater than"
CON_COMPARISON_LESS_THAN="Is Less than"
CON_COMPARISON_NOT_CONTAINS="Does not contain"
CON_COMPARISON_NOT_EQUALS="Is not equal to"
CON_COMPARISON_REGEX="Matches Regular Expression"
CON_COMPONENTS="Components"
CON_CONDITION="Condition"
CON_CONDITION_SET="Condition Set"
CON_CONDITION_SET_UNPUBLISHED="This Condition Set is unpublished and won't have any affect items using it."
CON_CONDITIONS="Conditions"
CON_CONTINENT="Continent"
CON_CONTINENTS="Continents"
CON_COUNTRIES="Countries"
CON_COUNTRY="Country"
CON_CURRENT_DATE="Current date/time: <strong>%s</strong>"
CON_DATE="Date"
CON_DATE_AFTER="After"
CON_DATE_BEFORE="Before"
CON_DATE_BETWEEN="Between"
CON_DATE_FROM="From"
CON_DATE_RECURRING="Recurring"
CON_DATE_RECURRING_DESC="Select to apply date range every year. (So the year in the selection will be ignored)"
CON_DATE_TIME="Date & Time"
CON_DATE_TIME_DESC="The date and time assignments use the date/time of your servers, not that of the visitors system."
CON_DATE_TO="To"
CON_DAYS="Days"
CON_DEVICES="Devices"
CON_DEVICES_DESC="Select the devices to assign to. Keep in mind that device detection is not always 100&#37; accurate. Users can setup their device to mimic other devices"
CON_DEVICES_DESKTOP="Desktop"
CON_DEVICES_MOBILE="Mobile"
CON_DEVICES_TABLET="Tablet"
CON_DISABLED_RULE_TYPES="Disabled Rule Types"
CON_DISABLED_RULE_TYPES_DESC="Select the rule types you do NOT want to be available to use in the conditions. Rule types you select will no longer show up, and will stop working on conditions that already use them."
CON_EASYBLOG="EasyBlog"
CON_EXCLUDE="Exclude"
CON_EXTENSION_ITEM="[[%1:extension name%]] item"
CON_FALL="Fall"
CON_FIELD="Field"
CON_FIELD_VALUE="Field Value"
CON_FINISH_PUBLISHING="Finish Publishing"
CON_FLEXICONTENT="FLEXIcontent"
CON_FOR_ITEM="For [[%1:extension item%]]: [[%2:item name%]]"
CON_GEO_CURRENT_DETAILS="Your current GeoLocation details according to the GeoIP library, based on your current IP address:"
CON_GEO_DESC="Geolocating is not always 100&#37; accurate. The geolocation is based on the IP address of the visitor. Not all IP addresses are fixed or known."
CON_GEO_GEOIP_COPYRIGHT_DESC="This product includes GeoLite2 data created by MaxMind, available from [[%1:link%]]"
CON_GEO_NO_GEOIP_LIBRARY="The Regular Labs GeoIP library is not installed. You need to [[%1:link start%]]install the Regular Labs GeoIP library[[%2:link end%]] to be able to use the Geolocating assignments."
CON_GEOLOCATION="Geolocation"
CON_HAS_CONDITIONS="Has Conditions"
CON_HEMISPHERE="Hemisphere"
CON_HIKASHOP="HikaShop"
CON_HOME_PAGE="Home Page"
CON_HOME_PAGE_DESC="Unlike selecting the home page (default) item via the Menu Items, this will only match the real home page, not any URL that has the same Itemid as the home menu item.<br><br>This might not work for all 3rd party SEF extensions."
CON_IGNORE="Ignore"
CON_INCLUDE="Include"
CON_INCLUDE_CHILD_CATEGORIES="Include child categories"
CON_INCLUDE_CHILD_ITEMS="Also on child items"
CON_INCLUDE_CHILD_ITEMS_MENU_ITEMS_DESC="The child items refer to actual sub-items in the above selection. They do not refer to links on selected pages."
CON_INCLUDE_NO_ITEMID="Include no Itemid"
CON_INCLUDE_NO_ITEMID_DESC="Select to also include pages where no menu Itemid is set in URL."
CON_IPS="IP Addresses"
CON_IPS_DESC="A comma and/or enter separated list of IP addresses and IP ranges. For instance:<br>127.0.0.1<br>128.0-128.1<br>129"
CON_ITEMS="Items"
CON_JOOMLA_CONTENT="Joomla Content"
CON_LANGUAGES="Languages"
CON_MATCH_ALL="Match All"
CON_MATCH_ALL_DESC="Select to only pass if all of the selected items are matched."
CON_MATCHING_METHOD_DESC="Should all or any of the condition rules be met?<br><br><strong>[[%1:all%]]</strong><br>[[%2:all description%]]<br><br><strong>[[%3:any%]]</strong><br>[[%4:any description%]]"
CON_MENU_ITEMS="Menu Items"
CON_MESSAGE_ITEM_HAS_NO_CONDITIONS="The items using this condition will not be"
CON_MESSAGE_NO_CONDITION_SELECTED="No condition set has been selected yet..."
CON_MESSAGE_NO_RULES_SELECTED="No condition rules have been selected yet..."
CON_MESSAGE_SAVE_AS_UNPUBLISHED="To prevent the [[%1:item name%]] to be active on all pages before adding the conditions, you can save the item as unpublished first."
CON_MESSAGE_SAVE_ITEM_BEFORE_CREATING="You need to save the item before it is possible to add conditions."
CON_MISCELLANEOUS="Miscellaneous"
CON_MOBILE_BROWSERS="Mobile Browsers"
CON_MONTHS="Months"
CON_NONE="None"
CON_NORTHERN="Northern"
CON_NOT_SPECIFIED="Not specified"
CON_NOT_USED="This condition set is not being used yet."
CON_NOW="Now"
CON_ONLY="Only"
CON_ONLY_ITEM_USING_CONDITION="This is the only item using this condition set."
CON_OR="OR"
CON_OS="Operating Systems"
CON_OS_DESC="Select the operating systems to assign to. Keep in mind that operating system detection is not always 100&#37; accurate. Users can setup their browser to mimic other operating systems."
CON_OTHER_CONDITION="Other Condition Set"
CON_PAGE_TYPES="Page Types"
CON_PHP="Custom PHP"
CON_PHP_DESC="Enter a piece of PHP code to evaluate. The code must return the value true or false.<br><br>For instance:<br><br>[[%1:code%]]"
CON_POSTAL_CODE="Postal Code"
CON_POSTAL_CODES="Postal Codes"
CON_POSTAL_CODES_DESC="A comma separated list of postal codes (12345) or postal code ranges (12300-12500).<br>This can only be used for [[%1:start link%]]a limited number of countries and IP addresses[[%2:end link%]]."
CON_PRODUCTS="Products"
CON_REGION="Region"
CON_REGIONS="Regions"
CON_REGULAR_EXPRESSIONS="Regular Expressions"
CON_RULE="Rule"
CON_RULES="Rules"
CON_SAVE_AS_PUBLISHED="Save as Published"
CON_SAVE_AS_UNPUBLISHED="Save as Unpublished"
CON_SEASONS="Seasons"
CON_SELECT_A_CONDITION="Select a Condition Set"
CON_SELECT_A_RULE_TYPE="Select a Rule Type"
CON_SOUTHERN="Southern"
CON_SPECIFY="Specify"
CON_SPRING="Spring"
CON_START_PUBLISHING="Start Publishing"
CON_SUMMARY="Summary"
CON_SUMMER="Summer"
CON_TAGS="Tags"
CON_TEMPLATES="Templates"
CON_TIME="Time"
CON_TYPES="Types"
CON_URL_PARTS_REGEX="Url parts will be matched using regular expressions. <strong>So make sure the string uses valid regex syntax.</strong>"
CON_URLS="URLs"
CON_URLS_DESC="Enter (part of) the URLs to match.<br>Use a new line for each different match."
CON_USAGE="Usage"
CON_USED_ON="This condition set is being used by these items:"
CON_USER_GROUPS="User Groups"
CON_USERS="Users"
CON_VIRTUEMART="VirtueMart"
CON_VISITORS="Visitors"
CON_WARNING_FOR_EDITING_MULTIPLE_USAGE="Be careful!<br>Saving this will affect all items using this condition set!"
CON_WHAT_TO_DO="What do you want to do?"
CON_WINTER="Winter"
CON_ZOO="Zoo"

View File

@ -0,0 +1,13 @@
;; @package Conditions
;; @version 24.11.1459
;;
;; @author Peter van Westen <info@regularlabs.com>
;; @link https://regularlabs.com
;; @copyright Copyright © 2024 Regular Labs All Rights Reserved
;; @license GNU General Public License version 2 or later
;;
;; @translate Want to help with translations? See: https://regularlabs.com/translate
COM_CONDITIONS="Regular Labs - Conditions"
COM_CONDITIONS_DESC="Conditions - manage your conditions used in other extensions in Joomla!"
CONDITIONS="Conditions"

View File

@ -0,0 +1,186 @@
;; @package Conditions
;; @version 24.11.1459
;;
;; @author Peter van Westen <info@regularlabs.com>
;; @link https://regularlabs.com
;; @copyright Copyright © 2024 Regular Labs All Rights Reserved
;; @license GNU General Public License version 2 or later
;;
;; @translate Want to help with translations? See: https://regularlabs.com/translate
; COM_CONDITIONS="Regular Labs - Conditions"
; COM_CONDITIONS_DESC="Conditions - manage your conditions used in other extensions in Joomla!"
COM_CONDITIONS_CONFIGURATION="Condizioni"
CONDITIONS="Condizioni"
CON_EXTENSION_CAN_NOT_FUNCTION="[[%1:extension name%]] non può funzionare."
CON_REGULAR_LABS_LIBRARY_NOT_ENABLED="Il plugin Regular Labs Library non è abilitato."
CON_REGULAR_LABS_LIBRARY_NOT_INSTALLED="Il plugin Regular Labs Library non è installato."
; CON_3RD_PARTY_EXTENSIONS="3rd Party Extensions"
; CON_ACCESS_LEVELS="Access Levels"
; CON_ADD_GROUP="Add Group"
; CON_ADD_RULE="Add Rule"
CON_ALL="TUTTO"
; CON_ALL_DESC="<strong>All</strong> the condition rules below should pass."
; CON_AND="AND"
CON_ANY="QUALSIASI"
; CON_ANY_DESC="<strong>Only one</strong> (or more) of the condition rules below should pass."
; CON_ARTICLE_AUTHORS="Article Authors"
; CON_ARTICLE_CONTENT_KEYWORDS="Article Content Keywords"
; CON_ARTICLE_DATE="Article Date"
; CON_ARTICLE_FEATURED="Featured Articles"
; CON_ARTICLE_FIELD="Article Field"
; CON_ARTICLE_META_KEYWORDS="Article Meta Keywords"
; CON_ARTICLE_STATUS="Article Publish State"
CON_ARTICLES="Articoli"
CON_AUSTRALIA="Australia"
CON_AUTHORS="Autori"
; CON_BETWEEN_A_AND_B="Between [[%1:first%]] and [[%2:second%]]"
; CON_BETWEEN_A_AND_B_EVERY_YEAR="Between [[%1:first%]] and [[%2:second%]] every year"
CON_BROWSERS="Browsers"
CON_BROWSERS_DESC="Seleziona i browsers a cui assengnare. Ricorda che il determinatore di browser non è mai 100&#37a prova di errore. Gli utenti possono configurare il loro browser per imitarne altri."
; CON_BUTTON_CONFIRM_COPY="Make a copy<br><small>of the condition set for the current item[[%1:item name%]]</small>"
; CON_BUTTON_CONFIRM_EDIT="Edit<br><small>condition set for <strong>ALL</strong> items</small>"
; CON_BUTTON_CONFIRM_REMOVE_BUT_KEEP="Remove<br><small>condition set from item[[%1:item name%]]<br>but keep it available for others</small>"
; CON_BUTTON_CONFIRM_REMOVE_COMPLETELY="Remove<br><small>condition set <strong>completely</strong></small>"
; CON_BUTTON_COPY="Copy Condition Set"
; CON_BUTTON_CREATE="Create New Condition Set"
; CON_BUTTON_EDIT="Edit Condition Set"
; CON_BUTTON_REMOVE="Remove Condition Set"
; CON_BUTTON_SELECT="Select existing Condition Set"
CON_CATEGORIES="Categorie"
; CON_COMMA_SEPARATED_DESC="Use commas to separate the keywords."
; CON_COMPARISON="Comparison"
; CON_COMPARISON_BEGINS_WITH="Begins with"
; CON_COMPARISON_CONTAINS="Contains"
; CON_COMPARISON_CONTAINS_ONE="Contains one of"
; CON_COMPARISON_ENDS_WITH="Ends with"
; CON_COMPARISON_EQUALS="Is equal to"
; CON_COMPARISON_GREATER_THAN="Is greater than"
; CON_COMPARISON_LESS_THAN="Is Less than"
; CON_COMPARISON_NOT_CONTAINS="Does not contain"
; CON_COMPARISON_NOT_EQUALS="Is not equal to"
; CON_COMPARISON_REGEX="Matches Regular Expression"
CON_COMPONENTS="Componenti"
; CON_CONDITION="Condition"
; CON_CONDITION_SET="Condition Set"
; CON_CONDITION_SET_UNPUBLISHED="This Condition Set is unpublished and won't have any affect items using it."
CON_CONDITIONS="Condizioni"
; CON_CONTINENT="Continent"
CON_CONTINENTS="Continenti"
CON_COUNTRIES="Nazioni"
; CON_COUNTRY="Country"
CON_CURRENT_DATE="Data/ora attuale: <strong>%s</strong>"
CON_DATE="Data"
; CON_DATE_AFTER="After"
; CON_DATE_BEFORE="Before"
; CON_DATE_BETWEEN="Between"
; CON_DATE_FROM="From"
CON_DATE_RECURRING="Periodico"
; CON_DATE_RECURRING_DESC="Select to apply date range every year. (So the year in the selection will be ignored)"
CON_DATE_TIME="Data & Ora"
CON_DATE_TIME_DESC="Parametri data ed ora usano l'orario dei tuoi server, non quello del sistema del visitatore."
; CON_DATE_TO="To"
; CON_DAYS="Days"
; CON_DEVICES="Devices"
; CON_DEVICES_DESC="Select the devices to assign to. Keep in mind that device detection is not always 100&#37; accurate. Users can setup their device to mimic other devices"
; CON_DEVICES_DESKTOP="Desktop"
; CON_DEVICES_MOBILE="Mobile"
; CON_DEVICES_TABLET="Tablet"
; CON_DISABLED_RULE_TYPES="Disabled Rule Types"
; CON_DISABLED_RULE_TYPES_DESC="Select the rule types you do NOT want to be available to use in the conditions. Rule types you select will no longer show up, and will stop working on conditions that already use them."
CON_EASYBLOG="EasyBlog"
CON_EXCLUDE="Escludi"
; CON_EXTENSION_ITEM="[[%1:extension name%]] item"
; CON_FALL="Fall"
; CON_FIELD="Field"
CON_FIELD_VALUE="Valore campo"
CON_FINISH_PUBLISHING="Termine Pubblicazione"
CON_FLEXICONTENT="FLEXIcontent"
; CON_FOR_ITEM="For [[%1:extension item%]]: [[%2:item name%]]"
; CON_GEO_CURRENT_DETAILS="Your current GeoLocation details according to the GeoIP library, based on your current IP address:"
; CON_GEO_DESC="Geolocating is not always 100&#37; accurate. The geolocation is based on the IP address of the visitor. Not all IP addresses are fixed or known."
; CON_GEO_GEOIP_COPYRIGHT_DESC="This product includes GeoLite2 data created by MaxMind, available from [[%1:link%]]"
; CON_GEO_NO_GEOIP_LIBRARY="The Regular Labs GeoIP library is not installed. You need to [[%1:link start%]]install the Regular Labs GeoIP library[[%2:link end%]] to be able to use the Geolocating assignments."
; CON_GEOLOCATION="Geolocation"
; CON_HAS_CONDITIONS="Has Conditions"
CON_HEMISPHERE="Emisfero"
CON_HIKASHOP="HikaShop"
CON_HOME_PAGE="Home Page"
; CON_HOME_PAGE_DESC="Unlike selecting the home page (default) item via the Menu Items, this will only match the real home page, not any URL that has the same Itemid as the home menu item.<br><br>This might not work for all 3rd party SEF extensions."
CON_IGNORE="Ignora"
CON_INCLUDE="Includi"
; CON_INCLUDE_CHILD_CATEGORIES="Include child categories"
CON_INCLUDE_CHILD_ITEMS="Anche sugli elementi figli"
; CON_INCLUDE_CHILD_ITEMS_MENU_ITEMS_DESC="The child items refer to actual sub-items in the above selection. They do not refer to links on selected pages."
CON_INCLUDE_NO_ITEMID="Inclidi no Itemid"
; CON_INCLUDE_NO_ITEMID_DESC="Select to also include pages where no menu Itemid is set in URL."
; CON_IPS="IP Addresses"
; CON_IPS_DESC="A comma and/or enter separated list of IP addresses and IP ranges. For instance:<br>127.0.0.1<br>128.0-128.1<br>129"
CON_ITEMS="Elementi"
; CON_JOOMLA_CONTENT="Joomla Content"
CON_LANGUAGES="Lingue"
; CON_MATCH_ALL="Match All"
; CON_MATCH_ALL_DESC="Select to only pass if all of the selected items are matched."
; CON_MATCHING_METHOD_DESC="Should all or any of the condition rules be met?<br><br><strong>[[%1:all%]]</strong><br>[[%2:all description%]]<br><br><strong>[[%3:any%]]</strong><br>[[%4:any description%]]"
CON_MENU_ITEMS="Voci di Menu"
; CON_MESSAGE_ITEM_HAS_NO_CONDITIONS="The items using this condition will not be"
; CON_MESSAGE_NO_CONDITION_SELECTED="No condition set has been selected yet..."
; CON_MESSAGE_NO_RULES_SELECTED="No condition rules have been selected yet..."
; CON_MESSAGE_SAVE_AS_UNPUBLISHED="To prevent the [[%1:item name%]] to be active on all pages before adding the conditions, you can save the item as unpublished first."
; CON_MESSAGE_SAVE_ITEM_BEFORE_CREATING="You need to save the item before it is possible to add conditions."
; CON_MISCELLANEOUS="Miscellaneous"
CON_MOBILE_BROWSERS="Browser Mobili"
CON_MONTHS="Mesi"
; CON_NONE="None"
CON_NORTHERN="Nord"
; CON_NOT_SPECIFIED="Not specified"
; CON_NOT_USED="This condition set is not being used yet."
; CON_NOW="Now"
CON_ONLY="Solo"
; CON_ONLY_ITEM_USING_CONDITION="This is the only item using this condition set."
; CON_OR="OR"
CON_OS="Sistemi Operativi"
CON_OS_DESC="Scegli i sistemi operativi cui assegnare. Tieni in mente che il rilevamento del sistema operativo non è mai 100&#37; completamente affidabile. Gli utenti possono impostare il loro browser per mimare altri sistemi operativi."
; CON_OTHER_CONDITION="Other Condition Set"
; CON_PAGE_TYPES="Page Types"
; CON_PHP="Custom PHP"
CON_PHP_DESC="Digita un pezzo di codice PHP da valutare. Il codice deve rendere il valore true oppure false.<br><br>Esempio:<br><br>[[%1:code%]]"
; CON_POSTAL_CODE="Postal Code"
; CON_POSTAL_CODES="Postal Codes"
; CON_POSTAL_CODES_DESC="A comma separated list of postal codes (12345) or postal code ranges (12300-12500).<br>This can only be used for [[%1:start link%]]a limited number of countries and IP addresses[[%2:end link%]]."
CON_PRODUCTS="Prodotti"
; CON_REGION="Region"
; CON_REGIONS="Regions"
CON_REGULAR_EXPRESSIONS="Regular Expressions"
; CON_RULE="Rule"
; CON_RULES="Rules"
; CON_SAVE_AS_PUBLISHED="Save as Published"
; CON_SAVE_AS_UNPUBLISHED="Save as Unpublished"
CON_SEASONS="Stagioni"
; CON_SELECT_A_CONDITION="Select a Condition Set"
; CON_SELECT_A_RULE_TYPE="Select a Rule Type"
CON_SOUTHERN="Sud"
; CON_SPECIFY="Specify"
CON_SPRING="Primavera"
CON_START_PUBLISHING="Inizia la pubblicazione"
; CON_SUMMARY="Summary"
CON_SUMMER="Estate"
CON_TAGS="Tag"
CON_TEMPLATES="Templates"
CON_TIME="Ora"
CON_TYPES="Tipi"
CON_URL_PARTS_REGEX="Le parti di Url saranno cercate usanndo espressioni regolari. <strong>Attenzione che la stringa usi una sinstassi corretta &quot;regex&quot;.</strong>"
; CON_URLS="URLs"
CON_URLS_DESC="Indica (parte di) URLs da cercare.<br>Usa un a capo per ogni differente ricerca."
; CON_USAGE="Usage"
; CON_USED_ON="This condition set is being used by these items:"
CON_USER_GROUPS="Utilizza gruppi"
CON_USERS="Utenti"
CON_VIRTUEMART="VirtueMart"
; CON_VISITORS="Visitors"
; CON_WARNING_FOR_EDITING_MULTIPLE_USAGE="Be careful!<br>Saving this will affect all items using this condition set!"
; CON_WHAT_TO_DO="What do you want to do?"
CON_WINTER="Inverno"
; CON_ZOO="Zoo"

View File

@ -0,0 +1,13 @@
;; @package Conditions
;; @version 24.11.1459
;;
;; @author Peter van Westen <info@regularlabs.com>
;; @link https://regularlabs.com
;; @copyright Copyright © 2024 Regular Labs All Rights Reserved
;; @license GNU General Public License version 2 or later
;;
;; @translate Want to help with translations? See: https://regularlabs.com/translate
; COM_CONDITIONS="Regular Labs - Conditions"
; COM_CONDITIONS_DESC="Conditions - manage your conditions used in other extensions in Joomla!"
CONDITIONS="Condizioni"

View File

@ -0,0 +1,169 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
defined('_JEXEC') or die;
use Joomla\CMS\Factory as JFactory;
use Joomla\CMS\Filesystem\File as JFile;
use Joomla\CMS\Filesystem\Folder as JFolder;
class Com_ConditionsInstallerScript
{
public function postflight($install_type, $adapter)
{
if ( ! in_array($install_type, ['install', 'update']))
{
return true;
}
self::createTables();
self::fixColumns();
self::deleteOldFiles();
}
private static function createTables()
{
$db = JFactory::getDbo();
$query = "CREATE TABLE IF NOT EXISTS `#__conditions` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`alias` VARCHAR(100) NOT NULL,
`name` VARCHAR(100) NOT NULL,
`description` TEXT NOT NULL,
`category` VARCHAR(50) NOT NULL DEFAULT '',
`color` VARCHAR(8) NULL DEFAULT NULL,
`match_all` TINYINT(1) UNSIGNED NOT NULL DEFAULT '1',
`published` TINYINT(1) NOT NULL DEFAULT '0',
`hash` VARCHAR(32) NOT NULL DEFAULT '',
`checked_out` INT UNSIGNED DEFAULT NULL,
`checked_out_time` datetime NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `published` (`published`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;";
$db->setQuery($query);
$db->execute();
$query = "CREATE TABLE IF NOT EXISTS `#__conditions_groups` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`condition_id` INT UNSIGNED NOT NULL,
`match_all` TINYINT(1) UNSIGNED NOT NULL DEFAULT '1',
`ordering` INT UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `condition_id` (`condition_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;";
$db->setQuery($query);
$db->execute();
$query = "CREATE TABLE IF NOT EXISTS `#__conditions_map` (
`condition_id` INT UNSIGNED NOT NULL,
`extension` VARCHAR(50) NOT NULL,
`item_id` INT UNSIGNED NOT NULL,
`table` VARCHAR(50) NOT NULL,
`name_column` VARCHAR(50) NOT NULL,
UNIQUE KEY `condition_id` (`condition_id`, `item_id`, `extension`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;";
$db->setQuery($query);
$db->execute();
$query = "CREATE TABLE IF NOT EXISTS `#__conditions_rules` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`group_id` INT UNSIGNED NOT NULL,
`type` VARCHAR(50) NOT NULL,
`exclude` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0',
`params` TEXT NOT NULL,
`ordering` INT UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `group_id` (`group_id`),
KEY `type` (`type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;";
$db->setQuery($query);
$db->execute();
}
private static function delete($files = [])
{
foreach ($files as $file)
{
if (is_dir($file))
{
JFolder::delete($file);
}
if (is_file($file))
{
JFile::delete($file);
}
}
}
private static function deleteOldFiles()
{
self::delete(
[
JPATH_ADMINISTRATOR . '/components/com_conditions/src/Form/Form.php',
JPATH_ADMINISTRATOR . '/components/com_conditions/src/Form/FormField.php',
JPATH_ADMINISTRATOR . '/components/com_conditions/src/Form/FormFieldGroup.php',
JPATH_ADMINISTRATOR . '/components/com_conditions/src/Form/Field/AgentsField.php',
JPATH_ADMINISTRATOR . '/components/com_conditions/src/Form/Field/ComponentsField.php',
JPATH_ADMINISTRATOR . '/components/com_conditions/src/Form/Field/ContentArticlesField.php',
JPATH_ADMINISTRATOR . '/components/com_conditions/src/Form/Field/ContentCategoriesField.php',
JPATH_ADMINISTRATOR . '/components/com_conditions/src/Form/Field/FieldField.php',
JPATH_ADMINISTRATOR . '/components/com_conditions/src/Form/Field/GeoField.php',
JPATH_ADMINISTRATOR . '/components/com_conditions/src/Form/Field/GeoInformationField.php',
JPATH_ADMINISTRATOR . '/components/com_conditions/src/Form/Field/LanguagesField.php',
JPATH_ADMINISTRATOR . '/components/com_conditions/src/Form/Field/MenuItemsField.php',
JPATH_ADMINISTRATOR . '/components/com_conditions/src/Form/Field/RulesField.php',
JPATH_ADMINISTRATOR . '/components/com_conditions/src/Form/Field/TagsField.php',
JPATH_ADMINISTRATOR . '/components/com_conditions/src/Form/Field/TemplatesField.php',
JPATH_ADMINISTRATOR . '/components/com_conditions/src/Form/Field/UserGroupsField.php',
JPATH_ADMINISTRATOR . '/components/com_conditions/src/Form/Field/UsersField.php',
JPATH_ADMINISTRATOR . '/components/com_conditions/src/Form/Field/geo.iso.regions.txt',
JPATH_ADMINISTRATOR . '/components/com_conditions/src/Helper/MobileDetect.php',
]
);
}
private static function fixColumns()
{
$db = JFactory::getDbo();
$query = 'SHOW COLUMNS FROM `#__conditions`';
$db->setQuery($query);
$columns = $db->loadColumn();
if ( ! in_array('color', $columns))
{
$query = "ALTER TABLE `#__conditions` ADD `color` VARCHAR(8) NULL DEFAULT NULL AFTER `category`;";
$db->setQuery($query);
$db->execute();
}
$query = 'SHOW COLUMNS FROM `#__conditions_groups`';
$db->setQuery($query);
$columns_groups = $db->loadColumn();
if (in_array('name', $columns_groups))
{
$query = "ALTER TABLE `#__conditions_groups` DROP `name`;";
$db->setQuery($query);
$db->execute();
}
if (in_array('description', $columns_groups))
{
$query = "ALTER TABLE `#__conditions_groups` DROP `description`;";
$db->setQuery($query);
$db->execute();
}
}
}

View File

@ -0,0 +1,50 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
defined('_JEXEC') or die;
use Joomla\CMS\Dispatcher\ComponentDispatcherFactoryInterface;
use Joomla\CMS\Extension\ComponentInterface;
use Joomla\CMS\Extension\Service\Provider\ComponentDispatcherFactory;
use Joomla\CMS\Extension\Service\Provider\MVCFactory;
use Joomla\CMS\Extension\Service\Provider\RouterFactory;
use Joomla\CMS\HTML\Registry;
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
use RegularLabs\Component\Conditions\Administrator\Extension\Component;
return new class implements ServiceProviderInterface {
/**
* Registers the service provider with a DI container.
*
* @param Container $container The DI container.
*
* @return void
*/
public function register(Container $container)
{
$container->registerServiceProvider(new MVCFactory('\\RegularLabs\\Component\\Conditions'));
$container->registerServiceProvider(new ComponentDispatcherFactory('\\RegularLabs\\Component\\Conditions'));
$container->registerServiceProvider(new RouterFactory('\\RegularLabs\\Component\\Conditions'));
$container->set(
ComponentInterface::class,
function (Container $container) {
$component = new Component($container->get(ComponentDispatcherFactoryInterface::class));
$component->setMVCFactory($container->get(MVCFactoryInterface::class));
$component->setRegistry($container->get(Registry::class));
return $component;
}
);
}
};

View File

@ -0,0 +1,202 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Api;
use RegularLabs\Component\Conditions\Administrator\Helper\Cache;
use RegularLabs\Component\Conditions\Administrator\Helper\Convert;
use RegularLabs\Component\Conditions\Administrator\Helper\Helper;
use RegularLabs\Component\Conditions\Administrator\Model\ItemModel;
defined('_JEXEC') or die;
/**
* Class Conditions
*
* @package RegularLabs\Library
*/
class Conditions
{
static $params;
private $article;
private $category_id;
private $condition;
private $module;
private $request;
public function __construct($article = null, $module = null)
{
$this->article = $article;
$this->module = $module;
}
public function pass(array $enabled_types = []): bool
{
if (empty($this->condition) || $this->condition->published < 1)
{
return true;
}
$cache = new Cache([
__METHOD__, $this->article->id ?? '', $this->module->id ?? '', $this->condition->hash,
$enabled_types
]);
if ($cache->exists())
{
return $cache->get();
}
$pass = true;
foreach ($this->condition->groups as $group)
{
$pass_group = $this->passGroup($group, $enabled_types);
// Break if not passed and matching method is ALL
if ( ! $pass_group && $this->condition->match_all)
{
$pass = false;
break;
}
// Break if passed and matching method is ANY
if ($pass_group && ! $this->condition->match_all)
{
$pass = true;
break;
}
$pass = $pass_group;
}
return $cache->set($pass);
}
public function setCategory(?int $category_id): self
{
$this->category_id = $category_id;
return $this;
}
public function setConditionByAttributes(object $attributes, string $name = ''): self
{
$this->condition = Convert::fromObject($attributes, $name);
return $this;
}
public function setConditionByExtensionItem(string $extension, int $item_id): self
{
$this->condition = (new ItemModel)->getConditionByExtensionItem($extension, $item_id, false);
return $this;
}
public function setConditionById(int $condition_id): self
{
$this->condition = (new ItemModel)->getConditionById($condition_id, false);
return $this;
}
public function setConditionByMixed(mixed $condition): self
{
$this->condition = (new ItemModel)->setConditionByMixed($condition, false);
return $this;
}
public function setRequest(object|false|null $request): self
{
$this->request = $request;
return $this;
}
private function passGroup(object $group, array $enabled_types = []): bool
{
$cache = new Cache([
__METHOD__, $this->article->id ?? '', $this->module->id ?? '', $group->hash,
$enabled_types
]);
if ($cache->exists())
{
return $cache->get();
}
$pass = true;
foreach ($group->rules as $rule)
{
if ( ! empty($enabled_types) && ! in_array($rule->type, $enabled_types))
{
continue;
}
$pass_rule = $this->passRule($rule);
// Break if not passed and matching method is ALL
if ( ! $pass_rule && $group->match_all)
{
$pass = false;
break;
}
// Break if passed and matching method is ANY
if ($pass_rule && ! $group->match_all)
{
$pass = true;
break;
}
$pass = $pass_rule;
}
return $cache->set($pass);
}
private function passRule(object $rule): bool
{
$cache = new Cache([__METHOD__, $this->article->id ?? '', $this->module->id ?? '', $rule]);
if ($cache->exists())
{
return $cache->get();
}
if ( ! Helper::conditionIsActive($rule))
{
return $cache->set(true);
}
$class = Helper::getConditionsClass($rule, $this->article, $this->module, $this->request, $this->category_id);
if ( ! $class)
{
return $cache->set(true);
}
$class->beforePass();
$pass = $class->pass();
if ($rule->exclude ?? false)
{
$pass = ! $pass;
}
return $cache->set($pass);
}
}

View File

@ -0,0 +1,132 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Agent;
defined('_JEXEC') or die;
use RegularLabs\Component\Conditions\Administrator\Condition\Condition;
use RegularLabs\Component\Conditions\Administrator\Condition\HasArraySelection;
use RegularLabs\Library\MobileDetect;
use RegularLabs\Library\RegEx;
abstract class Agent extends Condition
{
use HasArraySelection;
private $agent;
private $device;
private $is_mobile = false;
public function isDesktop(): bool
{
return $this->getDevice() == 'desktop';
}
public function isMobile(): bool
{
return $this->getDevice() == 'mobile';
}
public function isPhone(): bool
{
return $this->isMobile();
}
public function isTablet(): bool
{
return $this->getDevice() == 'tablet';
}
public function passBrowser(string $browser = ''): bool
{
if ( ! $browser)
{
return false;
}
if ($browser == 'mobile')
{
return $this->isMobile();
}
// also check for _ instead of .
$browser = RegEx::replace('\\\.([^\]])', '[\._]\1', $browser);
$browser = str_replace('\.]', '\._]', $browser);
return RegEx::match($browser, $this->getAgent(), $match, 'i');
}
private function getAgent(): string
{
if ( ! is_null($this->agent))
{
return $this->agent;
}
$detect = new MobileDetect;
$agent = $detect->getUserAgent() ?? '';
switch (true)
{
case (stripos($agent, 'Trident') !== false):
// Add MSIE to IE11 and others missing it
$agent = RegEx::replace('(Trident/[0-9\.]+;.*rv[: ]([0-9\.]+))', '\1 MSIE \2', $agent);
break;
case (stripos($agent, 'Chrome') !== false):
// Remove Safari from Chrome
$agent = RegEx::replace('(Chrome/.*)Safari/[0-9\.]*', '\1', $agent);
// Add MSIE to IE Edge and remove Chrome from IE Edge
$agent = RegEx::replace('Chrome/.*(Edge/[0-9])', 'MSIE \1', $agent);
break;
case (stripos($agent, 'Opera') !== false):
$agent = RegEx::replace('(Opera/.*)Version/', '\1Opera/', $agent);
break;
default:
break;
}
$this->agent = $agent;
return $this->agent;
}
private function getDevice(): string
{
if ( ! is_null($this->device))
{
return $this->device;
}
$detect = new MobileDetect;
$this->is_mobile = $detect->isMobile();
switch (true)
{
case($detect->isTablet()):
$this->device = 'tablet';
break;
case ($detect->isMobile()):
$this->device = 'mobile';
break;
default:
$this->device = 'desktop';
}
return $this->device;
}
}

View File

@ -0,0 +1,37 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Agent;
defined('_JEXEC') or die;
class Browser extends Agent
{
public function pass(): bool
{
if (empty($this->selection))
{
return false;
}
foreach ($this->selection as $browser)
{
if ( ! $this->passBrowser($browser))
{
continue;
}
return true;
}
return false;
}
}

View File

@ -0,0 +1,24 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Agent;
defined('_JEXEC') or die;
class Device extends Agent
{
public function pass(): bool
{
return (in_array('mobile', $this->selection) && $this->isMobile())
|| (in_array('tablet', $this->selection) && $this->isTablet())
|| (in_array('desktop', $this->selection) && $this->isDesktop());
}
}

View File

@ -0,0 +1,19 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Agent;
defined('_JEXEC') or die;
class Os extends Browser
{
// Same as AgentBrowsers
}

View File

@ -0,0 +1,508 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition;
defined('_JEXEC') or die;
use Joomla\CMS\Factory as JFactory;
use Joomla\CMS\Menu\MenuItem as JMenuItem;
use RegularLabs\Component\Conditions\Administrator\Helper\Cache;
use RegularLabs\Library\Document as RL_Document;
use RegularLabs\Library\Input as RL_Input;
use RegularLabs\Library\Parameters as RL_Parameters;
/**
* Class Condition
*
* @package RegularLabs\Library
*/
abstract class Condition
{
static $_request;
public $article;
public $category_id;
public $date;
public $db;
public $exclude;
public $module;
public $params;
public $request;
public $selection;
protected $request_keys = [];
public function __construct(
object $rule,
object|false|null $article = null,
object|false|null $module = null,
object|false|null $request = null,
?int $category_id = null
)
{
self::setRequest($request);
$this->db = JFactory::getDbo();
$this->params = $rule->params ?? (object) [];
$this->selection = $rule->params->selection ?? [];
$this->exclude = $rule->exclude ?? false;
$this->article = $article;
$this->module = $module;
$this->category_id = $category_id;
$this->prepareSelection();
}
public function beforePass(): void
{
}
public function getMenuItemParams(int $id = 0): object
{
$cache = new Cache;
if ($cache->exists())
{
return $cache->get();
}
$query = $this->db->getQuery(true)
->select('m.params')
->from('#__menu AS m')
->where('m.id = ' . (int) $id);
$this->db->setQuery($query);
$params = $this->db->loadResult();
return $cache->set(RL_Parameters::getObjectFromRegistry($params));
}
public function getParentIds(
int $id = 0,
string $table = 'menu',
string $parent = 'parent_id',
string $child = 'id'
): array
{
if ( ! $id)
{
return [];
}
$cache = new Cache;
if ($cache->exists())
{
return $cache->get();
}
$parent_ids = [];
while ($id)
{
$query = $this->db->getQuery(true)
->select('t.' . $parent)
->from('#__' . $table . ' as t')
->where('t.' . $child . ' = ' . (int) $id);
$this->db->setQuery($query);
$id = $this->db->loadResult();
// Break if no parent is found or parent already found before for some reason
if ( ! $id || in_array($id, $parent_ids))
{
break;
}
$parent_ids[] = $id;
}
return $cache->set($parent_ids);
}
public function init(): void
{
}
public function initRequest(&$request): void
{
}
public function makeArray(
array|string|null $array = '',
string $delimiter = ',',
bool $trim = false
): array
{
if (empty($array))
{
return [];
}
$cache = new Cache;
if ($cache->exists())
{
return $cache->get();
}
$array = $this->mixedDataToArray($array, $delimiter);
if (empty($array))
{
return $array;
}
if ( ! $trim)
{
return $array;
}
foreach ($array as $k => $v)
{
if ( ! is_string($v))
{
continue;
}
$array[$k] = trim($v);
}
return $cache->set($array);
}
public function passByPageType(
string $option,
array $selection = [],
bool $add_view = false,
bool $get_task = false,
bool $get_layout = true
): bool
{
if ($this->request->option != $option)
{
return false;
}
if ($get_task && $this->request->task && $this->request->task != $this->request->view && $this->request->task != 'default')
{
$pagetype = ($add_view ? $this->request->view . '_' : '') . $this->request->task;
return $this->passSimple($pagetype, $selection);
}
if ($get_layout && $this->request->layout && $this->request->layout != $this->request->view && $this->request->layout != 'default')
{
$pagetype = ($add_view ? $this->request->view . '_' : '') . $this->request->layout;
return $this->passSimple($pagetype, $selection);
}
return $this->passSimple($this->request->view, $selection);
}
public function passInRange(
string|int|null $value = '',
array|string|null $selection = null
): bool
{
if (empty($value))
{
return false;
}
$selections = $this->makeArray($selection ?: $this->selection);
$pass = false;
foreach ($selections as $selection)
{
if (empty($selection))
{
continue;
}
if ( ! str_contains($selection, '-'))
{
if ((int) $value == (int) $selection)
{
$pass = true;
break;
}
continue;
}
[$min, $max] = explode('-', $selection, 2);
if ((int) $value >= (int) $min && (int) $value <= (int) $max)
{
$pass = true;
break;
}
}
return $pass;
}
public function passItemByType(bool &$pass, string $type = '', mixed $data = null): bool
{
$pass_type = ! empty($data) ? $this->{'pass' . $type}($data) : $this->{'pass' . $type}();
if ($pass_type === null)
{
return true;
}
$pass = $pass_type;
return $pass;
}
public function passSimple(
mixed $values = '',
string|array|null $selection = null,
bool $caseinsensitive = false
)
{
$values = $this->makeArray($values);
$selection = $selection ?: $this->selection;
$selection = is_array($selection) ? $selection : [$selection];
if (empty($selection))
{
return false;
}
$pass = false;
foreach ($values as $value)
{
if ($caseinsensitive)
{
if (in_array(strtolower($value), array_map('strtolower', $selection), true))
{
$pass = true;
break;
}
continue;
}
if (in_array($value, $selection))
{
$pass = true;
break;
}
}
return $pass;
}
protected function prepareSelection(): void
{
}
private function getActiveMenu(): object|false
{
$menu = JFactory::getApplication()->getMenu()->getActive();
if (empty($menu->id))
{
return false;
}
return $this->getMenuById($menu->id);
}
private function getItemId(): int
{
$id = RL_Input::getInt('Itemid', 0);
if ($id)
{
return $id;
}
$menu = $this->getActiveMenu();
return $menu->id ?? 0;
}
private function getMenuById(int $id = 0): object|false
{
$menu = JFactory::getApplication()->getMenu()->getItem($id);
if (empty($menu->id))
{
return false;
}
if ($menu->type == 'alias')
{
$params = $menu->getParams();
return $this->getMenuById($params->get('aliasoptions'));
}
return $menu;
}
private function getRequest(): object
{
$return_early = ! is_null(self::$_request);
$app = JFactory::getApplication();
$id = RL_Input::getAsArray(
'a_id',
RL_Input::getAsArray('id', [0])
);
self::$_request = (object) [
'idname' => 'id',
'option' => RL_Input::getCmd('option'),
'view' => RL_Input::getCmd('view'),
'task' => RL_Input::getCmd('task'),
'layout' => RL_Input::getString('layout'),
'Itemid' => $this->getItemId(),
'id' => (int) $id[0],
];
switch (self::$_request->option)
{
case 'com_categories':
$extension = RL_Input::getCmd('extension');
self::$_request->option = $extension ?: 'com_content';
self::$_request->view = 'category';
break;
case 'com_breezingforms':
if (self::$_request->view == 'article')
{
self::$_request->option = 'com_content';
}
break;
default:
break;
}
$this->initRequest(self::$_request);
if ( ! self::$_request->id)
{
$cid = RL_Input::getAsArray('cid', [0]);
self::$_request->id = (int) $cid[0];
}
if ($return_early)
{
return self::$_request;
}
// if no id is found, check if menuitem exists to get view and id
if ( ! RL_Document::isClient('site')
|| (self::$_request->option && self::$_request->id)
)
{
return self::$_request;
}
/* @var JMenuItem $menu_item */
$menu_item = empty(self::$_request->Itemid)
? $app->getMenu('site')->getActive()
: $app->getMenu('site')->getItem(self::$_request->Itemid);
if ( ! $menu_item)
{
return self::$_request;
}
if ( ! self::$_request->option)
{
self::$_request->option = $menu_item->query['option'] ?? null;
}
self::$_request->view = $menu_item->query['view'] ?? null;
self::$_request->task = $menu_item->query['task'] ?? null;
if ( ! self::$_request->id)
{
self::$_request->id = $menu_item->query[self::$_request->idname] ?? $menu_item->getParams()->get(self::$_request->idname);
}
unset($menu_item);
return self::$_request;
}
private function getRequestKeys(): array
{
return ['option', 'view', 'task', 'layout', 'id', 'Itemid', ...$this->request_keys];
}
private function mixedDataToArray(
array|string $array = '',
bool $onlycommas = false
): array
{
if ( ! is_array($array))
{
$delimiter = ($onlycommas || ! str_contains($array, '|')) ? ',' : '|';
return explode($delimiter, $array);
}
if (empty($array))
{
return $array;
}
if (isset($array[0]) && is_array($array[0]))
{
return $array[0];
}
if (count($array) === 1 && str_contains($array[0], ','))
{
return explode(',', $array[0]);
}
return $array;
}
private function setRequest(object|false|null $request_overrides = null): void
{
$this->request = $this->getRequest();
if (empty($request_overrides))
{
return;
}
foreach ($request_overrides as $key => $value)
{
$key = $key == 'cid' ? 'id' : $key;
if ( ! in_array($key, $this->getRequestKeys()))
{
continue;
}
if ($key === 'id' && is_array($value))
{
$value = (int) $value[0];
}
$this->request->{$key} = $value;
}
}
}

View File

@ -0,0 +1,62 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Content\Article;
defined('_JEXEC') or die;
use Joomla\CMS\Factory as JFactory;
use Joomla\CMS\User\UserFactoryInterface as JUserFactoryInterface;
use RegularLabs\Component\Conditions\Administrator\Condition\Content\Content;
use RegularLabs\Component\Conditions\Administrator\Condition\HasArraySelection;
class Author extends Content
{
use HasArraySelection;
public function pass(): bool
{
if ( ! $this->isArticle())
{
return false;
}
if (empty($this->selection))
{
return false;
}
$item = $this->getArticle();
$author = $item->created_by ?? 0;
if ($this->passSimple($author))
{
return true;
}
$author = JFactory::getContainer()->get(JUserFactoryInterface::class)->loadUserById((int) $author);
if ($this->passSimple($author->get('username')))
{
return true;
}
if ( ! in_array('current', $this->selection))
{
return false;
}
$user = JFactory::getApplication()->getIdentity() ?: JFactory::getUser();
return $author == $user->get('id');
}
}

View File

@ -0,0 +1,63 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Content\Article;
defined('_JEXEC') or die;
use RegularLabs\Component\Conditions\Administrator\Condition\Content\Content;
use RegularLabs\Library\ArrayHelper as RL_Array;
use RegularLabs\Library\RegEx as RL_RegEx;
class ContentKeyword extends Content
{
public function pass(): bool
{
if ( ! $this->isArticle())
{
return false;
}
if (empty($this->selection))
{
return false;
}
$item = $this->getArticle();
$texts = [];
$text_fields = ['title', 'introtext', 'fulltext'];
foreach ($text_fields as $field)
{
if ( ! isset($item->{$field}))
{
return false;
}
$texts[] = $item->{$field};
}
if (empty($texts))
{
return false;
}
$texts = RL_Array::implode($texts, ' ');
$keywords = RL_RegEx::quote($this->makeArray($this->selection));
$case_sensitve = $this->params->case_sensitve ?? false;
$options = $case_sensitve ? 'si' : 's';
return RL_RegEx::match('\b' . $keywords . '\b', $texts, $match, $options);
}
}

View File

@ -0,0 +1,45 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Content\Article;
defined('_JEXEC') or die;
use RegularLabs\Component\Conditions\Administrator\Condition\Content\Content;
use RegularLabs\Component\Conditions\Administrator\Helper\Date as DateHelper;
class Date extends Content
{
public function pass(): bool
{
if ( ! $this->isArticle())
{
return false;
}
if (empty($this->selection))
{
return false;
}
$item = $this->getArticle();
$field = $this->selection;
if ( ! isset($item->{$field}))
{
return false;
}
$date = DateHelper::getString($item->{$field});
return DateHelper::pass($this->params, $date);
}
}

View File

@ -0,0 +1,31 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Content\Article;
defined('_JEXEC') or die;
use RegularLabs\Component\Conditions\Administrator\Condition\Content\Content;
class Featured extends Content
{
public function pass(): bool
{
if ( ! $this->isArticle())
{
return false;
}
$item = $this->getArticle();
return $item->featured ?? false;
}
}

View File

@ -0,0 +1,263 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Content\Article;
defined('_JEXEC') or die;
use DateTimeZone;
use Joomla\CMS\Date\Date as JDate;
use Joomla\CMS\Factory as JFactory;
use Joomla\Component\Fields\Administrator\Helper\FieldsHelper as JFieldsHelper;
use RegularLabs\Component\Conditions\Administrator\Condition\Content\Content;
use RegularLabs\Library\ArrayHelper as RL_Array;
use RegularLabs\Library\RegEx as RL_RegEx;
use RegularLabs\Library\StringHelper as RL_String;
class Field extends Content
{
public function pass(): bool
{
if ( ! $this->isArticle())
{
return false;
}
if (empty($this->params->field))
{
return false;
}
$item = $this->getArticle();
if ( ! isset($item->id))
{
return false;
}
$article_fields = JFieldsHelper::getFields('com_content.article', $item, true);
foreach ($article_fields as $article_field)
{
if ($article_field->id != $this->params->field)
{
continue;
}
$comparison = ($this->params->comparison ?? null) ?: 'equals';
if ( ! self::passComparison($this->params->value, $article_field->rawvalue, $comparison)
&& ! self::passComparison($this->params->value, $article_field->value, $comparison)
)
{
return false;
}
return true;
}
return false;
}
private static function hasTime(string $string): bool
{
if ( ! self::isDateTimeString($string))
{
return false;
}
return RL_RegEx::match('^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}', $string);
}
private static function isDateTimeString(string $string): bool
{
return RL_RegEx::match('^[0-9]{4}-[0-9]{2}-[0-9]{2}', $string);
}
private static function passComparison(
string $needle,
string|array $haystack,
string $comparison = 'equals'
): bool
{
$haystack = RL_Array::toArray($haystack);
if (empty($haystack))
{
return false;
}
// For list values
if (count($haystack) > 1)
{
switch ($comparison)
{
case 'not_equals':
$needle = RL_Array::toArray($needle);
sort($needle);
sort($haystack);
return $needle != $haystack;
case 'contains':
$needle = RL_Array::toArray($needle);
sort($needle);
$intersect = array_intersect($needle, $haystack);
return $needle == $intersect;
case 'contains_one':
return RL_Array::find($needle, $haystack);
case 'not_contains':
return ! RL_Array::find($needle, $haystack);
case 'equals':
default:
$needle = RL_Array::toArray($needle);
sort($needle);
sort($haystack);
return $needle == $haystack;
}
}
$haystack = $haystack[0];
if ($comparison == 'regex')
{
return RL_RegEx::match($needle, $haystack);
}
// Convert dynamic date values i, like date('yesterday')
$haystack = self::valueToDateString($haystack, true);
$has_time = self::hasTime($haystack);
$needle = self::valueToDateString($needle, false, $has_time);
// make the needle and haystack lowercase, so comparisons are case insensitive
$needle = RL_String::strtolower($needle);
$haystack = RL_String::strtolower($haystack);
switch ($comparison)
{
case 'not_equals':
return $needle != $haystack;
case 'contains':
case 'contains_one':
return str_contains($haystack, $needle);
case 'not_contains':
return ! str_contains($haystack, $needle);
case 'begins_with':
$length = strlen($needle);
return substr($haystack, 0, $length) === $needle;
case 'ends_with':
$length = strlen($needle);
if ($length == 0)
{
return true;
}
return substr($haystack, -$length) === $needle;
case 'less_than':
return $haystack < $needle;
case 'greater_than':
return $haystack > $needle;
case 'less_than_or_equals':
return $haystack <= $needle;
case 'greater_than_or_equals':
return $haystack >= $needle;
case 'equals':
default:
return $needle == $haystack;
}
}
private static function valueToDateString(
string $value,
bool $apply_offset = true,
bool $add_time = false
): string
{
$value = trim($value);
if (
in_array($value, [
'now()',
'JFactory::getDate()',
], true)
)
{
if ( ! $apply_offset)
{
return date('Y-m-d H:i:s', strtotime('now'));
}
$date = new JDate('now', JFactory::getApplication()->get('offset', 'UTC'));
return $date->format('Y-m-d H:i:s');
}
if (self::isDateTimeString($value))
{
$format = 'Y-m-d H:i:s';
$date = new JDate($value, JFactory::getApplication()->get('offset', 'UTC'));
if ($apply_offset)
{
$date = JFactory::getDate($value, 'UTC');
$date->setTimezone(new DateTimeZone(JFactory::getApplication()->get('offset')));
}
return $date->format($format, true, false);
}
$regex = '^date\(\s*'
. '(?:\'(?<datetime>.*?)\')?'
. '(?:\\\\?,\s*\'(?<format>.*?)\')?'
. '\s*\)$';
if ( ! RL_RegEx::match($regex, $value, $match))
{
return $value;
}
$datetime = ($match['datetime'] ?? null) ?: 'now';
$format = $match['format'] ?? '';
if (empty($format))
{
$time = date('His', strtotime($datetime));
$format = (int) $time || $add_time ? 'Y-m-d H:i:s' : 'Y-m-d';
}
$date = new JDate($datetime, JFactory::getApplication()->get('offset', 'UTC'));
if ($apply_offset)
{
$date = JFactory::getDate($datetime, 'UTC');
$date->setTimezone(new DateTimeZone(JFactory::getApplication()->get('offset')));
}
return $date->format($format, true, false);
}
}

View File

@ -0,0 +1,32 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Content\Article;
defined('_JEXEC') or die;
use RegularLabs\Component\Conditions\Administrator\Condition\Content\Content;
use RegularLabs\Component\Conditions\Administrator\Condition\HasArraySelection;
class Id extends Content
{
use HasArraySelection;
public function pass(): bool
{
if ( ! $this->isArticle())
{
return false;
}
return $this->passSimple($this->request->id);
}
}

View File

@ -0,0 +1,56 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Content\Article;
defined('_JEXEC') or die;
use RegularLabs\Component\Conditions\Administrator\Condition\Content\Content;
use RegularLabs\Library\ArrayHelper as RL_Array;
class MetaKeyword extends Content
{
public function pass(): bool
{
if ( ! $this->isArticle())
{
return false;
}
if (empty($this->selection))
{
return false;
}
$item = $this->getArticle();
$keywords = $item->metakey ?: '';
if (empty($keywords))
{
return false;
}
$case_sensitve = $this->params->case_sensitve ?? false;
$this->selection = RL_Array::implode($this->selection, ',');
if ( ! $case_sensitve)
{
$this->selection = strtolower($this->selection);
$keywords = strtolower($keywords);
}
$this->selection = RL_Array::toArray($this->selection);
$keywords = RL_Array::toArray($keywords);
return RL_Array::find($this->selection, $keywords);
}
}

View File

@ -0,0 +1,59 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Content\Article;
defined('_JEXEC') or die;
use Joomla\CMS\Factory as JFactory;
use RegularLabs\Component\Conditions\Administrator\Condition\Content\Content;
use RegularLabs\Component\Conditions\Administrator\Condition\HasArraySelection;
class Status extends Content
{
use HasArraySelection;
public function pass(): bool
{
if ( ! $this->isArticle())
{
return false;
}
if (empty($this->selection))
{
return false;
}
$item = $this->getArticle();
$publish_state = $item->state;
$now = JFactory::getDate()->format('Y-m-d H:i:s');
if ($publish_state === 1)
{
$isUnpublished = $item->publish_up > $now
|| ( ! is_null($item->publish_down) && $item->publish_down < $now);
$publish_state = $isUnpublished ? 0 : 1;
}
$states = [
0 => 'unpublished',
1 => 'published',
2 => 'archived',
-2 => 'trashed',
];
return $this->passSimple([$publish_state, $states[$publish_state] ?? $publish_state]);
}
}

View File

@ -0,0 +1,174 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Content;
defined('_JEXEC') or die;
use Joomla\CMS\Factory as JFactory;
use Joomla\CMS\Table\Table as JTable;
use RegularLabs\Component\Conditions\Administrator\Condition\HasArraySelection;
use RegularLabs\Library\Input as RL_Input;
class Category extends Content
{
use HasArraySelection;
public function pass(): bool
{
// components that use the com_content secs/cats
$components = ['com_content', 'com_flexicontent'];
if ( ! in_array($this->request->option, $components)
&& empty($this->category_id)
)
{
return false;
}
if (empty($this->selection))
{
return false;
}
$page_types = $this->params->page_types ?? [];
$is_content = in_array($this->request->option, ['com_content', 'com_flexicontent']);
$is_category = in_array($this->request->view, ['category']);
$is_item = in_array($this->request->view, ['', 'article', 'item', 'form']);
if (
! (in_array('categories', $page_types) && $is_content && $is_category)
&& ! (in_array('articles', $page_types) && $is_content && $is_item)
&& ! (in_array('others', $page_types) && ! ($is_content && ($is_category || $is_item)))
&& ! (RL_Input::getInt('rl_qp') && ! empty($this->getCategoryIds()))
&& empty($this->category_id)
)
{
return false;
}
$pass = false;
if (
in_array('others', $page_types)
&& ! ($is_content && ($is_category || $is_item))
&& $this->article
)
{
if ( ! isset($this->article->id) && isset($this->article->slug))
{
$this->article->id = (int) $this->article->slug;
}
if ( ! isset($this->article->catid) && isset($this->article->catslug))
{
$this->article->catid = (int) $this->article->catslug;
}
$this->request->id = $this->article->id;
$this->request->view = 'article';
}
$category_ids = $this->getCategoryIds($is_category);
foreach ($category_ids as $category_id)
{
if ( ! $category_id)
{
continue;
}
$pass = in_array($category_id, $this->selection);
if ($pass && (int) $this->params->include_children === 2)
{
$pass = false;
continue;
}
if ( ! $pass && $this->params->include_children)
{
$parent_ids = $this->getCategoryParentIds((int) $category_id);
$parent_ids = array_diff($parent_ids, [1]);
foreach ($parent_ids as $parent_id)
{
if (in_array($parent_id, $this->selection))
{
$pass = true;
break;
}
}
unset($parent_ids);
}
}
return $pass;
}
private function getCategoryIds(bool $is_category = false): array
{
if ($is_category)
{
return (array) $this->request->id;
}
if ( ! empty($this->category_id))
{
return [$this->category_id];
}
$app = JFactory::getApplication();
$category_id = $app->getUserState('com_content.edit.article.data.catid');
if ( ! $category_id)
{
if ( ! $this->article && $this->request->id)
{
$this->article = JTable::getInstance('content');
$this->article->load($this->request->id);
}
if ($this->article && isset($this->article->catid))
{
return (array) $this->article->catid;
}
}
if ( ! $category_id)
{
$category_id = $app->getUserState('com_content.articles.filter.category_id');
}
if ( ! $category_id)
{
$category_id = RL_Input::getInt('catid');
}
$menuparams = $this->getMenuItemParams($this->request->Itemid);
if ($this->request->view == 'featured')
{
$menuparams = $this->getMenuItemParams($this->request->Itemid);
return (array) ($menuparams->featured_categories ?? $category_id);
}
return (array) ($menuparams->catid ?? $category_id);
}
private function getCategoryParentIds(int $id = 0): array
{
return $this->getParentIds($id, 'categories');
}
}

View File

@ -0,0 +1,46 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Content;
defined('_JEXEC') or die;
use Joomla\Component\Content\Site\Model\ArticleModel as JArticleModel;
use RegularLabs\Component\Conditions\Administrator\Condition\Condition;
use RegularLabs\Component\Conditions\Administrator\Condition\Traits\isContent;
abstract class Content extends Condition
{
public function getArticle(): ?object
{
if ($this->article)
{
return $this->article;
}
$model = new JArticleModel;
$this->article = $model->getItem($this->request->id);
return $this->article;
}
protected function isArticle(): bool
{
if (empty($this->request->id))
{
return false;
}
return ($this->request->option == 'com_content' && $this->request->view == 'article')
|| ($this->request->option == 'com_flexicontent' && $this->request->view == 'item');
}
}

View File

@ -0,0 +1,40 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Content;
use RegularLabs\Component\Conditions\Administrator\Condition\HasArraySelection;
defined('_JEXEC') or die;
class PageType extends Content
{
use HasArraySelection;
public function pass(): bool
{
$components = ['com_content', 'com_contentsubmit'];
if ( ! in_array($this->request->option, $components))
{
return false;
}
$view = $this->request->view;
if ($this->request->view == 'category' && $this->request->layout == 'blog')
{
$view = 'categoryblog';
}
return $this->passSimple($view);
}
}

View File

@ -0,0 +1,27 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Date;
defined('_JEXEC') or die;
use RegularLabs\Component\Conditions\Administrator\Condition\Condition;
use RegularLabs\Component\Conditions\Administrator\Helper\Date as DateHelper;
class Date extends Condition
{
public function pass(): bool
{
$now = DateHelper::getNow();
return DateHelper::pass($this->params, $now);
}
}

View File

@ -0,0 +1,35 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Date;
defined('_JEXEC') or die;
use RegularLabs\Component\Conditions\Administrator\Condition\Condition;
use RegularLabs\Component\Conditions\Administrator\Condition\HasArraySelection;
use RegularLabs\Component\Conditions\Administrator\Helper\Date as DateHelper;
class Day extends Condition
{
use HasArraySelection;
public function pass(): bool
{
$current_day = (int) DateHelper::getString('', 'N'); // 1 (for Monday) though 7 (for Sunday )
foreach ($this->selection as &$day)
{
$day = DateHelper::getDayNumber($day);
}
return $this->passSimple($current_day);
}
}

View File

@ -0,0 +1,35 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Date;
defined('_JEXEC') or die;
use RegularLabs\Component\Conditions\Administrator\Condition\Condition;
use RegularLabs\Component\Conditions\Administrator\Condition\HasArraySelection;
use RegularLabs\Component\Conditions\Administrator\Helper\Date as DateHelper;
class Month extends Condition
{
use HasArraySelection;
public function pass(): bool
{
$current_month = DateHelper::getString('', 'm'); // 01 (for January) through 12 (for December)
foreach ($this->selection as &$month)
{
$month = DateHelper::getMonthNumber($month);
}
return $this->passSimple((int) $current_month);
}
}

View File

@ -0,0 +1,120 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Date;
defined('_JEXEC') or die;
use RegularLabs\Component\Conditions\Administrator\Condition\Condition;
use RegularLabs\Component\Conditions\Administrator\Condition\HasArraySelection;
use RegularLabs\Component\Conditions\Administrator\Helper\Date as DateHelper;
class Season extends Condition
{
use HasArraySelection;
public function pass(): bool
{
$season = self::getSeason($this->params->hemisphere);
return $this->passSimple($season);
}
private function getSeason(string $hemisphere = 'northern'): string
{
$now = DateHelper::getTimeStamp();
// Get year of date specified
$date_year = DateHelper::getString('', 'Y'); // Four digit representation for the year
// Specify the season names
$season_names = ['winter', 'spring', 'summer', 'fall'];
// Declare season date ranges
switch (strtolower($hemisphere))
{
case 'southern':
if (
$now < strtotime($date_year . '-03-21')
|| $now >= strtotime($date_year . '-12-21')
)
{
return $season_names[2]; // Must be in Summer
}
if ($now >= strtotime($date_year . '-09-23'))
{
return $season_names[1]; // Must be in Spring
}
if ($now >= strtotime($date_year . '-06-21'))
{
return $season_names[0]; // Must be in Winter
}
if ($now >= strtotime($date_year . '-03-21'))
{
return $season_names[3]; // Must be in Fall
}
break;
case 'australia':
if (
$now < strtotime($date_year . '-03-01')
|| $now >= strtotime($date_year . '-12-01')
)
{
return $season_names[2]; // Must be in Summer
}
if ($now >= strtotime($date_year . '-09-01'))
{
return $season_names[1]; // Must be in Spring
}
if ($now >= strtotime($date_year . '-06-01'))
{
return $season_names[0]; // Must be in Winter
}
if ($now >= strtotime($date_year . '-03-01'))
{
return $season_names[3]; // Must be in Fall
}
break;
default: // northern
if (
$now < strtotime($date_year . '-03-21')
|| $now >= strtotime($date_year . '-12-21')
)
{
return $season_names[0]; // Must be in Winter
}
if ($now >= strtotime($date_year . '-09-23'))
{
return $season_names[3]; // Must be in Fall
}
if ($now >= strtotime($date_year . '-06-21'))
{
return $season_names[2]; // Must be in Summer
}
if ($now >= strtotime($date_year . '-03-21'))
{
return $season_names[1]; // Must be in Spring
}
break;
}
return 0;
}
}

View File

@ -0,0 +1,74 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Date;
defined('_JEXEC') or die;
use RegularLabs\Component\Conditions\Administrator\Condition\Condition;
use RegularLabs\Component\Conditions\Administrator\Helper\Date as DateHelper;
use RegularLabs\Library\Date as RL_Date;
class Time extends Condition
{
public function pass(): bool
{
$now = DateHelper::getTimeStamp();
$comparison = $this->params->comparison ?? 'between';
if ($comparison == 'before')
{
return $now < $this->getDateTime($this->params->time ?? '');
}
if ($comparison == 'after')
{
return $now > $this->getDateTime($this->params->time ?? '');
}
$from = $this->getDateTime($this->params->from);
$to = $this->getDateTime($this->params->to);
if ($from > $to)
{
// from is after to (spans midnight)
// current time should be:
// - after from
// - OR before to
if ($now >= $from || $now < $to)
{
return true;
}
return false;
}
// to is after from (simple time span)
// current time should be:
// - after from
// - AND before to
if ($now >= $from && $now < $to)
{
return true;
}
return false;
}
private function getDateTime(string $value): int
{
$date = DateHelper::getString('', 'Y-m-d');
$time = RL_Date::fixTime($value);
return strtotime($date . ' ' . $time);
}
}

View File

@ -0,0 +1,21 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Flexicontent;
defined('_JEXEC') or die;
use RegularLabs\Component\Conditions\Administrator\Condition\Condition;
use RegularLabs\Component\Conditions\Administrator\Condition\Traits\isContent;
abstract class Flexicontent extends Condition
{
}

View File

@ -0,0 +1,26 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Flexicontent;
use RegularLabs\Component\Conditions\Administrator\Condition\HasArraySelection;
defined('_JEXEC') or die;
class PageType extends Flexicontent
{
use HasArraySelection;
public function pass(): bool
{
return $this->passByPageType('com_flexicontent', $this->selection, true);
}
}

View File

@ -0,0 +1,65 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Flexicontent;
defined('_JEXEC') or die;
use RegularLabs\Component\Conditions\Administrator\Condition\HasArraySelection;
use RegularLabs\Library\Input as RL_Input;
class Tag extends Flexicontent
{
use HasArraySelection;
public function pass(): bool
{
if ($this->request->option !== 'com_flexicontent')
{
return false;
}
$page_types = $this->params->page_types ?? [];
if (
(in_array('tags', $page_types) && $this->request->view == 'tags')
|| (in_array('items', $page_types) && in_array($this->request->view, ['item', 'items']))
)
{
return false;
}
if (in_array('tags', $page_types) && $this->request->view == 'tags')
{
$query = $this->db->getQuery(true)
->select('t.name')
->from('#__flexicontent_tags AS t')
->where('t.id = ' . (int) trim(RL_Input::getInt('id', 0)))
->where('t.published = 1');
$this->db->setQuery($query);
$tag = $this->db->loadResult();
$tags = [$tag];
return $this->passSimple($tags, null, true);
}
$query = $this->db->getQuery(true)
->select('t.name')
->from('#__flexicontent_tags_item_relations AS x')
->join('LEFT', '#__flexicontent_tags AS t ON t.id = x.tid')
->where('x.itemid = ' . (int) $this->request->id)
->where('t.published = 1');
$this->db->setQuery($query);
$tags = $this->db->loadColumn();
return $this->passSimple($tags, null, true);
}
}

View File

@ -0,0 +1,45 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Flexicontent;
defined('_JEXEC') or die;
use RegularLabs\Component\Conditions\Administrator\Condition\HasArraySelection;
class Type extends Flexicontent
{
use HasArraySelection;
public function pass(): bool
{
if ($this->request->option !== 'com_flexicontent')
{
return false;
}
if ( ! in_array($this->request->view, ['item', 'items']))
{
return false;
}
$query = $this->db->getQuery(true)
->select('x.type_id')
->from('#__flexicontent_items_ext AS x')
->where('x.item_id = ' . (int) $this->request->id);
$this->db->setQuery($query);
$type = $this->db->loadResult();
$types = $this->makeArray($type);
return $this->passSimple($types);
}
}

View File

@ -0,0 +1,31 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Geo;
use RegularLabs\Component\Conditions\Administrator\Condition\HasArraySelection;
defined('_JEXEC') or die;
class Continent extends Geo
{
use HasArraySelection;
public function pass(): bool
{
if ( ! $this->getGeo() || empty($this->geo->continentCode))
{
return false;
}
return $this->passSimple([$this->geo->continent, $this->geo->continentCode]);
}
}

View File

@ -0,0 +1,39 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Geo;
use RegularLabs\Component\Conditions\Administrator\Condition\HasArraySelection;
defined('_JEXEC') or die;
class Country extends Geo
{
use HasArraySelection;
public function pass(): bool
{
if ( ! $this->getGeo())
{
return false;
}
$country = $this->geo->country ?? '';
$countryCode = $this->geo->countryCode ?? '';
if (empty($country) && empty($countryCode))
{
return false;
}
return $this->passSimple([$country, $countryCode]);
}
}

View File

@ -0,0 +1,60 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Geo;
defined('_JEXEC') or die;
use Joomla\CMS\Factory as JFactory;
use Joomla\CMS\Log\Log as JLog;
use RegularLabs\Component\Conditions\Administrator\Condition\Condition;
use RegularLabs\Library\GeoIp\GeoIp as RL_GeoIP;
abstract class Geo extends Condition
{
var $geo;
public function getGeo(string $ip = ''): object|false
{
if ( ! is_null($this->geo))
{
return $this->geo;
}
$geo = $this->getGeoObject($ip);
if (empty($geo))
{
return false;
}
$this->geo = $geo->get();
if (JFactory::getApplication()->get('debug'))
{
JLog::addLogger(['text_file' => 'regularlabs_geoip.log.php'], JLog::ALL, ['regularlabs_geoip']);
JLog::add(json_encode($this->geo), JLog::DEBUG, 'regularlabs_geoip');
}
return $this->geo;
}
private function getGeoObject(string $ip): RL_GeoIP|false
{
if ( ! class_exists('RegularLabs\\Library\\GeoIp\\GeoIp'))
{
return false;
}
return new RL_GeoIP($ip);
}
}

View File

@ -0,0 +1,30 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Geo;
defined('_JEXEC') or die;
class PostalCode extends Geo
{
public function pass(): bool
{
if ( ! $this->getGeo() || empty($this->geo->postalCode))
{
return false;
}
// replace dashes with dots: 730-0011 => 730.0011
$postalcode = str_replace('-', '.', $this->geo->postalCode);
return $this->passInRange($postalcode);
}
}

View File

@ -0,0 +1,52 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Geo;
use RegularLabs\Component\Conditions\Administrator\Condition\HasArraySelection;
defined('_JEXEC') or die;
class Region extends Geo
{
use HasArraySelection;
public function pass(): bool
{
if ( ! $this->getGeo())
{
return false;
}
$country = $this->geo->countryCode ?? '';
$regions = $this->geo->regionCodes ?? [];
if (empty($country) || empty($regions))
{
return false;
}
array_walk($regions, function (&$region, $key, $country) {
$region = $this->getCountryRegionCode($region, $country);
}, $country);
return $this->passSimple($regions);
}
private function getCountryRegionCode(string $region, string $country): string
{
return match ($country . '-' . $region)
{
'MX-CMX' => 'MX-DIF',
default => $country . '-' . $region,
};
}
}

View File

@ -0,0 +1,33 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition;
defined('_JEXEC') or die;
use RegularLabs\Library\ArrayHelper as RL_Array;
/**
* Class ConditionList
*
* @package RegularLabs\Library
*/
trait HasArraySelection
{
protected function prepareSelection(): void
{
if ( ! is_array($this->selection))
{
$this->selection = RL_Array::toArray($this->selection);
$this->selection = RL_Array::clean($this->selection);
}
}
}

View File

@ -0,0 +1,112 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Hikashop;
defined('_JEXEC') or die;
use Joomla\CMS\Factory as JFactory;
use RegularLabs\Component\Conditions\Administrator\Condition\HasArraySelection;
use RegularLabs\Library\Input as RL_Input;
class Category extends Hikashop
{
use HasArraySelection;
public function pass(): bool
{
if ($this->request->option !== 'com_hikashop')
{
return false;
}
if (empty($this->selection))
{
return false;
}
$app = JFactory::getApplication();
$page_types = $this->params->page_types ?? [];
$is_category = $this->request->view == 'category' || $this->request->layout == 'listing';
$is_item = $this->request->view == 'product';
if (
! (in_array('categories', $page_types) && $is_category)
&& ! (in_array('items', $page_types) && $is_item)
&& ! (RL_Input::getInt('rl_qp') && ! empty($this->getCategoryIds()))
)
{
return false;
}
$category_ids = $this->getCategoryIds($is_category);
$pass = $this->passSimple($category_ids);
if ($pass)
{
// If passed, return false if assigned to only children
// Else return true
return (int) $this->params->include_children !== 2;
}
if ( ! $this->params->include_children)
{
return false;
}
$parent_ids = [];
foreach ($category_ids as $category_id)
{
$parent_ids = [...$parent_ids, ...$this->getCategoryParentIds((int) $category_id)];
}
return $this->passSimple($parent_ids);
}
private function getCategoryIds(bool $is_category = false): array
{
if ($is_category)
{
return (array) $this->request->id;
}
switch (true)
{
case ($this->request->view == 'category' || $this->request->layout == 'listing'):
include_once JPATH_ADMINISTRATOR . '/components/com_hikashop/helpers/helper.php';
$menuClass = hikashop_get('class.menus');
$menuData = $menuClass->get($this->request->Itemid);
return $this->makeArray($menuData->hikashop_params['selectparentlisting']);
case ($this->request->id):
$query = $this->db->getQuery(true)
->select('c.category_id')
->from('#__hikashop_product_category AS c')
->where('c.product_id = ' . (int) $this->request->id);
$this->db->setQuery($query);
$cats = $this->db->loadColumn();
return $this->makeArray($cats);
default:
return [];
}
}
private function getCategoryParentIds(int $id = 0): array
{
return $this->getParentIds($id, 'hikashop_category', 'category_parent_id', 'category_id');
}
}

View File

@ -0,0 +1,21 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Hikashop;
defined('_JEXEC') or die;
use RegularLabs\Component\Conditions\Administrator\Condition\Condition;
use RegularLabs\Component\Conditions\Administrator\Condition\Traits\isContent;
abstract class Hikashop extends Condition
{
}

View File

@ -0,0 +1,36 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Hikashop;
defined('_JEXEC') or die;
use RegularLabs\Component\Conditions\Administrator\Condition\HasArraySelection;
class Item extends Hikashop
{
use HasArraySelection;
public function pass(): bool
{
if ($this->request->option !== 'com_hikashop')
{
return false;
}
if ($this->request->view !== 'product')
{
return false;
}
return $this->passSimple($this->request->id);
}
}

View File

@ -0,0 +1,47 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Hikashop;
use RegularLabs\Component\Conditions\Administrator\Condition\HasArraySelection;
defined('_JEXEC') or die;
class PageType extends Hikashop
{
use HasArraySelection;
public function pass(): bool
{
if ($this->request->option !== 'com_hikashop')
{
return false;
}
$type = $this->request->view;
if (
($type == 'product' && in_array($this->request->task, ['contact', 'show']))
)
{
$type .= '_' . $this->request->task;
}
elseif (
($type == 'product' && in_array($this->request->layout, ['contact', 'show']))
|| ($type == 'user' && in_array($this->request->layout, ['cpanel']))
)
{
$type .= '_' . $this->request->layout;
}
return $this->passSimple($type);
}
}

View File

@ -0,0 +1,191 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Menu;
defined('_JEXEC') or die;
use Joomla\CMS\Factory as JFactory;
use Joomla\CMS\Language\LanguageHelper as JLanguageHelper;
use Joomla\CMS\Menu\MenuItem as JMenuItem;
use Joomla\CMS\Uri\Uri as JUri;
use RegularLabs\Component\Conditions\Administrator\Condition\Condition;
use RegularLabs\Library\Input as RL_Input;
use RegularLabs\Library\RegEx;
use RegularLabs\Library\StringHelper;
class HomePage extends Condition
{
public function pass(): bool
{
$home = JFactory::getApplication()->getMenu('site')->getDefault(JFactory::getApplication()->getLanguage()->getTag());
// return if option or other set values do not match the homepage menu item values
if ( ! $this->request->option)
{
return $this->checkPass($home) || $this->checkPass($home, true);
}
// check if option is different to home menu
if ( ! $home || ! isset($home->query['option']) || $home->query['option'] != $this->request->option)
{
return false;
}
if ( ! $this->request->option)
{
// set the view/task/layout in the menu item to empty if not set
$home->query['view'] ??= '';
$home->query['task'] ??= '';
$home->query['layout'] ??= '';
}
// check set values against home menu query items
foreach ($home->query as $key => $value)
{
if (
(isset($this->request->{$key}) && $this->request->{$key} != $value)
|| (
( ! isset($this->request->{$key})
|| in_array($value, [
'virtuemart', 'mijoshop'
]))
&& RL_Input::get($key) != $value
)
)
{
return false;
}
}
// check post values against home menu params
foreach ($home->getParams() as $key => $value)
{
if (
($value && isset($_POST[$key]) && $_POST[$key] != $value)
|| ( ! $value && isset($_POST[$key]) && $_POST[$key])
)
{
return false;
}
}
return $this->checkPass($home) || $this->checkPass($home, true);
}
private function checkPass(?JMenuItem &$home, bool $addlang = false): bool
{
$uri = JUri::getInstance();
if ($addlang)
{
$sef = $uri->getVar('lang');
if (empty($sef))
{
$langs = array_keys(JLanguageHelper::getLanguages('sef'));
$path = StringHelper::substr(
$uri->toString(['scheme', 'user', 'pass', 'host', 'port', 'path']),
StringHelper::strlen($uri->base())
);
$path = RegEx::replace('^index\.php/?', '', $path);
$parts = explode('/', $path);
$part = reset($parts);
if (in_array($part, $langs))
{
$sef = $part;
}
}
if (empty($sef))
{
return false;
}
}
$query = $uri->toString(['query']);
if ( ! str_contains($query, 'option=') && ! str_contains($query, 'Itemid='))
{
$url = $uri->toString(['host', 'path']);
}
else
{
$url = $uri->toString(['host', 'path', 'query']);
}
// remove the www.
$url = RegEx::replace('^www\.', '', $url);
// replace ampersand chars
$url = str_replace('&amp;', '&', $url);
// remove any language vars
$url = RegEx::replace('((\?)lang=[a-z-_]*(&|$)|&lang=[a-z-_]*)', '\2', $url);
// remove trailing nonsense
$url = trim(RegEx::replace('/?\??&?$', '', $url));
// remove the index.php/
$url = RegEx::replace('/index\.php(/|$)', '/', $url);
// remove trailing /
$url = trim(RegEx::replace('/$', '', $url));
$root = JUri::root();
// remove the http(s)
$root = RegEx::replace('^.*?://', '', $root);
// remove the www.
$root = RegEx::replace('^www\.', '', $root);
//remove the port
$root = RegEx::replace(':[0-9]+', '', $root);
// so also passes on urls with trailing /, ?, &, /?, etc...
$root = RegEx::replace('(Itemid=[0-9]*).*^', '\1', $root);
// remove trailing /
$root = trim(RegEx::replace('/$', '', $root));
if ($addlang)
{
$root .= '/' . $sef;
}
/* Pass urls:
* [root]
*/
$regex = '^' . $root . '$';
if (RegEx::match($regex, $url))
{
return true;
}
/* Pass urls:
* [root]?Itemid=[menu-id]
* [root]/?Itemid=[menu-id]
* [root]/index.php?Itemid=[menu-id]
* [root]/[menu-alias]
* [root]/[menu-alias]?Itemid=[menu-id]
* [root]/index.php?[menu-alias]
* [root]/index.php?[menu-alias]?Itemid=[menu-id]
* [root]/[menu-link]
* [root]/[menu-link]&Itemid=[menu-id]
*/
$regex = '^' . $root
. '(/('
. 'index\.php'
. '|'
. '(index\.php\?)?' . RegEx::quote($home->alias)
. '|'
. RegEx::quote($home->link)
. ')?)?'
. '(/?[\?&]Itemid=' . (int) $home->id . ')?'
. '$';
return RegEx::match($regex, $url);
}
}

View File

@ -0,0 +1,109 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Menu;
defined('_JEXEC') or die;
use Joomla\CMS\Factory as JFactory;
use RegularLabs\Component\Conditions\Administrator\Condition\Condition;
use RegularLabs\Component\Conditions\Administrator\Condition\HasArraySelection;
use RegularLabs\Library\Document as RL_Document;
class MenuItem extends Condition
{
use HasArraySelection;
public function pass(): bool
{
// return if no Itemid or selection is set
if ( ! $this->request->Itemid || empty($this->selection))
{
return false;
}
// return true if menu is in selection
if (in_array($this->request->Itemid, $this->selection))
{
return (int) $this->params->include_children !== 2;
}
// return false if selection is 0 or empty
if (count($this->selection) === 1 && empty($this->selection[0]))
{
return false;
}
$menutype = 'type.' . self::getMenuType();
// return true if menu type is in selection
if (in_array($menutype, $this->selection))
{
return true;
}
if ( ! $this->params->include_children)
{
return false;
}
$parent_ids = $this->getMenuParentIds((int) $this->request->Itemid);
$parent_ids = array_diff($parent_ids, [1]);
foreach ($parent_ids as $parent_id)
{
if (in_array($parent_id, $this->selection))
{
return true;
}
}
return false;
}
private function getMenuParentIds(int $id = 0): array
{
return $this->getParentIds($id, 'menu');
}
private function getMenuType(): string
{
if (isset($this->request->menutype))
{
return $this->request->menutype;
}
if (empty($this->request->Itemid))
{
$this->request->menutype = '';
return $this->request->menutype;
}
if (RL_Document::isClient('site'))
{
$menu = JFactory::getApplication()->getMenu()->getItem((int) $this->request->Itemid);
$this->request->menutype = $menu->menutype ?? '';
return $this->request->menutype;
}
$query = $this->db->getQuery(true)
->select('m.menutype')
->from('#__menu AS m')
->where('m.id = ' . (int) $this->request->Itemid);
$this->db->setQuery($query);
$this->request->menutype = $this->db->loadResult();
return $this->request->menutype;
}
}

View File

@ -0,0 +1,42 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Other;
defined('_JEXEC') or die;
use RegularLabs\Component\Conditions\Administrator\Condition\Condition;
use RegularLabs\Component\Conditions\Administrator\Condition\HasArraySelection;
use RegularLabs\Library\Input as RL_Input;
/**
* Class Component
*
* @package RegularLabs\Library\Condition
*/
class Component extends Condition
{
use HasArraySelection;
public function pass(): bool
{
$option = RL_Input::getCmd('option') == 'com_categories'
? 'com_categories'
: $this->request->option;
$options = [
strtolower($option),
strtolower(str_replace('com_', '', $option)),
];
return $this->passSimple($options);
}
}

View File

@ -0,0 +1,32 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Other;
defined('_JEXEC') or die;
use RegularLabs\Component\Conditions\Administrator\Api\Conditions as Api_Conditions;
use RegularLabs\Component\Conditions\Administrator\Condition\Condition as BaseCondition;
/**
* Class Component
*
* @package RegularLabs\Library\Condition
*/
class Condition extends BaseCondition
{
public function pass(): bool
{
return (new Api_Conditions($this->article))
->setConditionByMixed($this->selection)
->pass();
}
}

View File

@ -0,0 +1,32 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Other;
defined('_JEXEC') or die;
use RegularLabs\Component\Conditions\Administrator\Condition\Condition;
use RegularLabs\Library\Php as RL_Php;
class Php extends Condition
{
public function pass(): bool
{
if ( ! is_array($this->selection))
{
$this->selection = [$this->selection];
}
$code = '<?php ' . implode(";\n", $this->selection) . '; ?>';
return RL_Php::execute($code, $this->article, $this->module, true) ? true : false;
}
}

View File

@ -0,0 +1,223 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Other;
defined('_JEXEC') or die;
use RegularLabs\Component\Conditions\Administrator\Condition\Condition;
use RegularLabs\Component\Conditions\Administrator\Condition\HasArraySelection;
use RegularLabs\Component\Conditions\Administrator\Helper\Cache;
class Tag extends Condition
{
use HasArraySelection;
public function pass(): bool
{
if ( ! $this->request->id)
{
return false;
}
if (in_array($this->request->option, ['com_content', 'com_flexicontent']))
{
return $this->passTagsContent();
}
if (
$this->request->option != 'com_tags'
|| $this->request->view != 'tag'
)
{
return false;
}
return $this->passTag($this->request->id);
}
private function getTag(int $tag_id): ?object
{
$query = $this->db->getQuery(true)
->select(['t.id', 't.alias', 't.title', 't.parent_id'])
->from('#__tags as t')
->where('t.id = ' . (int) $tag_id);
$this->db->setQuery($query);
return $this->db->loadObject();
}
private function getTagsParents(int $id = 0): array
{
if ( ! $id)
{
return [];
}
$cache = new Cache;
if ($cache->exists())
{
return $cache->get();
}
$parents = [];
while ($id)
{
$tag = $this->getTag($id);
// Break if no parent is found or parent already found before for some reason
if ( ! $tag || ! $tag->id || isset($parents[$tag->id]))
{
break;
}
$id = $tag->parent_id ?? 0;
$parents[$tag->id] = $tag;
}
// Remove the root tag
unset($parents[1]);
return $cache->set($parents);
}
private function passTag(int $tag_id): bool
{
$tag = $this->getTag($tag_id);
$pass = $this->tagIsInSelection($tag);
if ($pass)
{
// If passed, return false if assigned to only children
// Else return true
return (int) $this->params->include_children !== 2;
}
if ( ! $this->params->include_children)
{
return false;
}
// Return true if a parent is in the selection
$parents = $this->getTagsParents($tag->parent_id);
foreach ($parents as $parent)
{
if ($this->tagIsInSelection($parent))
{
return true;
}
}
return false;
}
private function passTagList(array $tags): bool
{
if ($this->params->match_all ?? false)
{
return $this->passTagListMatchAll($tags);
}
foreach ($tags as $tag)
{
if ( ! $this->passTag($tag->id))
{
continue;
}
return true;
}
return false;
}
private function passTagListMatchAll(array $tags): bool
{
foreach ($this->selection as $id)
{
if ( ! $this->passTagMatchAll($id, $tags))
{
return false;
}
}
return true;
}
private function passTagMatchAll(int|string $id, array $tags): bool
{
foreach ($tags as $tag)
{
if ($tag->id == $id || $tag->alias == $id || $tag->title == $id)
{
return true;
}
}
return false;
}
private function passTagsContent(): bool
{
$is_item = in_array($this->request->view, ['', 'article', 'item']);
$is_category = in_array($this->request->view, ['category']);
switch (true)
{
case ($is_item):
$prefix = 'com_content.article';
break;
case ($is_category):
$prefix = 'com_content.category';
break;
default:
return false;
}
// Load the tags.
$query = $this->db->getQuery(true)
->select($this->db->quoteName('t.id'))
->select($this->db->quoteName('t.title'))
->from('#__tags AS t')
->join(
'INNER', '#__contentitem_tag_map AS m'
. ' ON m.tag_id = t.id'
. ' AND m.type_alias = ' . $this->db->quote($prefix)
. ' AND m.content_item_id = ' . (int) $this->request->id
);
$this->db->setQuery($query);
$tags = $this->db->loadObjectList();
if (empty($tags))
{
return false;
}
return $this->passTagList($tags);
}
private function tagIsInSelection(object $tag): bool
{
return $tag
&& (
in_array($tag->id ?? 0, $this->selection)
|| in_array($tag->alias ?? '', $this->selection)
|| in_array($tag->title ?? '', $this->selection)
);
}
}

View File

@ -0,0 +1,75 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Other;
defined('_JEXEC') or die;
use Joomla\CMS\Factory as JFactory;
use RegularLabs\Component\Conditions\Administrator\Condition\Condition;
use RegularLabs\Component\Conditions\Administrator\Condition\HasArraySelection;
class Template extends Condition
{
use HasArraySelection;
public function getTemplate(): object
{
$template = JFactory::getApplication()->getTemplate(true);
if (isset($template->id))
{
return $template;
}
$params = json_encode($template->params);
// Find template style id based on params, as the template style id is not always stored in the getTemplate
$query = $this->db->getQuery(true)
->select('id')
->from('#__template_styles AS s')
->where('s.client_id = 0')
->where('s.template = ' . $this->db->quote($template->template))
->where('s.params = ' . $this->db->quote($params))
->setLimit(1);
$this->db->setQuery($query);
$template->id = $this->db->loadResult('id');
if ($template->id)
{
return $template;
}
// No template style id is found, so just grab the first result based on the template name
$query->clear('where')
->where('s.client_id = 0')
->where('s.template = ' . $this->db->quote($template->template))
->setLimit(1);
$this->db->setQuery($query);
$template->id = $this->db->loadResult('id');
return $template;
}
public function pass(): bool
{
$template = $this->getTemplate();
// Put template name and name + style id into array
// The '::' separator was used in pre Joomla 3.3
$template = [
$template->template, $template->template . '--' . $template->id,
$template->template . '::' . $template->id
];
return $this->passSimple($template, null, true);
}
}

View File

@ -0,0 +1,91 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Other;
defined('_JEXEC') or die;
use Joomla\CMS\Uri\Uri as JUri;
use RegularLabs\Component\Conditions\Administrator\Condition\Condition;
use RegularLabs\Library\RegEx;
use RegularLabs\Library\StringHelper;
class Url extends Condition
{
public function pass(): bool
{
$regex = $this->params->regex ?? false;
$case_sensitive = $this->params->case_sensitive ?? false;
if ( ! is_array($this->selection))
{
$this->selection = explode("\n", $this->selection);
}
if (count($this->selection) == 1)
{
$this->selection = explode("\n", $this->selection[0]);
}
$url = JUri::getInstance();
$url = $url->toString();
$urls = [
StringHelper::html_entity_decoder(urldecode($url)),
urldecode($url),
StringHelper::html_entity_decoder($url),
$url,
];
$urls = array_unique($urls);
foreach ($urls as $url)
{
if ( ! $case_sensitive)
{
$url = StringHelper::strtolower($url);
}
foreach ($this->selection as $selection)
{
$selection = trim($selection);
if ($selection == '')
{
continue;
}
if ($regex)
{
$url_part = str_replace(['#', '&amp;'], ['\#', '(&amp;|&)'], $selection);
if (@RegEx::match($url_part, $url, $match, $case_sensitive ? 's' : 'si'))
{
return true;
}
continue;
}
if ( ! $case_sensitive)
{
$selection = StringHelper::strtolower($selection);
}
if (str_contains($url, $selection))
{
return true;
}
}
}
return false;
}
}

View File

@ -0,0 +1,79 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Visitor;
defined('_JEXEC') or die;
use Joomla\CMS\Factory as JFactory;
use RegularLabs\Component\Conditions\Administrator\Condition\Condition;
use RegularLabs\Component\Conditions\Administrator\Condition\HasArraySelection;
use RegularLabs\Library\DB as RL_DB;
class AccessLevel extends Condition
{
use HasArraySelection;
public function pass(): bool
{
$user = JFactory::getApplication()->getIdentity() ?: JFactory::getUser();
$levels = $user->getAuthorisedViewLevels();
$this->selection = $this->convertAccessLevelNamesToIds($this->selection);
if ($this->params->match_all ?? false)
{
return $this->passMatchAll($levels);
}
return $this->passSimple($levels);
}
private function convertAccessLevelNamesToIds(array $selection): array
{
$names = [];
foreach ($selection as $i => $level)
{
if (is_numeric($level))
{
continue;
}
unset($selection[$i]);
$names[] = strtolower(str_replace(' ', '', $level));
}
if (empty($names))
{
return $selection;
}
$db = RL_DB::get();
$query = $db->getQuery(true)
->select($db->quoteName('id'))
->from('#__viewlevels')
->where(RL_DB::in('LOWER(REPLACE(' . $db->quoteName('title') . ', " ", ""))', $names, [], false));
$db->setQuery($query);
$level_ids = $db->loadColumn();
return array_unique([...$selection, ...$level_ids]);
}
private function passMatchAll(array $groups): bool
{
return empty(array_diff($this->selection, $groups));
}
}

View File

@ -0,0 +1,193 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Visitor;
defined('_JEXEC') or die;
use RegularLabs\Component\Conditions\Administrator\Condition\Condition;
class Ip extends Condition
{
public function pass(): bool
{
if (is_array($this->selection))
{
$this->selection = implode(',', $this->selection);
}
$this->selection = $this->getIPsFromString($this->selection);
return $this->checkIPList();
}
private function getIPsFromString(?string $string): array
{
if (is_array($string))
{
$this->selection = implode('\n', $this->selection);
}
$string = str_replace("\r", "\n", $string);
$string = preg_replace('#\s*(\#|\/\/).*?(\n|$)#', "\n", $string);
$string = str_replace(',', "\n", $string);
$string = preg_replace('#\n\n+#', "\n", $string);
$string = trim($string);
return explode("\n", $string);
}
private function checkIP(?string $range): bool
{
if (empty($range))
{
return false;
}
if (str_contains($range, '-'))
{
// Selection is an IP range
return $this->checkIPRange($range);
}
// Selection is a single IP (part)
return $this->checkIPPart($range);
}
private function checkIPList(): bool
{
foreach ($this->selection as $range)
{
// Check next range if this one doesn't match
if ( ! $this->checkIP($range))
{
continue;
}
// Match found, so return true!
return true;
}
// No matches found, so return false
return false;
}
private function checkIPPart(string $range): bool
{
$ip = $this->getIP();
// Return if no IP address can be found (shouldn't happen, but who knows)
if (empty($ip))
{
return false;
}
$ip_parts = explode('.', $ip);
$range_parts = explode('.', trim($range));
// Trim the IP to the part length of the range
$ip = implode('.', array_slice($ip_parts, 0, count($range_parts)));
// Return false if ip does not match the range
if ($range != $ip)
{
return false;
}
return true;
}
/* Fill the max range by prefixing it with the missing parts from the min range
* So 101.102.103.104-201.202 becomes:
* max: 101.102.201.202
*/
private function checkIPRange(string $range): bool
{
$ip = $this->getIP();
// Return if no IP address can be found (shouldn't happen, but who knows)
if (empty($ip))
{
return false;
}
// check if IP is between or equal to the from and to IP range
[$min, $max] = explode('-', trim($range), 2);
// Return false if IP is smaller than the range start
if ($ip < trim($min))
{
return false;
}
$max = $this->fillMaxRange($max, $min);
// Return false if IP is larger than the range end
if ($ip > trim($max))
{
return false;
}
return true;
}
private function fillMaxRange(string $max, string $min): string
{
$max_parts = explode('.', $max);
if (count($max_parts) == 4)
{
return $max;
}
$min_parts = explode('.', $min);
$prefix = array_slice($min_parts, 0, count($min_parts) - count($max_parts));
return implode('.', $prefix) . '.' . implode('.', $max_parts);
}
private function getIP(): string
{
if ( ! empty($_SERVER['HTTP_CF_CONNECTING_IP']) && $this->isValidIp($_SERVER['HTTP_CF_CONNECTING_IP']))
{
return $_SERVER['HTTP_CF_CONNECTING_IP'];
}
if ( ! empty($_SERVER['HTTP_TRUE_CLIENT_IP']) && $this->isValidIp($_SERVER['HTTP_TRUE_CLIENT_IP']))
{
return $_SERVER['HTTP_TRUE_CLIENT_IP'];
}
if ( ! empty($_SERVER['HTTP_X_FORWARDED_FOR']) && $this->isValidIp($_SERVER['HTTP_X_FORWARDED_FOR']))
{
return $_SERVER['HTTP_X_FORWARDED_FOR'];
}
if ( ! empty($_SERVER['HTTP_X_REAL_IP']) && $this->isValidIp($_SERVER['HTTP_X_REAL_IP']))
{
return $_SERVER['HTTP_X_REAL_IP'];
}
if ( ! empty($_SERVER['HTTP_CLIENT_IP']) && $this->isValidIp($_SERVER['HTTP_CLIENT_IP']))
{
return $_SERVER['HTTP_CLIENT_IP'];
}
return $_SERVER['REMOTE_ADDR'];
}
private function isValidIp(string $string): bool
{
return preg_match('#^([0-9]{1,3}\.){3}[0-9]{1,3}$#', $string);
}
}

View File

@ -0,0 +1,28 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Visitor;
defined('_JEXEC') or die;
use Joomla\CMS\Factory as JFactory;
use RegularLabs\Component\Conditions\Administrator\Condition\Condition;
use RegularLabs\Component\Conditions\Administrator\Condition\HasArraySelection;
class Language extends Condition
{
use HasArraySelection;
public function pass(): bool
{
return $this->passSimple(JFactory::getApplication()->getLanguage()->getTag(), null, true);
}
}

View File

@ -0,0 +1,30 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Visitor;
defined('_JEXEC') or die;
use Joomla\CMS\Factory as JFactory;
use RegularLabs\Component\Conditions\Administrator\Condition\Condition;
use RegularLabs\Component\Conditions\Administrator\Condition\HasArraySelection;
class User extends Condition
{
use HasArraySelection;
public function pass(): bool
{
$user = JFactory::getApplication()->getIdentity() ?: JFactory::getUser();
return $this->passSimple($user->get('id'));
}
}

View File

@ -0,0 +1,163 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Visitor;
defined('_JEXEC') or die;
use Joomla\CMS\Factory as JFactory;
use RegularLabs\Component\Conditions\Administrator\Condition\Condition;
use RegularLabs\Component\Conditions\Administrator\Condition\HasArraySelection;
use RegularLabs\Library\DB as RL_DB;
class UserGroup extends Condition
{
use HasArraySelection;
static $user_group_children;
public function pass(): bool
{
$user = JFactory::getApplication()->getIdentity() ?: JFactory::getUser();
$groups = ! empty($user->groups)
? array_values($user->groups)
: $user->getAuthorisedGroups();
if ( ! $this->params->match_all && $this->params->include_children)
{
$this->setUserGroupChildrenIds();
}
$this->selection = $this->convertUsergroupNamesToIds($this->selection);
if ($this->params->match_all ?? false)
{
return $this->passMatchAll($groups);
}
return $this->passSimple($groups);
}
private function convertUsergroupNamesToIds(array $selection): array
{
$names = [];
foreach ($selection as $i => $group)
{
if (is_numeric($group))
{
continue;
}
unset($selection[$i]);
$names[] = strtolower(str_replace(' ', '', $group));
}
if (empty($names))
{
return $selection;
}
$db = RL_DB::get();
$query = $db->getQuery(true)
->select($db->quoteName('id'))
->from('#__usergroups')
->where(RL_DB::in('LOWER(REPLACE(' . $db->quoteName('title') . ', " ", ""))', $names, [], false));
$db->setQuery($query);
$group_ids = $db->loadColumn();
return array_unique([...$selection, ...$group_ids]);
}
private function getUserGroupChildrenIds(array $groups): array
{
$children = [];
foreach ($groups as $group)
{
$group_children = $this->getUserGroupChildrenIdsByGroup($group);
if (empty($group_children))
{
continue;
}
$children = [...$children, ...$group_children];
$group_grand_children = $this->getUserGroupChildrenIds($group_children);
if (empty($group_grand_children))
{
continue;
}
$children = [...$children, ...$group_grand_children];
}
$children = array_unique($children);
return $children;
}
private function getUserGroupChildrenIdsByGroup(?int $group): array
{
$group = (int) $group;
if ( ! is_null(self::$user_group_children))
{
return self::$user_group_children[$group] ?? [];
}
$db = RL_DB::get();
$query = $db->getQuery(true)
->select(['id', 'parent_id'])
->from($db->quoteName('#__usergroups'));
$db->setQuery($query);
$groups = $db->loadAssocList('id', 'parent_id');
foreach ($groups as $id => $parent)
{
if ( ! isset(self::$user_group_children[$parent]))
{
self::$user_group_children[$parent] = [];
}
self::$user_group_children[$parent][] = $id;
}
return self::$user_group_children[$group] ?? [];
}
private function passMatchAll(array $groups): bool
{
return empty(array_diff($this->selection, $groups));
}
private function setUserGroupChildrenIds(): void
{
$children = $this->getUserGroupChildrenIds($this->selection);
if (($this->params->include_children ?? 0) === 2)
{
$this->selection = $children;
return;
}
$this->selection = [...$this->selection, ...$children];
}
}

View File

@ -0,0 +1,168 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Zoo;
defined('_JEXEC') or die;
use RegularLabs\Component\Conditions\Administrator\Condition\HasArraySelection;
use RegularLabs\Library\Input as RL_Input;
class Category extends Zoo
{
use HasArraySelection;
public function pass(): bool
{
if ($this->request->option !== 'com_zoo')
{
return false;
}
if (empty($this->selection))
{
return false;
}
$page_types = $this->params->page_types ?? [];
$is_category = $this->request->view == 'category';
$is_item = $this->request->view == 'item';
if (
! (in_array('categories', $page_types) && $is_category)
&& ! (in_array('items', $page_types) && $is_item)
&& ! (RL_Input::getInt('rl_qp') && ! empty($this->getCategoryIds()))
)
{
return false;
}
$category_ids = $this->getCategoryIds($is_category);
$pass = $this->passSimple($category_ids);
if ($pass)
{
// If passed, return false if assigned to only children
// Else return true
return (int) $this->params->include_children !== 2;
}
if ( ! $this->params->include_children)
{
return false;
}
$parent_ids = [];
foreach ($category_ids as $category_id)
{
$parent_ids = [...$parent_ids, ...$this->getCategoryParentIds((int) $category_id)];
}
return $this->passSimple($parent_ids);
}
private function getCategoryIds(bool $is_category = false): array
{
if ($is_category)
{
return (array) $this->request->id;
}
if ($this->article && isset($this->article->catid))
{
return [$this->article->catid];
}
$menuparams = $this->getMenuItemParams($this->request->Itemid);
switch ($this->request->view)
{
case 'frontpage':
if ($this->request->id)
{
return [$this->request->id];
}
if ( ! isset($menuparams->application))
{
return [];
}
return ['app' . $menuparams->application];
case 'category':
$cats = [];
if ($this->request->id)
{
$cats[] = $this->request->id;
}
elseif (isset($menuparams->category))
{
$cats[] = $menuparams->category;
}
if (empty($cats[0]))
{
return [];
}
$query = $this->db->getQuery(true)
->select('c.application_id')
->from('#__zoo_category AS c')
->where('c.id = ' . (int) $cats[0]);
$this->db->setQuery($query);
$cats[] = 'app' . $this->db->loadResult();
return $cats;
case 'item':
$id = $this->request->id;
if ( ! $id && isset($menuparams->item_id))
{
$id = $menuparams->item_id;
}
if ( ! $id)
{
return [];
}
$query = $this->db->getQuery(true)
->select('c.category_id')
->from('#__zoo_category_item AS c')
->where('c.item_id = ' . (int) $id)
->where('c.category_id != 0');
$this->db->setQuery($query);
$cats = $this->db->loadColumn();
$query = $this->db->getQuery(true)
->select('i.application_id')
->from('#__zoo_item AS i')
->where('i.id = ' . (int) $id);
$this->db->setQuery($query);
$cats[] = 'app' . $this->db->loadResult();
return $cats;
default:
return false;
}
}
private function getCategoryParentIds(int $id = 0): array
{
return $this->getParentIds($id, 'zoo_category', 'parent', 'id');
}
}

View File

@ -0,0 +1,36 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Zoo;
defined('_JEXEC') or die;
use RegularLabs\Component\Conditions\Administrator\Condition\HasArraySelection;
class Item extends Zoo
{
use HasArraySelection;
public function pass(): bool
{
if ($this->request->option !== 'com_zoo')
{
return false;
}
if ($this->request->view !== 'item')
{
return false;
}
return $this->passSimple($this->request->id);
}
}

View File

@ -0,0 +1,26 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Zoo;
use RegularLabs\Component\Conditions\Administrator\Condition\HasArraySelection;
defined('_JEXEC') or die;
class PageType extends Zoo
{
use HasArraySelection;
public function pass(): bool
{
return $this->passByPageType('com_zoo', $this->selection, true);
}
}

View File

@ -0,0 +1,72 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Condition\Zoo;
defined('_JEXEC') or die;
use Joomla\CMS\Factory as JFactory;
use Joomla\CMS\Menu\MenuItem as JMenuItem;
use RegularLabs\Component\Conditions\Administrator\Condition\Condition;
use RegularLabs\Library\Input as RL_Input;
abstract class Zoo extends Condition
{
protected $request_keys = ['controller'];
public function beforePass(): void
{
if ( ! $this->request->option == 'com_zoo')
{
return;
}
$full_request = RL_Input::getArray();
$this->request->view = $this->request->task ?: $this->request->view;
$this->request->idname = match ($this->request->view)
{
'item' => 'item_id',
'category' => 'category_id',
default => 'id',
};
if ( ! isset($full_request[$this->request->idname]))
{
$this->request->idname = 'id';
}
$this->request->id = $this->request->{$this->request->idname}
?? RL_Input::getInt($this->request->idname, 0);
if ($this->request->id)
{
return;
}
$app = JFactory::getApplication();
/* @var JMenuItem $menu_item */
$menu = empty(self::$_request->Itemid)
? $app->getMenu('site')->getActive()
: $app->getMenu('site')->getItem(self::$_request->Itemid);
if (empty($menu))
{
return;
}
$id_name = $this->request->view == 'category' ? 'category' : 'item_id';
$this->request->id = $menu->getParams()->get($id_name, 0);
}
}

View File

@ -0,0 +1,53 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Controller;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\Controller\FormController;
use Joomla\CMS\Router\Route;
defined('_JEXEC') or die;
/**
* Conditions master display controller.
*/
class DisplayController extends FormController
{
protected $default_view = 'items';
/**
* @param boolean $cachable If true, the view output will be cached.
* @param mixed $urlparams An array of safe URL parameters and their variable types, for valid values see {@link \JFilterInput::clean()}.
*
* @return static|boolean This object to support chaining or false on failure.
*/
public function display($cachable = false, $urlparams = false)
{
$view = $this->input->get('view', $this->default_view);
$layout = $this->input->get('layout', $view == 'item' ? 'edit' : 'default');
$id = $this->input->getInt('id');
// Check for edit form.
if ($view == 'item' && $layout == 'edit' && ! $this->checkEditId('com_conditions.edit.item', $id))
{
// Somehow the person just went to the form - we don't allow that.
$this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id), 'error');
$this->setRedirect(Route::_('index.php?option=com_conditions&view=items', false));
return false;
}
$this->input->set('layout', $layout);
return parent::display();
}
}

View File

@ -0,0 +1,233 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Controller;
use Joomla\CMS\MVC\Controller\FormController as JFormController;
use Joomla\CMS\Router\Route as JRoute;
use RegularLabs\Component\Conditions\Administrator\Helper\Helper;
use RegularLabs\Component\Conditions\Administrator\Model\ItemModel;
use RegularLabs\Library\Input as RL_Input;
defined('_JEXEC') or die;
class ItemController extends JFormController
{
/**
* @var string The prefix to use with controller messages.
*/
protected $text_prefix = 'RL';
/**
* Duplicate the item and then edit it
*/
public function copy()
{
$extension = $this->input->get('extension', '');
$item_id = $this->input->getInt('item_id');
$table = $this->input->get('table', '');
$name_column = $this->input->get('name_column', '');
$id = $this->input->getInt('id');
$name = '';
/* @var ItemModel $item_model */
$item_model = $this->getModel('Item');
if ( ! $id)
{
$condition = $item_model->getConditionByExtensionItem($extension, $item_id);
$id = $condition->id;
}
if ($extension && $item_id)
{
$name = Helper::getForItemText($extension, $item_id, $table, $name_column);
}
$condition = $item_model->duplicate($id, true, $name);
ItemModel::map($condition->id, $extension, $item_id);
$this->setRedirect(
JRoute::_(
'index.php?option=' . $this->option . '&view=' . $this->view_item
. '&task=item.edit'
. $this->getRedirectToItemAppend($condition->id), false
)
);
}
/**
* Map an existing condition to an extension item
*/
public function map()
{
$condition_id = $this->input->getInt('id');
$extension = $this->input->get('extension', '');
$item_id = $this->input->getInt('item_id');
$item_model = $this->getModel('Item');
$item_model->map($condition_id, $extension, $item_id);
RL_Input::set('tmpl', 'component');
RL_Input::set('layout', 'modal_update_summary');
return parent::display();
}
/**
* ...
*/
public function modaledit($data = [], $key = 'id')
{
$extension = $this->input->get('extension', '');
$item_id = $this->input->getInt('item_id');
$this->input->set('tmpl', 'component');
$this->input->set('layout', 'modal_edit');
if ( ! $extension)
{
return parent::display();
}
$item_model = $this->getModel('Item');
$condition = $item_model->getConditionByExtensionItem($extension, $item_id);
if ( ! $condition || $condition->nr_of_uses < 2)
{
return parent::display();
}
RL_Input::set('layout', 'modal_multiple_usage');
return parent::display();
}
/**
* Map an existing condition to an extension item
*/
public function remove_mapping()
{
$extension = $this->input->get('extension', '');
$item_id = $this->input->getInt('item_id');
$remove = $this->input->get('remove', '');
RL_Input::set('tmpl', 'component');
RL_Input::set('layout', 'modal_update_summary');
switch ($remove)
{
case 'all':
$this->getModel('Item')->trashByExtension($extension, $item_id);
break;
case 1:
ItemModel::removeMapping($extension, $item_id);
break;
default:
if (ItemModel::hasOtherUsesByExtensionItem($extension, $item_id))
{
ItemModel::removeMapping($extension, $item_id);
break;
}
RL_Input::set('layout', 'modal_remove_mapping');
break;
}
return parent::display();
}
/**
* Gets the URL arguments to append to an item redirect.
*
* @param integer $recordId The primary key id for the item.
* @param string $urlVar The name of the URL variable for the id.
*
* @return string The arguments to append to the redirect URL.
*/
protected function getRedirectToItemAppend($recordId = null, $urlVar = 'id')
{
$task = $this->getTask();
$layout = $this->input->getString('layout');
$is_modal = $this->input->get('tmpl', '') === 'component';
if ($is_modal && ! str_starts_with($layout, 'modal'))
{
$layout = 'modal_' . ($layout ?: 'edit');
}
if ($is_modal && $task === 'save')
{
$this->view_list = 'item';
$layout = 'modal_update_summary';
}
$params = [
$urlVar => $recordId,
'id' => $this->input->getInt('id'),
'extension' => $this->input->get('extension', ''),
'item_id' => $this->input->getInt('item_id'),
'table' => $this->input->get('table', ''),
'enabled_types' => $this->input->getString('enabled_types'),
'name_column' => $this->input->get('name_column', ''),
'message' => $this->input->get('message', ''),
'tmpl' => $this->input->getString('tmpl'),
'layout' => $layout,
'forcedLanguage' => $this->input->get('forcedLanguage', '', 'cmd'),
'return' => $this->input->getBase64('return'),
];
$append = http_build_query($params);
return $append ? '&' . $append : '';
}
/**
* Gets the URL arguments to append to a list redirect.
*
* @return string The arguments to append to the redirect URL.
*
* @since 1.6
*/
protected function getRedirectToListAppend()
{
$task = $this->getTask();
$is_modal = $this->input->get('tmpl', '') === 'component';
if ($is_modal && $task === 'save')
{
$layout = 'modal_update_summary';
}
$params = [
'id' => $this->input->getInt('id'),
'extension' => $this->input->get('extension', ''),
'item_id' => $this->input->getInt('item_id'),
'table' => $this->input->get('table', ''),
'name_column' => $this->input->get('name_column', ''),
'enabled_types' => $this->input->getString('enabled_types'),
'message' => $this->input->get('message', ''),
'tmpl' => $this->input->getString('tmpl'),
'layout' => $layout,
'forcedLanguage' => $this->input->get('forcedLanguage', '', 'cmd'),
];
$append = http_build_query($params);
return $append ? '&' . $append : '';
}
}

View File

@ -0,0 +1,87 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Controller;
use Joomla\CMS\MVC\Controller\AdminController;
use Joomla\CMS\MVC\Model\BaseDatabaseModel;
use Joomla\CMS\Router\Route;
defined('_JEXEC') or die;
class ItemsController extends AdminController
{
/**
* @var string The prefix to use with controller messages.
*/
protected $text_prefix = 'RL';
/**
* Duplicate Method
* Duplicate all items specified by array id
*/
public function duplicate()
{
$ids = $this->input->get('cid', [], 'array');
$model = $this->getModel('Items');
$item_model = $this->getModel('Item');
$model->duplicate($ids, $item_model);
$this->setRedirect(Route::_('index.php?option=com_conditions&view=items', false));
}
/**
* Export Method
* Export the selected items specified by id
*/
public function export()
{
$ids = $this->input->get('cid', [], 'array');
$model = $this->getModel('Items');
$model->export($ids);
}
/**
* Proxy for getModel.
*
* @param string $name The name of the model.
* @param string $prefix The prefix of the model.
* @param array $config An array of settings.
*
* @return BaseDatabaseModel The model instance
*/
public function getModel(
$name = 'Item',
$prefix = 'Administrator',
$config = ['ignore_request' => true]
)
{
return parent::getModel($name, $prefix, $config);
}
/**
* Import Method
* Set layout to import
*/
public function import()
{
$file = $this->input->files->get('file', null, 'raw');
// Get the model.
$model = $this->getModel('Items');
$model_item = $this->getModel('Item');
$model->import($file, $model_item);
$this->setRedirect(Route::_('index.php?option=com_conditions&view=items', false));
}
}

View File

@ -0,0 +1,25 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Extension;
use Joomla\CMS\Component\Router\RouterServiceInterface;
use Joomla\CMS\Component\Router\RouterServiceTrait;
use Joomla\CMS\Extension\MVCComponent;
use Joomla\CMS\HTML\HTMLRegistryAwareTrait;
defined('JPATH_PLATFORM') or die;
class Component extends MVCComponent implements RouterServiceInterface
{
use HTMLRegistryAwareTrait;
use RouterServiceTrait;
}

View File

@ -0,0 +1,388 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Form\Field;
defined('_JEXEC') or die;
use Joomla\CMS\Factory as JFactory;
use Joomla\CMS\Language\Text as JText;
use Joomla\CMS\Object\CMSObject as JCMSObject;
use RegularLabs\Component\Conditions\Administrator\Helper\Helper;
use RegularLabs\Component\Conditions\Administrator\Helper\Summary;
use RegularLabs\Component\Conditions\Administrator\Model\ItemModel;
use RegularLabs\Library\Document as RL_Document;
use RegularLabs\Library\Form\FormField as RL_FormField;
use RegularLabs\Library\Language as RL_Language;
use RegularLabs\Library\ShowOn as RL_ShowOn;
use RegularLabs\Library\StringHelper as RL_String;
class ConditionField extends RL_FormField
{
private $canCreate;
private $canEdit;
private $enabled_types;
private $extension;
private $item_id;
private $name_column;
private $table;
private $text_no_conditions;
private $user;
public function __construct($form = null)
{
parent::__construct($form);
$this->user = JFactory::getApplication()->getIdentity() ?: JFactory::getUser();
$this->canCreate = $this->user->authorise('core.create', 'com_conditions');
$this->canEdit = $this->user->authorise('core.edit', 'com_conditions');
}
public function getCondition(): ?object
{
return (new ItemModel)->getConditionByExtensionItem(
$this->extension,
$this->item_id,
false,
$this->enabled_types
);
}
protected function getButtonUrl($view, $task = 'edit', $layout = 'modal')
{
return 'index.php?option=com_conditions'
. '&view=' . $view
. ($task ? '&task=' . $view . '.' . $task : '')
. '&extension=' . $this->extension
. '&item_id=' . $this->item_id
. '&table=' . $this->table
. '&name_column=' . $this->name_column
. '&enabled_types=' . $this->enabled_types
. '&message=' . $this->text_no_conditions
. '&layout=' . $layout
. '&tmpl=component';
}
protected function getInput()
{
$this->extension = $this->get('extension', $this->app->input->getCmd('option', ''));
$this->item_id = $this->get('item_id', $this->app->input->getInt('id'));
$this->table = $this->get('table', $this->app->input->getCmd('table'));
$this->name_column = $this->get('name_column', $this->app->input->getCmd('name_column'));
$this->text_no_conditions = $this->get('text_no_conditions', $this->app->input->get('message', ''));
$this->enabled_types = $this->get('enable', '');
$this->enabled_types = str_replace(' ', '', $this->enabled_types);
// Fix incorrect table value
if ($this->table == 'array' || $this->table == 'Array')
{
$this->table = 'modules';
}
if ( ! $this->extension)
{
return '';
}
if ( ! $this->item_id)
{
return $this->getHtmlForNoItemId();
}
RL_Document::script('regularlabs.regular');
RL_Document::script('conditions.script');
RL_Language::load($this->extension);
$condition = $this->getCondition();
if ($condition && $condition->published !== 1)
{
$condition = null;
}
$has_conditions = ! empty($condition);
$html = [];
$html[] = '<input type="hidden" name="' . $this->getName('has_conditions') . '" id="' . $this->getId('', 'has_conditions') . '" value="' . (int) $has_conditions . '">';
$html[] = '<input type="hidden" name="' . $this->getName('condition_id') . '" id="' . $this->getId('', 'condition_id') . '" value="' . ($condition->id ?? '') . '">';
$html[] = '<input type="hidden" name="' . $this->getName('condition_alias') . '" id="' . $this->getId('', 'condition_alias') . '" value="' . RL_String::escape($condition->alias ?? '') . '">';
$html[] = '<input type="hidden" name="' . $this->getName('condition_name') . '" id="' . $this->getId('', 'condition_name') . '" value="' . RL_String::escape($condition->name ?? '') . '">';
$html[] = '<div id="rules_summary" class="position-relative">';
$html[] = '<div id="rules_summary_message" class="alert alert-warning' . ($has_conditions ? ' hidden' : '') . '">'
. '<span class="icon-info-circle text-info" aria-hidden="true"></span> '
. JText::_('CON_MESSAGE_NO_CONDITION_SELECTED')
. ($this->text_no_conditions ? '<br><br>' . JText::_($this->text_no_conditions) : '')
. '</div>';
$html[] = $this->getButtons();
$html[] = '<div id="rules_summary_content" class="mt-4">';
$html[] = Summary::render($condition, $this->extension, $this->text_no_conditions, $this->enable);
$html[] = '</div >';
$html[] = '</div >';
return implode('', $html);
}
protected function getLabel()
{
return '';
}
private function addSaveButtons(array &$options): void
{
$modal = 'this.closest(\'.modal-content\')';
$iframe = $modal . '.querySelector(\'.modal-body > iframe\')';
$hide_self = 'this.classList.add(\'hidden\');';
$apply = $hide_self . $modal . ' && ' . $iframe . ' && ' . $iframe . '.contentWindow.Joomla.submitbutton(\'item.apply\')';
$save = $hide_self . $modal . ' && ' . $iframe . ' && ' . $iframe . '.contentWindow.Joomla.submitbutton(\'item.save\')';
$options = [
...$options,
'keyboard' => false,
'backdrop' => 'static',
'confirmText' => JText::_('JAPPLY'),
'confirmCallback' => $apply,
'confirmClass' => 'btn btn-success hidden conditions-button',
'confirmIcon' => 'save',
'confirm2Text' => JText::_('JSAVE'),
'confirm2Callback' => $save,
'confirm2Class' => 'btn btn-success hidden conditions-button',
'confirm2Icon' => 'save',
];
}
private function getButton(
string $name,
string $text,
string $link,
string $icon,
string $class = 'primary',
array $options = []
): JCMSObject
{
$button = new JCMSObject;
$button->name = $this->id . '_' . $name;
$button->text = JText::_($text);
$button->icon = $icon;
$button->class = 'btn-' . $class . ' mb-1';
$button->options = $options;
if ($link)
{
$button->link = $link;
}
return $button;
}
private function getButtonCreate(): string
{
if ( ! $this->canCreate)
{
return '';
}
$options = [];
$this->addSaveButtons($options);
return $this->renderButtonAndModal(
'create',
'CON_BUTTON_CREATE',
$this->getButtonUrl('item', 'modaledit', 'modal_edit'),
'file-add',
'success',
$options
);
}
private function getButtonDelete(): string
{
return $this->renderButtonAndModal(
'delete',
'CON_BUTTON_REMOVE',
$this->getButtonUrl('item', 'remove_mapping'),
'times',
'danger',
[
'height' => '400px',
'width' => '400px',
'bodyHeight' => '400px',
'modalWidth' => '400px',
]
);
}
private function getButtonEdit(): string
{
if ( ! $this->canEdit)
{
return '';
}
$options = [];
$this->addSaveButtons($options);
return $this->renderButtonAndModal(
'edit',
'CON_BUTTON_EDIT',
$this->getButtonUrl('item', 'modaledit'),
'edit',
'warning',
$options
);
}
private function getButtonSelect(): string
{
if ( ! Helper::thereAreConditions())
{
return '';
}
return $this->renderButton(
'select',
'CON_BUTTON_SELECT',
$this->getButtonUrl('items', ''),
'hand-pointer'
);
}
private function getButtons(): string
{
$html = [
RL_ShowOn::open('has_conditions:1', $this->formControl),
$this->getButtonSelect(),
$this->getButtonEdit(),
$this->getButtonDelete(),
RL_ShowOn::close(),
RL_ShowOn::open('has_conditions:0', $this->formControl),
$this->getButtonSelect(),
$this->getButtonCreate(),
RL_ShowOn::close(),
$this->getModalSelect(),
];
return implode('', $html);
}
private function getHtmlForNoItemId(): string
{
$item_name = Helper::getExtensionItemString($this->extension);
return '<div class="alert alert-warning">'
. '<span class="icon-warning"></span> '
. JText::_('CON_MESSAGE_SAVE_ITEM_BEFORE_CREATING')
. '<br><br>'
. JText::sprintf('CON_MESSAGE_SAVE_AS_UNPUBLISHED', $item_name)
. '<br><br>'
. $this->getSaveButton(true)
. $this->getSaveButton(false)
. '</div>';
}
private function getModalButton(
string $name,
string $text,
string $link,
string $icon,
string $class = 'primary',
array $options = []
): JCMSObject
{
$button = $this->getButton($name, $text, $link, $icon, $class, $options);
$button->modal = true;
$button->options = [
'height' => '400px',
'width' => '800px',
'bodyHeight' => '70',
'modalWidth' => '80',
...$button->options,
];
return $button;
}
private function getModalSelect(): string
{
return $this->renderModal(
'select',
'CON_BUTTON_SELECT',
$this->getButtonUrl('items', ''),
'hand-pointer'
);
}
private function getSaveButton(bool $published = true): string
{
$button = $this->getButton(
$published ? 'save-published' : 'save-unpublished',
$published ? 'CON_SAVE_AS_PUBLISHED' : 'CON_SAVE_AS_UNPUBLISHED',
'',
'save',
$published ? 'warning' : 'success'
);
$button->onclick = '$("select#jform_state").val(' . ($published ? 1 : 0) . ');'
. '$("select#jform_published").val(' . ($published ? 1 : 0) . ');'
. '$("joomla-toolbar-button#toolbar-apply > button").click();';
return $this->getRenderer('regularlabs.buttons.button')
->addIncludePath(JPATH_SITE . '/libraries/regularlabs/layouts')
->render($button);
}
private function renderButton(
string $name,
string $text,
string $link,
string $icon,
string $class = 'primary',
array $options = []
): string
{
$button = $this->getModalButton($name, $text, $link, $icon, $class, $options);
return $this->getRenderer('regularlabs.buttons.button')
->addIncludePath(JPATH_SITE . '/libraries/regularlabs/layouts')
->render($button);
}
private function renderButtonAndModal(
string $name,
string $text,
string $link,
string $icon,
string $class = 'primary',
array $options = []
): string
{
return $this->renderButton($name, $text, $link, $icon, $class, $options)
. $this->renderModal($name, $text, $link, $icon, $class, $options);
}
private function renderModal(
string $name,
string $text,
string $link,
string $icon,
string $class = 'primary',
array $options = []
): string
{
$button = $this->getModalButton($name, $text, $link, $icon, $class, $options);
return $this->getRenderer('regularlabs.buttons.modal')
->addIncludePath(JPATH_SITE . '/libraries/regularlabs/layouts')
->render($button);
}
}

View File

@ -0,0 +1,239 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Form\Field;
defined('_JEXEC') or die;
use InvalidArgumentException;
use Joomla\CMS\Form\Form as JForm;
use Joomla\CMS\Language\Text as JText;
use RegularLabs\Library\ArrayHelper as RL_Array;
use RegularLabs\Library\Extension as RL_Extension;
use RegularLabs\Library\Form\Field\SubformField as RL_SubformField;
use RegularLabs\Library\Input as RL_Input;
use RegularLabs\Library\Parameters as RL_Parameters;
use RuntimeException;
class ConditionRulesField extends RL_SubformField
{
/**
* @var string
*/
protected $layout = 'regularlabs.form.field.subform.repeatable';
/**
* Loads the form instance for the subform by given name and control.
*
* @param string $name The name of the form.
* @param string $control The control name of the form.
*
* @return JForm The form instance.
*
* @throws InvalidArgumentException if no form provided.
* @throws RuntimeException if the form could not be loaded.
*/
public function loadSubFormByName($name, $control)
{
$tmpl = JForm::getInstance($name, $this->formsource, ['control' => $control]);
$disabled_types = $this->getDisabledTypes();
$enabled_types = $this->getEnabledTypes();
// If enabled_types is empty, there is no specific limitation
if (empty($disabled_types) && empty($enabled_types))
{
return $tmpl;
}
$remove = false;
$removals = [];
$previous_type = '';
$fields = $tmpl->getXml()->fieldset->field;
foreach ($fields as $field)
{
$name = (string) $field->attributes()->name;
if ($this->isDisabledStartShowonField($field, $disabled_types, $enabled_types))
{
$parts = explode('__', $name);
$type = $parts[1] . '__' . $parts[2];
$disabled_types[] = $type;
$previous_type = $type;
$remove = true;
}
if ($remove)
{
$removals[] = $name;
}
if ($previous_type && $name === '@showon__' . $previous_type . '__b')
{
$remove = false;
}
}
foreach ($removals as $removal)
{
$tmpl->removeField($removal);
}
$type_field = $tmpl->getField('type');
[
$removals, $convert_to_free
] = $this->getRemovals($type_field->element->group, $disabled_types, $enabled_types);
$this->removeDisabledOptions($removals);
$this->disableProOptionsForFree($convert_to_free);
$this->removeEmptyGroups($type_field->element->group);
return $tmpl;
}
private function disableProOptionsForFree(array $options): void
{
foreach ($options as $option)
{
if ( ! isset($option->attributes()->disabled))
{
$option->addAttribute('disabled', 'disabled');
}
$option[0] = JText::_($option[0]) . ' (' . strip_tags(JText::_('RL_ONLY_AVAILABLE_IN_PRO')) . ')';
}
}
private function getDisabledTypes(): array
{
$disabled_types = RL_Array::toArray(RL_Parameters::getComponent('conditions')->disabled_rule_types ?: []);
$extensions = ['hikashop', 'flexicontent', 'k2', 'zoo'];
foreach ($extensions as $extension)
{
if ( ! RL_Extension::isEnabled($extension))
{
$disabled_types[] = $extension;
}
}
return $disabled_types;
}
private function getEnabledTypes(): array
{
return RL_Array::toArray(RL_Input::getString('enabled_types'));
}
private function getRemovals(object $groups, array $disabled_types, array $enabled_types): array
{
$removals = [];
$convert_to_free = [];
foreach ($groups as $group)
{
foreach ($group->option as $option)
{
$type = (string) $option->attributes()->value;
if (in_array($type, $disabled_types))
{
$removals[] = $option;
continue;
}
if ( ! empty($enabled_types)
&& ! in_array($type, $enabled_types)
)
{
$convert_to_free[] = $option;
}
}
}
return [$removals, $convert_to_free];
}
private function isDisabledStartShowonField(
object $field,
array $disabled_types,
array $enabled_types
): bool
{
$name = (string) $field->attributes()->name;
$is_showon = str_starts_with($name, '@showon');
if ( ! $is_showon)
{
return false;
}
$parts = explode('__', $name);
if (count($parts) !== 4 || $parts[3] !== 'a')
{
return false;
}
$group = $parts[1];
$type = $group . '__' . $parts[2];
if (
in_array($group, $disabled_types)
|| in_array($type, $disabled_types)
)
{
return true;
}
if ( ! empty($enabled_types)
&& ! in_array($group, $enabled_types)
&& ! in_array($type, $enabled_types)
)
{
return true;
}
return false;
}
private function removeDisabledOptions(array $options): void
{
foreach ($options as $option)
{
$this->removeXmlElement($option);
}
}
private function removeEmptyGroups(object $groups): void
{
foreach ($groups as $group)
{
if (empty($group->option))
{
$this->removeXmlElement($group);
}
}
}
private function removeXmlElement(object $element): void
{
$dom = dom_import_simplexml($element);
$dom->parentNode->removeChild($dom);
}
}

View File

@ -0,0 +1,85 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Form\Field;
defined('_JEXEC') or die;
use Joomla\CMS\Factory as JFactory;
use Joomla\CMS\HTML\HTMLHelper as JHtml;
use Joomla\CMS\Language\Text as JText;
use RegularLabs\Library\ArrayHelper as RL_Array;
use RegularLabs\Library\DB as RL_DB;
use RegularLabs\Library\Form\Form as RL_Form;
use RegularLabs\Library\Form\FormField as RL_FormField;
use RegularLabs\Library\Language as RL_Language;
class ConditionSelectionField extends RL_FormField
{
public bool $is_select_list = true;
public bool $use_ajax = true;
public function getNameById(string $value, array $attributes): string
{
return RL_Array::implode($this->getNamesByIds([$value], $attributes));
}
public function getNamesByIds(array $values, array $attributes): array
{
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('DISTINCT a.id, a.alias, a.name')
->from('#__conditions AS a')
->where('a.published = 1')
->where(RL_DB::is('a.id', $values))
->order('a.name');
$db->setQuery($query);
$fields = $db->loadObjectList();
return RL_Form::getNamesWithExtras($fields);
}
protected function getOptions()
{
RL_Language::load('com_conditions');
$current_id = 0;
if (($this->parent_request->option ?? '') === 'com_conditions')
{
$current_id = ($this->parent_request->id ?? 0);
}
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('DISTINCT a.id, a.alias, a.name')
->from('#__conditions AS a')
->where('a.published = 1')
->where('a.id != ' . $current_id)
->order('a.name');
$db->setQuery($query);
$conditions = $db->loadObjectList();
$options = [];
$options[] = JHtml::_('select.option', '', '- ' . JText::_('CON_SELECT_A_CONDITION') . ' -');
foreach ($conditions as $condition)
{
$options[] = JHtml::_('select.option', $condition->id, $condition->name);
}
return $options;
}
}

View File

@ -0,0 +1,54 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Form\Field;
defined('_JEXEC') or die;
use RegularLabs\Library\DB as RL_DB;
use RegularLabs\Library\Form\Form;
use RegularLabs\Library\Form\FormField as RL_FormField;
class FlexicontentTagsField extends RL_FormField
{
public bool $is_select_list = true;
public bool $use_ajax = true;
public bool $use_tree_select = true;
public function getNamesByIds(array $values, array $attributes): array
{
$query = $this->db->getQuery(true)
->select('t.name as id, t.name, t.published')
->from('#__flexicontent_tags AS t')
->where(RL_DB::is('t.name', $values))
->group('t.name')
->order('t.name');
$this->db->setQuery($query);
$tags = $this->db->loadObjectList();
return Form::getNamesWithExtras($tags, ['unpublished']);
}
protected function getOptions()
{
$query = $this->db->getQuery(true)
->select('t.name as id, t.name, t.published')
->from('#__flexicontent_tags AS t')
->where('t.published > -1')
->where('t.name != ' . $this->db->quote(''))
->group('t.name')
->order('t.name');
$this->db->setQuery($query);
$tags = $this->db->loadObjectList();
return $this->getOptionsByList($tags, ['unpublished']);
}
}

View File

@ -0,0 +1,51 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Form\Field;
defined('_JEXEC') or die;
use RegularLabs\Library\DB as RL_DB;
use RegularLabs\Library\Form\Form;
use RegularLabs\Library\Form\FormField as RL_FormField;
class FlexicontentTypesField extends RL_FormField
{
public bool $is_select_list = true;
public bool $use_ajax = true;
public bool $use_tree_select = true;
public function getNamesByIds(array $values, array $attributes): array
{
$query = $this->db->getQuery(true)
->select('t.id, t.name, t.published')
->from('#__flexicontent_types AS t')
->where(RL_DB::is('t.id', $values))
->order('t.name, t.id');
$this->db->setQuery($query);
$types = $this->db->loadObjectList();
return Form::getNamesWithExtras($types, ['unpublished']);
}
protected function getOptions()
{
$query = $this->db->getQuery(true)
->select('t.id, t.name, t.published')
->from('#__flexicontent_types AS t')
->where('t.published > -1')
->order('t.name, t.id');
$this->db->setQuery($query);
$types = $this->db->loadObjectList();
return $this->getOptionsByList($types, ['unpublished']);
}
}

View File

@ -0,0 +1,90 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Form\Field;
defined('_JEXEC') or die;
use Joomla\CMS\Language\Text as JText;
use RegularLabs\Library\ArrayHelper as RL_Array;
use RegularLabs\Library\DB as RL_DB;
use RegularLabs\Library\Form\Form;
use RegularLabs\Library\Form\FormField as RL_FormField;
use RegularLabs\Library\Language as RL_Language;
class HikashopCategoriesField extends RL_FormField
{
public bool $is_select_list = true;
public bool $use_ajax = true;
public bool $use_tree_select = true;
public function getNamesByIds(array $values, array $attributes): array
{
RL_Language::load('com_conditions');
$query = $this->db->getQuery(true)
->select('c.category_id as id, c.category_parent_id AS parent_id, c.category_name AS name, c.category_published as published')
->from('#__hikashop_category AS c')
->where(RL_DB::is('c.category_id', $values))
->order('c.category_left');
$this->db->setQuery($query);
$categories = $this->db->loadObjectList();
foreach ($categories as $category)
{
if ($category->name == 'product category')
{
$category->name = JText::_('CON_PRODUCTS');
break;
}
}
return Form::getNamesWithExtras($categories, ['unpublished']);
}
protected function getOptions()
{
RL_Language::load('com_conditions');
$query = $this->db->getQuery(true)
->select('COUNT(*)')
->from('#__hikashop_category AS c')
->where('c.category_type = ' . $this->db->quote('product'))
->where('c.category_published > -1')
->where('c.category_parent_id > 0');
$this->db->setQuery($query);
$total = $this->db->loadResult();
if ($total > $this->max_list_count)
{
return -1;
}
$this->value = RL_Array::toArray($this->value);
$query->clear('select')
->select('c.category_id as id, c.category_depth AS level, c.category_name AS name, c.category_published as published')
->order('c.category_left');
$this->db->setQuery($query);
$categories = $this->db->loadObjectList();
foreach ($categories as $category)
{
if ($category->name == 'product category')
{
$category->name = JText::_('CON_PRODUCTS');
break;
}
}
return $this->getOptionsByList($categories, ['unpublished'], -1);
}
}

View File

@ -0,0 +1,70 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Form\Field;
defined('_JEXEC') or die;
use RegularLabs\Library\ArrayHelper as RL_Array;
use RegularLabs\Library\DB as RL_DB;
use RegularLabs\Library\Form\Form;
use RegularLabs\Library\Form\FormField as RL_FormField;
class HikashopItemsField extends RL_FormField
{
public bool $is_select_list = true;
public bool $use_ajax = true;
public bool $use_tree_select = true;
public function getNamesByIds(array $values, array $attributes): array
{
$query = $this->db->getQuery(true)
->select('p.product_id as id, p.product_name AS name, p.product_published AS published, c.category_name AS category')
->from('#__hikashop_product AS p')
->join('LEFT', '#__hikashop_product_category AS x ON x.product_id = p.product_id')
->join('INNER', '#__hikashop_category AS c ON c.category_id = x.category_id')
->where(RL_DB::is('p.product_id', $values))
->order('p.product_name');
$this->db->setQuery($query);
$items = $this->db->loadObjectList();
return Form::getNamesWithExtras($items, ['category', 'unpublished']);
}
protected function getOptions()
{
$query = $this->db->getQuery(true)
->select('COUNT(*)')
->from('#__hikashop_product AS p')
->where('p.product_published = 1')
->where('p.product_type = ' . $this->db->quote('main'));
$this->db->setQuery($query);
$total = $this->db->loadResult();
if ($total > $this->max_list_count)
{
return -1;
}
$this->value = RL_Array::toArray($this->value);
$query->clear('select')
->select('p.product_id as id, p.product_name AS name, p.product_published AS published, c.category_name AS category')
->join('LEFT', '#__hikashop_product_category AS x ON x.product_id = p.product_id')
->join('INNER', '#__hikashop_category AS c ON c.category_id = x.category_id')
->group('p.product_id')
->order('p.product_name');
$this->db->setQuery($query);
$items = $this->db->loadObjectList();
return $this->getOptionsByList($items, ['category', 'id', 'unpublished'], -2);
}
}

View File

@ -0,0 +1,114 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Form\Field;
defined('_JEXEC') or die;
use RegularLabs\Library\ArrayHelper as RL_Array;
use RegularLabs\Library\DB as RL_DB;
use RegularLabs\Library\Form\Form;
use RegularLabs\Library\Form\FormField as RL_FormField;
use RegularLabs\Library\Language as RL_Language;
class ZooCategoriesField extends RL_FormField
{
public bool $is_select_list = true;
public bool $use_ajax = true;
public bool $use_tree_select = true;
public function getNamesByIds(array $values, array $attributes): array
{
RL_Language::load('com_conditions');
$app_values = [];
$category_values = [];
foreach ($values as $value)
{
if (str_starts_with($value, 'app'))
{
$app_values[] = (int) str_replace('app', '', $value);
continue;
}
$category_values[] = (int) $value;
}
$query = $this->db->getQuery(true)
->select('CONCAT("[",a.name,"]") as name, 1 as published')
->from('#__zoo_application AS a')
->where(RL_DB::is('a.id', $app_values))
->order('a.id');
$this->db->setQuery($query);
$apps = $this->db->loadObjectList();
$query = $this->db->getQuery(true)
->select('c.name, c.published')
->from('#__zoo_category AS c')
->where(RL_DB::is('c.id', $category_values))
->order('c.ordering');
$this->db->setQuery($query);
$categories = $this->db->loadObjectList();
$items = [...$apps, ...$categories];
return Form::getNamesWithExtras($items, ['unpublished']);
}
protected function getOptions()
{
RL_Language::load('com_conditions');
$query = $this->db->getQuery(true)
->select('COUNT(*)')
->from('#__zoo_category AS c')
->where('c.published > -1');
$this->db->setQuery($query);
$total = $this->db->loadResult();
if ($total > $this->max_list_count)
{
return -1;
}
$this->value = RL_Array::toArray($this->value);
$query->clear()
->select('CONCAT("app",a.id) as id, CONCAT("[",a.name,"]") as name, 1 as published, 0 as parent_id')
->from('#__zoo_application AS a')
->order('a.name, a.id');
$this->db->setQuery($query);
$apps = $this->db->loadObjectList();
$query->clear()
->select('c.id, c.name, c.published, c.parent as parent_id, c.application_id as app_id')
->from('#__zoo_category AS c')
->where('c.published > -1')
->order('c.ordering, c.name');
$this->db->setQuery($query);
$categories = $this->db->loadObjectList();
foreach ($categories as $category)
{
if ($category->parent_id == 0)
{
$category->parent_id = 'app' . $category->app_id;
}
}
$items = [...$apps, ...$categories];
$items = RL_Array::setLevelsByParentIds($items);
return $this->getOptionsByList($items, ['unpublished']);
}
}

View File

@ -0,0 +1,67 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Form\Field;
defined('_JEXEC') or die;
use RegularLabs\Library\ArrayHelper as RL_Array;
use RegularLabs\Library\DB as RL_DB;
use RegularLabs\Library\Form\Form;
use RegularLabs\Library\Form\FormField as RL_FormField;
class ZooItemsField extends RL_FormField
{
public bool $is_select_list = true;
public bool $use_ajax = true;
public bool $use_tree_select = true;
public function getNamesByIds(array $values, array $attributes): array
{
$query = $this->db->getQuery(true)
->select('i.id, i.name, a.name as category, i.state as published')
->from('#__zoo_item AS i')
->join('LEFT', '#__zoo_application AS a ON a.id = i.application_id')
->where(RL_DB::is('i.id', $values))
->order('i.name');
$this->db->setQuery($query);
$items = $this->db->loadObjectList();
return Form::getNamesWithExtras($items, ['category', 'unpublished']);
}
protected function getOptions()
{
$query = $this->db->getQuery(true)
->select('COUNT(*)')
->from('#__zoo_item AS i')
->where('i.state > -1');
$this->db->setQuery($query);
$total = $this->db->loadResult();
if ($total > $this->max_list_count)
{
return -1;
}
$this->value = RL_Array::toArray($this->value);
$query->clear('select')
->select('i.id, i.name, a.name as category, i.state as published')
->join('LEFT', '#__zoo_application AS a ON a.id = i.application_id')
->group('i.id')
->order('i.name, i.priority, i.id');
$this->db->setQuery($query);
$list = $this->db->loadObjectList();
return $this->getOptionsByList($list, ['category', 'id']);
}
}

View File

@ -0,0 +1,43 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Helper;
use RegularLabs\Library\Cache as RL_Cache;
use RegularLabs\Library\Document as RL_Document;
class Cache extends RL_Cache
{
public function __construct(
mixed $id = null,
string $group = 'rl_conditions',
int $class_offset = 2
)
{
parent::__construct($id, $group, 2);
}
public function resetAll(): void
{
parent::useFiles();
parent::resetAll();
}
public function useFiles(int $time_to_life_in_minutes = 0, bool $force_caching = true): self
{
if (RL_Document::isAdmin())
{
return $this;
}
return parent::useFiles($time_to_life_in_minutes, $force_caching);
}
}

View File

@ -0,0 +1,694 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 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\Library\ArrayHelper as RL_Array;
use RegularLabs\Library\DB as RL_DB;
use RegularLabs\Library\ObjectHelper as RL_Object;
use RegularLabs\Library\RegEx as RL_RegEx;
use RegularLabs\Library\StringHelper as RL_String;
class Convert
{
static $fields;
public static function addRule(
object &$group,
string $type,
?string $selection,
array $extra_params = [],
bool $override = true
): void
{
if ($override)
{
self::removeRule($group, $type);
}
$selection = $selection ? trim($selection) : '';
$selection = html_entity_decode($selection);
$selection = RL_RegEx::replace('<br ?/?>', "\n", $selection);
$extra_params = (object) $extra_params;
$exclude = self::prepareSelection($selection, $extra_params);
$params = [
'selection' => $selection,
...(array) $extra_params,
];
$group->rules[] = (object) [
'type' => $type,
'exclude' => $exclude ? 1 : 0,
'params' => (object) $params,
];
self::createHashGroup($group);
}
public static function fromObject(
object $object,
string $name = '',
string $extension = '',
int $item_id = 0,
string $table = '',
string $name_column = 'name'
): object
{
$name = $name ?: Helper::getForItemText($extension, $item_id, $table, $name_column);
$object = RL_Object::changeKeyCase($object, 'underscore');
$object = self::replaceKeyAliases($object);
if (isset($object->matching_method))
{
$object->match_all = strtolower($object->matching_method ?? 'and') === 'and' ? 1 : 0;
}
$condition = (object) [
'name' => $name,
'match_all' => $object->match_all ?? 1,
'published' => 1,
'groups' => self::createGroups($object),
];
$condition->hash = md5(json_encode([$condition->match_all, $condition->groups]));
return $condition;
}
public static function hasRule(object &$group, string $type): bool
{
foreach ($group->rules as $rule)
{
if ($rule->type === $type)
{
return true;
}
}
return false;
}
public static function removeRule(object &$group, string $type): void
{
foreach ($group->rules as $i => $rule)
{
if ($rule->type !== $type)
{
continue;
}
unset($group->rules[$i]);
return;
}
}
private static function addRuleBasicSelection(
string $new_name,
string $old_name,
object $params,
object $group,
int $id = 0
): void
{
self::addRule($group,
$new_name,
$params->{$old_name},
[],
$id
);
}
private static function addRuleContentArticleDate(
string $prefix,
object $params,
object $group,
string $type = ''
): void
{
$type = $type ?: $prefix;
if ( ! isset($params->{$prefix}))
{
return;
}
$exclude = self::prepareSelection($params->{$prefix}, $params);
[$comparison, $date, $from, $to] = self::convertDateStringToDates($params->{$prefix});
self::addRule($group,
'content__article__date',
$exclude . ($params->{$prefix . '_type'} ?? $type),
[
'comparison' => $comparison,
'date' => $date ?: '',
'from' => $from ?: '',
'to' => $to ?: '',
'recurring' => $params->{$prefix . '_recurring'} ?? 0,
],
false
);
}
private static function addRuleContentArticleFeatured(object $params, object $group): void
{
self::addRule($group,
'content__article__featured',
$params->featured ? '' : '!'
);
}
private static function addRuleContentArticleFields(
string $key,
object $params,
object $group
): void
{
$key = RL_String::toUnderscoreCase($key);
$fields = self::getFieldNames();
if ( ! isset($fields[$key]))
{
return;
}
$value = RL_DB::removeOperator($params->{$key});
$operator = RL_DB::getOperator($params->{$key});
$comparison = self::convertOperatorToComparison($operator);
self::addRule($group,
'content__article__field',
'',
[
'field' => $fields[$key],
'comparison' => $comparison,
'value' => $value,
]
);
}
private static function addRuleContentCategory(object $params, object $group): void
{
self::addRule($group,
'content__category',
$params->category,
[
'include_children' => $params->category_include_children ?? 0,
'page_types' => $params->category_page_types ?? [],
]
);
}
private static function addRuleDateDate(object $params, object $group): void
{
$exclude = self::prepareSelection($params->date, $params);
[$comparison, $date, $from, $to] = self::convertDateStringToDates($params->date);
self::addRule($group,
'date__date',
$exclude,
[
'comparison' => $comparison,
'date' => $date ?: '',
'from' => $from ?: '',
'to' => $to ?: '',
'recurring' => $params->date_recurring ?? 0,
]
);
}
private static function addRuleDateSeason(object $params, object $group): void
{
self::addRule($group,
'date__season',
$params->season,
[
'hemisphere' => $params->season_hemisphere ?? 'northern',
]
);
}
private static function addRuleDateTime(object $params, object $group): void
{
$exclude = self::prepareSelection($params->time, $params);
[$comparison, $time, $from, $to] = self::convertDateStringToDates($params->time);
self::addRule($group,
'date__time',
$exclude,
[
'comparison' => $comparison,
'from' => $from ?: ($comparison === 'after' ? $time : ''),
'to' => $to ?: ($comparison === 'before' ? $time : ''),
]
);
}
private static function addRuleMenuHomePage(object $params, object $group): void
{
self::addRule($group,
'menu__home_page',
$params->home_page ? '' : '!'
);
}
private static function addRuleMenuMenuItem(object $params, object $group): void
{
self::addRule($group,
'menu__menu_item',
$params->menu_item,
[
'include_children' => $params->menu_item_inc_children ?? 0,
]
);
}
private static function addRuleOtherTag(object $params, object $group): void
{
if (empty($params->tag))
{
return;
}
self::addRule($group,
'other__tag',
$params->tag,
[
'match_all' => $params->tag_match_all ?? 0,
'include_children' => $params->tag_inc_children ?? 0,
]
);
}
private static function addRuleOtherUrl(object $params, object $group): void
{
if (empty($params->url))
{
return;
}
self::addRule($group,
'other__url',
$params->url,
[
'case_sensitive' => $params->url_casesensitive ?? 0,
'regex' => $params->url_regex ?? 0,
]
);
}
private static function addRuleVisitorAccessLevel(object $params, object $group): void
{
self::addRule($group,
'visitor__access_level',
$params->access_level,
[
'match_all' => $params->access_level_match_all ?? 0,
]
);
}
private static function addRuleVisitorUserGroup(object $params, object $group): void
{
self::addRule($group,
'visitor__user_group',
$params->user_group,
[
'match_all' => $params->user_group_match_all ?? 0,
'include_children' => $params->user_group_inc_children ?? 0,
]
);
}
/**
* Convert date="... to ..." to $from/$to
* Convert date=">..." to $from
* Convert date="<..." to $to
*/
private static function convertDateStringToDates(string $string): array
{
$string = str_replace(['&gt;', '&lt;'], ['>', '<'], $string);
if (str_starts_with($string, '>'))
{
// only has a from date
return [
'after',
substr($string, 1),
null,
null,
];
}
if (str_starts_with($string, '<'))
{
// only has a to date
return [
'before',
substr($string, 1),
null,
null,
];
}
[$from, $to] = explode(' to ', $string . ' to ');
// a from and to date
return [
'between',
null,
$from,
$to,
];
}
private static function convertOperatorToComparison(string $operator): string
{
return match ($operator)
{
'!', '!=' => 'not_equals',
'>' => 'greater_than',
'<' => 'less_than',
'>=' => 'greater_than_or_equal',
'<=' => 'less_than_or_equal',
'*' => 'contains',
default => 'equals',
};
}
private static function createGroups(object $object): array
{
$group = (object) [
'match_all' => $object->match_all ?? 1,
'rules' => [],
];
self::setRulesOnGroup($object, $group);
if (empty($group->rules))
{
return [];
}
self::createHashGroup($group);
return [$group];
}
/**
* @param object $group
*/
private static function createHashGroup(object &$group): void
{
unset($group->hash);
$group->hash = md5(json_encode([$group->match_all, $group->rules]));
}
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] = $db->loadResult();
return static::$field_ids[$name];
}
private static function getFieldNames(): array
{
if ( ! is_null(static::$fields))
{
return static::$fields;
}
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select(['a.id', 'a.name'])
->from('#__fields AS a');
$db->setQuery($query);
$fields = $db->loadAssocList('name', 'id');
static::$fields = RL_Array::changeKeyCase($fields, 'underscore');
return static::$fields;
}
private static function handleMatchAllList(string &$list): bool
{
if ( ! str_contains($list, ' + '))
{
return false;
}
$list = RL_Array::implode(RL_Array::toArray($list, ' + '), ',');
return true;
}
private static function prepareSelection(string &$selection, object &$params): bool
{
if (in_array($selection, ['true', 'false']))
{
$exclude = $selection === 'false';
$selection = '';
return $exclude;
}
$exclude = false;
if (strlen($selection) > 0 && $selection[0] === '!')
{
$exclude = true;
$selection = RL_RegEx::replace('^\!NOT\!', '!', $selection, 's');
$selection = substr($selection, 1);
}
if ( ! isset($params->match_all))
{
return $exclude;
}
$match_all = self::handleMatchAllList($selection);
if ( ! $match_all)
{
return $exclude;
}
$params->match_all = 1;
return $exclude;
}
private static function replaceKeyAliases(object $object): object
{
$aliases = [
'matching_method' => ['match_method', 'method'],
'match_all' => ['matchall'],
'menu_item' => ['menu_items', 'menuitem', 'menuitems'],
'home_page' => ['homepage'],
//'date' => ['dates'],
'season' => ['seasons'],
'month' => ['months'],
'day' => ['days'],
'time' => ['times'],
'page_type' => [
'page_types', 'pagetype', 'pagetypes', 'contentpagetype', 'contentpagetypes'
],
'category' => ['categories', 'cat', 'cats'],
'article' => ['articles'],
//'featured' => ['featured'],
'article_status' => ['status', 'state', 'states', 'publish_state', 'publish_states'],
'article_date' => ['articles_date', 'articledate'],
'article_author' => ['article_authors', 'author', 'authors'],
'content_keyword' => ['content_keywords', 'contentkeyword', 'contentkeywords'],
'meta_keyword' => ['meta_keywords', 'metakeyword', 'metakeywords'],
//'field' => ['field'],
'user' => ['users'],
'access_level' => ['access_levels', 'accesslevel', 'accesslevels'],
'user_group' => [
'user_groups', 'usergroup', 'usergroups', 'user_group_level', 'user_group_levels',
'usergrouplevel', 'usergrouplevels'
],
'language' => ['languages'],
'device' => ['devices'],
//'os' => ['os'],
'browser' => ['browsers'],
'browser_mobile' => [
'browser_mobiles', 'browsermobile', 'browsermobiles', 'mobile_browser',
'mobile_browsers', 'mobilebrowser', 'mobilebrowsers', 'mobile',
'mobiles',
],
'ip' => ['ips', 'ip_address', 'ip_addresses', 'ipaddress', 'ipaddresses'],
'continent' => ['continents'],
'country' => ['countries'],
'region' => ['regions'],
'postal_code' => ['postal_codes', 'postalcode', 'postalcodes'],
'tag' => ['tags'],
'component' => ['components'],
'template' => ['templates'],
'url' => ['urls'],
//'php' => ['php'],
//'condition' => ['condition'],
];
return RL_Object::replaceKeys($object, $aliases, true);
}
private static function setRuleOnGroupByKey(string $key, object $params, object &$group): void
{
$basic_selection_types = [
'month' => 'date__month',
'day' => 'date__day',
'page_type' => 'content__page_type',
'article' => 'content__article__id',
'article_status' => 'content__article__status',
'article_author' => 'content__article__author',
'content_keyword' => 'content__article__content_keyword',
'meta_keyword' => 'content__article__meta_keyword',
'user' => 'visitor__user',
'language' => 'visitor__language',
'ip' => 'visitor__ip',
'device' => 'agent__device',
'os' => 'agent__os',
'browser' => 'agent__browser',
'browser_mobile' => 'agent__browser_mobile',
'continent' => 'geo__continent',
'country' => 'geo__country',
'region' => 'geo__region',
'postal_code' => 'geo__postal_code',
'component' => 'other__component',
'template' => 'other__template',
'php' => 'other__php',
'condition' => 'other__condition',
];
if (isset($basic_selection_types[$key]))
{
self::addRule($group,
$basic_selection_types[$key],
$params->{$key},
[],
false
);
return;
}
switch ($key)
{
case 'menu_item':
self::addRuleMenuMenuItem($params, $group);
return;
case 'home_page':
self::addRuleMenuHomepage($params, $group);
return;
case 'date':
self::addRuleDateDate($params, $group);
return;
case 'season':
self::addRuleDateSeason($params, $group);
return;
case 'time':
self::addRuleDateTime($params, $group);
return;
case 'category':
self::addRuleContentCategory($params, $group);
return;
case 'featured':
self::addRuleContentArticleFeatured($params, $group);
return;
case 'article_date':
self::addRuleContentArticleDate('article_date', $params, $group, 'created');
return;
case 'created':
case 'modified':
case 'publish_up':
case 'publish_down':
self::addRuleContentArticleDate($key, $params, $group);
return;
case 'access_level':
self::addRuleVisitorAccessLevel($params, $group);
return;
case 'user_group':
self::addRuleVisitorUserGroup($params, $group);
return;
case 'tag':
self::addRuleOtherTag($params, $group);
return;
case 'url':
self::addRuleOtherUrl($params, $group);
return;
default:
self::addRuleContentArticleFields($key, $params, $group);
return;
}
}
private static function setRulesOnGroup(object $params, object &$group): void
{
if ( ! isset($group->rules))
{
$group->rules = [];
}
foreach ($params as $key => $value)
{
self::setRuleOnGroupByKey($key, $params, $group);
}
}
}

View File

@ -0,0 +1,875 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 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();
}
}

View File

@ -0,0 +1,159 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Helper;
use DateTimeZone;
use Joomla\CMS\Date\Date as JDate;
use Joomla\CMS\Factory as JFactory;
use RegularLabs\Library\Date as RL_Date;
class Date
{
static $dates = [];
static $timezone;
public static function get(string $date = '', bool $ignore_time_zone = false): JDate
{
$date = RL_Date::fix($date);
$id = 'date_' . $date . '_' . $ignore_time_zone;
if (isset(self::$dates[$id]))
{
return self::$dates[$id];
}
self::$dates[$id] = JFactory::getDate($date);
if ( ! $ignore_time_zone)
{
self::$dates[$id]->setTimeZone(self::getTimeZone());
}
return self::$dates[$id];
}
public static function getDayNumber(string $string): int
{
if ( ! is_string($string))
{
return false;
}
if (is_numeric($string))
{
return $string;
}
$string = strip_tags($string);
return (int) date('N', strtotime($string));
}
public static function getMonthNumber(string $string): int
{
if ( ! is_string($string))
{
return false;
}
if (is_numeric($string))
{
return $string;
}
return (int) date('m', strtotime($string));
}
public static function getNow(): string
{
return self::getString();
}
public static function getString(
string $date = '',
string $format = 'Y-m-d H:i:s',
bool $ignore_time_zone = false
): string
{
$date = self::get($date, $ignore_time_zone);
return $date->format($format, true);
}
public static function getTimeStamp(string $date = '', bool $ignore_time_zone = false): int
{
return strtotime(self::getString($date, 'Y-m-d H:i:s', $ignore_time_zone));
}
public static function pass(object $params, ?string $date = null): bool
{
$datetime = strtotime($date ?: self::getNow());
$comparison = $params->comparison ?? 'between';
if ($comparison == 'before')
{
return $datetime < self::getTimeStamp($params->date ?? '', true);
}
if ($comparison == 'after')
{
return $datetime > self::getTimeStamp($params->date ?? '', true);
}
$from = $params->from ?? false;
$to = $params->to ?? false;
// no date range set
if ( ! $from && ! $to)
{
return true;
}
if (empty($params->recurring))
{
$from = $from ? self::getTimeStamp($from, true) : false;
$to = $to ? self::getTimeStamp($to, true) : false;
return ( ! $from || $datetime >= $from)
&& ( ! $to || $datetime <= $to);
}
$from = strtotime(date('Y') . self::getString($from, '-m-d H:i:s', true));
$to = strtotime(date('Y') . self::getString($to, '-m-d H:i:s', true));
// pass: from is before to
if ($from <= $to)
{
// and now is between from and to
return ($from < $datetime && $to > $datetime);
}
// pass: from is later in year than to and:
// - to is after up
// - or now is before from
return ($to > $datetime || $from < $datetime);
}
private static function getTimeZone(): DateTimeZone
{
if ( ! is_null(self::$timezone))
{
return self::$timezone;
}
self::$timezone = new DateTimeZone(JFactory::getApplication()->getCfg('offset'));
return self::$timezone;
}
}

View File

@ -0,0 +1,322 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 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 Joomla\CMS\Language\Text as JText;
use RegularLabs\Library\ArrayHelper as RL_Array;
use RegularLabs\Library\DB as RL_DB;
use RegularLabs\Library\Language as RL_Language;
use RegularLabs\Library\Parameters as RL_Parameters;
use RegularLabs\Library\StringHelper as RL_String;
class Helper
{
public static function conditionIsActive(object $rule): bool
{
if (empty($rule->type))
{
return false;
}
$disabled_types = RL_Array::toArray(RL_Parameters::getComponent('conditions')->disabled_rule_types);
return ! in_array($rule->type, $disabled_types);
}
public static function getConditionsClass(
object $rule,
object|false|null $article,
object|false|null $module,
object|false|null $request = null,
?int $category_id = null
)
{
if (empty($rule->type))
{
return false;
}
if ( ! self::conditionIsActive($rule))
{
return false;
}
$field = self::getField($rule->type);
if ( ! $field)
{
return false;
}
$classname = str_replace('_', '. ', $field->class);
$classname = RL_String::toTitleCase($classname);
$classname = str_replace(['. . ', '. '], ['\\', ''], $classname);
$classname = 'RegularLabs\\Component\\Conditions\\Administrator\\Condition\\'
. $classname;
if ( ! class_exists($classname))
{
return false;
}
return new $classname($rule, $article, $module, $request, $category_id);
}
public static function getExtensionItemString(string $extension): string
{
RL_Language::load($extension);
$no_com_prefix = strtoupper(preg_replace('#^com_#', '', $extension));
$item_name = $no_com_prefix . '_ITEM_NAME_FOR_CONDITIONS';
if (JText::_($item_name) !== $item_name)
{
return JText::_($item_name);
}
$extension = self::getExtensionName($extension);
return JText::sprintf('CON_EXTENSION_ITEM', $extension);
}
public static function getExtensionName(string $extension): string
{
RL_Language::load($extension);
$no_com_prefix = strtoupper(preg_replace('#^com_#', '', $extension));
$extension_name = JText::_($no_com_prefix) !== $no_com_prefix
? JText::_($no_com_prefix)
: JText::_($extension);
return str_replace('Regular Labs - ', '', $extension_name);
}
public static function getField(string $key): ?object
{
$fields = Helper::getXmlFields();
return $fields[$key] ?? null;
}
public static function getFieldClass(string $key): object|false
{
$field = self::getField($key);
if ( ! $field)
{
return false;
}
$classname = 'RegularLabs\\Component\\Conditions\\Administrator\\Form\\Field\\' . $field->type . 'Field';
if ( ! class_exists($classname))
{
$classname = 'RegularLabs\\Library\\Form\\Field\\' . $field->type . 'Field';
}
if ( ! class_exists($classname))
{
return false;
}
$class = new $classname;
if ( ! method_exists($class, 'getNamesByIds'))
{
return false;
}
return $class;
}
public static function getForItemText(
string $extension,
int $item_id,
string $table,
string $name_column = 'name'
): string
{
RL_Language::load('com_conditions');
$extension_item = self::getExtensionItemString($extension);
$item_name = self::getItemNameFromDB($item_id, $table, $name_column);
return JText::sprintf('CON_FOR_ITEM', $extension_item, $item_name);
}
public static function getIdValuesFromDB(string $table, string $name_column = 'name'): array
{
if ( ! $table || ! $name_column)
{
return [];
}
$cache = new Cache;
if ($cache->exists())
{
return $cache->get();
}
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select(RL_DB::quoteName('id'))
->select(RL_DB::quoteName($name_column, 'value'))
->from(RL_DB::quoteName('#__' . $table));
$db->setQuery($query);
return $cache->set($db->loadAssocList('id', 'value'));
}
public static function getItemNameFromDB(
int $item_id,
string $table,
string $name_column = 'name'
): string
{
$items = self::getIdValuesFromDB($table, $name_column);
return $items[$item_id] ?? '';
}
public static function getItemPublishStateFromDB(int $item_id, string $table): int
{
$columns = RL_DB::getTableColumns('#__' . $table);
$published_column = isset($columns['published'])
? 'published'
: ($columns['state'] ? 'state' : '');
if ( ! $published_column)
{
return 1;
}
$items = self::getIdValuesFromDB($table, $published_column);
return $items[$item_id] ?? 0;
}
public static function getPublishStateString(int $state): string
{
$state = match ($state)
{
1 => 'PUBLISHED',
0 => 'UNPUBLISHED',
2 => 'ARCHIVED',
-2 => 'TRASHED',
default => '',
};
return JText::_($state);
}
public static function getXmlFields(bool $use_cache = true): array
{
$cache = new Cache('Conditions.getXmlFields');
if ($use_cache && $cache->exists())
{
return $cache->get();
}
RL_Parameters::getObjectFromRegistry('', 'administrator/components/com_conditions/forms/item_rule.xml');
$file = file_get_contents(JPATH_ADMINISTRATOR . '/components/com_conditions/forms/item_rule.xml');
$xml_parser = xml_parser_create();
xml_parse_into_struct($xml_parser, $file, $xml_fields);
xml_parser_free($xml_parser);
$fields = [];
$field_name = '';
foreach ($xml_fields as $field)
{
if ( ! in_array($field['tag'], ['FIELD', 'OPTION'])
|| ! isset($field['attributes'])
|| isset($field['attributes']['DISABLED'])
)
{
continue;
}
if ($field['tag'] === 'OPTION')
{
$option_name = $field_name . '.' . RL_String::toUnderscoreCase($field['attributes']['VALUE'], true, true);
$fields[$option_name] = (object) [
'type' => '',
'name' => $field['value'],
'class' => $field['attributes']['CONDITION'] ?? '',
'attributes' => (array) RL_Array::changeKeyCase($field['attributes'], 'lowercase'),
];
continue;
}
if (isset($field['attributes']['TYPE']) && $field['attributes']['TYPE'] === 'LoadLanguage')
{
RL_Language::load($field['attributes']['EXTENSION'], JPATH_ADMINISTRATOR);
continue;
}
if ( ! isset($field['attributes']['NAME'])
|| ! isset($field['attributes']['TYPE'])
|| $field['attributes']['NAME'] == ''
|| $field['attributes']['NAME'][0] == '@'
|| $field['attributes']['TYPE'] == 'spacer'
)
{
continue;
}
$field_name = $field['attributes']['NAME'];
$fields[$field_name] = (object) [
'type' => $field['attributes']['TYPE'],
'name' => $field['attributes']['LABEL'] ?? $field['attributes']['NAME'],
'class' => $field['attributes']['CONDITION'] ?? $field['attributes']['NAME'],
'attributes' => (array) RL_Array::changeKeyCase($field['attributes'], 'lowercase'),
];
}
return $cache->set($fields);
}
public static function thereAreConditions(): bool
{
$cache = new Cache;
if ($cache->exists())
{
return $cache->get();
}
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('count(*)')
->from('#__conditions')
->where(RL_DB::is('published', 1));
$db->setQuery($query);
return $cache->set($db->loadResult() > 0);
}
}

View File

@ -0,0 +1,490 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Helper;
defined('_JEXEC') or die;
use Joomla\CMS\Language\Text as JText;
use RegularLabs\Library\ArrayHelper as RL_Array;
use RegularLabs\Library\Date as RL_Date;
use RegularLabs\Library\Language as RL_Language;
use RegularLabs\Library\StringHelper as RL_String;
class Summary
{
public static function render(
?object $condition,
string $extension = '',
string $message = ''
): string
{
if (empty($condition))
{
return '';
}
if ($extension && ! empty($condition->name))
{
RL_Language::load($extension);
}
$no_rules_set = '<div class="alert alert-warning">'
. '<span class="icon-info-circle text-info" aria-hidden="true"></span> '
. JText::_('CON_MESSAGE_NO_RULES_SELECTED')
. ($message ? '<br><br>' . JText::_($message) : '')
. '</div>';
$html = [];
if ($extension && ! empty($condition->name))
{
$html[] = '<h4>'
. '<small class="text-uppercase text-muted">' . JText::_('CON_CONDITION_SET') . ':</small><br>'
. RL_String::escape($condition->name)
. '</h4>';
}
$output = self::getGroupsOutput($condition);
if ($output === false)
{
$output = $no_rules_set;
}
$html[] = $output;
return implode('', $html);
}
private static function getAttributeOutput(
string $key,
string|array $value,
string $default = 'CON_NONE',
bool $output_as_list = false
): string
{
if (is_array($value) && $output_as_list)
{
$value = '<ul><li>' . RL_Array::implode($value, '</li><li>') . '</li></ul>';
}
if (is_array($value))
{
$value = RL_Array::implode($value, ', ');
}
if (empty($value) && $value !== '0')
{
$value = JText::_('<em>%s</em>,' . $default);
}
return '<strong>' . $key . '</strong>: ' . $value;
}
private static function getAttributesOutputByRule(object $rule): string
{
$attributes = [];
foreach ($rule->params as $key => $value)
{
$output = self::getRuleLineOutput($rule, $key, $value);
if ( ! $output)
{
continue;
}
$attributes[] = $output;
}
if (empty($attributes))
{
return '';
}
return '<div class="small">' . implode('<br>', $attributes) . '</div>';
}
private static function getDateTimeValue(
string $value,
string $type,
bool $recurring = false
): string
{
if ( ! $value)
{
return '<em>' . JText::_('CON_NOT_SPECIFIED') . '</em>';
}
if ($type == 'date__time')
{
return RL_Date::fixTime($value, false);
}
$format = $recurring
? 'd F H:i'
: 'd F Y H:i';
return Date::getString($value, $format, true);
}
private static function getGlue(bool $match_all = true): string
{
$text = JText::_($match_all ? 'CON_AND' : 'CON_OR');
$class = $match_all ? 'bg-info' : 'bg-warning text-black';
return '<div class="text-center"><span class="badge px-4 ' . $class . '">' . $text . '</span></div>';
}
private static function getGroupsOutput(object $condition): string|false
{
$condition->groups = RL_Array::clean($condition->groups ?? []);
if (empty($condition->groups))
{
return false;
}
$groups = [];
foreach ($condition->groups as $group)
{
$groups[] = self::getOutputByGroup($group);
}
$groups = RL_Array::clean($groups);
if (empty($groups))
{
return false;
}
if (count($groups) < 2)
{
$html[] = implode('', $groups);
return implode('', $html);
}
foreach ($groups as &$group)
{
$group = '<div class="card border-dark rl-card"><div class="card-body">' . $group . '</div></div>';
}
$html[] = implode(self::getGlue($condition->match_all), $groups);
return implode('', $html);
}
private static function getNameString(string $name, string $type = ''): string
{
$id = str_replace('-', '_', $name);
$field = Helper::getField($type . '.' . $id) ?? Helper::getField($id) ?? null;
if ( ! $field || ! isset($field->name))
{
return JText::_($name);
}
$name = trim($field->name);
if (empty($field->attributes['group_name']))
{
return JText::_($name);
}
return JText::_($field->attributes['group_name']) . ': ' . JText::_($name);
}
private static function getOutputByGroup(object $group): string
{
$rules = [];
foreach ($group->rules as $rule)
{
$rules[] = self::getOutputByRule($rule);
}
return implode(self::getGlue($group->match_all), $rules);
}
private static function getOutputByRule(object $rule): string
{
$html = [];
$state = self::getNameString('exclude.' . $rule->exclude);
$state_class = $rule->exclude ? 'danger' : 'success';
$type_name = self::getNameString('type.' . $rule->type);
$values_output = self::getValuesOutputByRule($rule);
$attributes_output = self::getAttributesOutputByRule($rule);
$class = 'alert alert-' . $state_class;
if (isset($rule->disabled) && $rule->disabled)
{
$class .= ' disabled ghosted';
}
$html[] = '<div class="' . $class . '">';
if (isset($rule->disabled) && $rule->disabled)
{
$html[] = '<div class="alert alert-danger">'
. JText::_('RL_ONLY_AVAILABLE_IN_PRO')
. '</div>';
}
$html[] = '<h3>'
. '<span class="badge bg-' . $state_class . ' align-text-bottom">' . $state . '</span> '
. $type_name
. '</h3>';
$html[] = $values_output;
$html[] = $attributes_output;
$html[] = '</div>';
return implode('', $html);
}
private static function getRuleLineOutput(
object $rule,
string $key,
string|array $value
): string
{
switch ($rule->type)
{
case 'date__date':
case 'date__time':
case 'content__article__date':
case 'content__article__field':
return '';
default:
return self::getRuleLineOutputDefault($rule, $key, $value);
}
}
private static function getRuleLineOutputDefault(
object $rule,
string $key,
string|array $value
): string
{
if ($key === 'selection')
{
return '';
}
$key = $rule->type . '__' . $key;
$name = self::getNameString($key);
if ($name === $key)
{
return '';
}
$value = self::getValues($value, $key);
return self::getAttributeOutput($name, $value);
}
private static function getValues(string|array $values, string $key): string|array
{
if (empty($values) && $values !== '0')
{
return [];
}
$field = Helper::getField($key);
if ( ! $field)
{
return $values;
}
if ($field->type == 'Radio')
{
return self::getNameString($key . '.' . $values);
}
if ( ! is_array($values))
{
$values = [$values];
}
$class = Helper::getFieldClass($key);
if ($class)
{
$values = $class->getNamesByIds($values, $field->attributes);
}
else
{
foreach ($values as &$value)
{
$value = self::getNameString($value, $key);
}
}
if (count($values) < 6)
{
return $values;
}
$values = array_slice($values, 0, 5);
$values[] = '...';
return $values;
}
private static function getValuesOutputByRule(object $rule): string
{
switch ($rule->type)
{
case 'date__date':
case 'date__time':
case 'content__article__date':
return self::getValuesOutputByRuleDateTime($rule);
case 'content__article__field':
return self::getValuesOutputByRuleField($rule);
default:
return self::getValuesOutputByRuleDefault($rule);
}
}
private static function getValuesOutputByRuleDateTime(object $rule): string
{
$name = isset($rule->params->selection)
? self::getNameString($rule->params->selection, $rule->type)
: '';
if ($rule->params->comparison == 'between')
{
return self::getValuesOutputByRuleDateTimeBetween($rule, $name);
}
return self::getValuesOutputByRuleDateTimeBeforeOrAfter($rule, $name);
}
private static function getValuesOutputByRuleDateTimeBeforeOrAfter(
object $rule,
string $name
): string
{
$value = $rule->params->date ?? $rule->params->time;
$type = $rule->params->type ?? 'specific';
$value = $type == 'now'
? JText::_('CON_NOW')
: self::getDateTimeValue($value, $rule->type, false);
$comparison = JText::_('CON_DATE_' . $rule->params->comparison);
if ($name)
{
$comparison = lcfirst($comparison);
}
return '<strong>' . $name . '</strong>'
. ' ' . $comparison
. ' <code>' . $value . '</code>';
}
private static function getValuesOutputByRuleDateTimeBetween(object $rule, string $name): string
{
$recurring = ($rule->params->recurring ?? false);
$value_from = self::getDateTimeValue($rule->params->from, $rule->type, $recurring);
$value_to = self::getDateTimeValue($rule->params->to, $rule->type, $recurring);
$string = $recurring ? 'CON_BETWEEN_A_AND_B_EVERY_YEAR' : 'CON_BETWEEN_A_AND_B';
$value = JText::sprintf(
$string,
'<code class="text-nowrap">' . $value_from . '</code>',
'<code class="text-nowrap">' . $value_to . '</code>'
);
if ($name)
{
$value = lcfirst($value);
}
return '<strong>' . $name . '</strong>'
. ' ' . $value;
}
private static function getValuesOutputByRuleDefault(object $rule): string
{
$values = null;
foreach ($rule->params as $key => $value)
{
if ($key !== 'selection')
{
continue;
}
$values = self::getValues($value, $rule->type);
}
if (is_null($values))
{
return '';
}
if (RL_Array::implode($values, '') === '')
{
return '<ul><li>' . JText::_('<em>%s</em>,CON_NONE') . '</li></ul>';
}
$state_class = $rule->exclude ? 'danger' : 'success';
$fields = Helper::getField($rule->type);
if ($fields && in_array($fields->type, ['Editor', 'Textarea']))
{
return '<pre class="p-2 my-1 border border-' . $state_class . ' rounded"><code>'
. RL_String::escape(RL_Array::implode($values, '<br>'))
. '</code></pre>';
}
return '<ul><li>' . RL_Array::implode($values, '</li><li>') . '</li></ul>';
}
private static function getValuesOutputByRuleField(object $rule): string
{
$id = $rule->type . '__field';
$name = $rule->params->field;
$field = Helper::getField($id);
$class = Helper::getFieldClass($id);
if ($field && $class && method_exists($class, 'getNameById'))
{
$name = $class->getNameById($rule->params->field, $field->attributes);
}
$comparison = JText::_('CON_COMPARISON_' . strtoupper($rule->params->comparison));
return '<strong>' . $name . '</strong>'
. ' <code>' . lcfirst($comparison) . '</code> '
. $rule->params->value;
}
}

View File

@ -0,0 +1,178 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Model;
use Exception;
use Joomla\CMS\Factory as JFactory;
use Joomla\CMS\Form\FormFactoryInterface;
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
use Joomla\CMS\MVC\Model\AdminModel as JAdminModel;
use Joomla\Utilities\ArrayHelper as JArray;
use RegularLabs\Component\Conditions\Administrator\Helper\Cache;
use RegularLabs\Library\DB as RL_DB;
use RegularLabs\Library\Parameters as RL_Parameters;
defined('_JEXEC') or die;
class GroupModel extends JAdminModel
{
protected $name = 'group';
/**
* @var string The prefix to use with controller messages.
*/
protected $text_prefix = 'RL';
/* @var RuleModel $group_model */
private $rule_model;
/**
* @param array $config An array of configuration options (name, state, dbo, table_path, ignore_request).
* @param MVCFactoryInterface $factory The factory.
* @param FormFactoryInterface $formFactory The form factory.
*
* @throws Exception
*/
public function __construct(
$config = [],
MVCFactoryInterface $factory = null,
FormFactoryInterface $formFactory = null
)
{
parent::__construct($config, $factory, $formFactory);
$this->config = RL_Parameters::getComponent('conditions');
$this->rule_model = JFactory::getApplication()->bootComponent('com_conditions')
->getMVCFactory()->createModel('Rule', 'Administrator', ['ignore_request' => true]);
}
/**
* @param array &$pks An array of record primary keys.
*
* @return boolean True if successful, false if an error occurs.
*/
public function delete(&$pks)
{
$group_ids = JArray::toInteger((array) $pks);
$this->rule_model->deleteByGroupIds($group_ids);
if ( ! parent::delete($pks))
{
return false;
}
$query = $this->_db->replacePrefix('ALTER TABLE ' . RL_DB::quoteName('#__conditions_groups') . ' AUTO_INCREMENT = 1');
$this->_db->setQuery($query);
$this->_db->execute();
return true;
}
public function deleteByConditionId($condition_id)
{
$group_ids = $this->getGroupIdsByConditionId($condition_id);
$this->delete($group_ids);
}
public function getForm($data = [], $loadData = true)
{
return false;
}
public function getRules($group_id)
{
$cache = (new Cache)->useFiles();
if ($cache->exists())
{
return $cache->get();
}
$query = $this->_db->getQuery(true)
->select('*')
->from('#__conditions_rules as r')
->where('r.group_id = ' . (int) $group_id);
$this->_db->setQuery($query);
$rules = $this->_db->loadObjectList();
foreach ($rules as &$rule)
{
if ( ! isset($rule->params))
{
continue;
}
$rule->params = (object) json_decode($rule->params);
}
return $cache->set($rules);
}
/**
* @param array $data The form data.
*
* @return boolean True on success.
*/
public function save($data)
{
$this->setState($this->getName() . '.id', null);
$data = (array) $data;
if (empty($data['rules']))
{
return true;
}
$rules = $data['rules'];
$data['id'] = 0;
unset($data['rules']);
if ( ! parent::save($data))
{
return false;
}
$data['id'] = (int) $this->getState($this->getName() . '.id');
foreach ($rules as $rule)
{
$rule->group_id = $data['id'];
if ( ! $this->rule_model->save($rule))
{
return false;
}
}
(new Cache())->resetAll();
return parent::save($data);
}
private function getGroupIdsByConditionId(?int $condition_id): array
{
$query = $this->_db->getQuery(true)
->select('g.id')
->from('#__conditions_groups as g')
->where('g.condition_id = ' . (int) $condition_id);
$this->_db->setQuery($query);
return $this->_db->loadColumn();
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,217 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Model;
use Joomla\CMS\Factory as JFactory;
use Joomla\CMS\Language\Text as JText;
use Joomla\CMS\MVC\Model\ListModel;
use RegularLabs\Library\Input as RL_Input;
use RegularLabs\Library\Parameters as RL_Parameters;
defined('_JEXEC') or die;
class ItemsModel extends ListModel
{
protected $config;
/**
* @var string The prefix to use with controller messages.
*/
protected $text_prefix = 'RL';
/**
* Constructor.
*
* @param array An optional associative array of configuration settings.
*
* @see JController
*/
public function __construct($config = [])
{
if (empty($config['filter_fields']))
{
$config['filter_fields'] = [
'alias', 'a.alias',
'category', 'a.category',
'color', 'a.color',
'description', 'a.description',
'id', 'a.id',
'name', 'a.name',
'published', 'a.published',
];
}
parent::__construct($config);
$is_modal = RL_Input::getString('layout') === 'modal';
if ($is_modal)
{
$this->context .= '_modal';
}
$this->config = RL_Parameters::getComponent('conditions');
}
/**
* Duplicate Method
* Duplicate all items specified by array id
*/
public function duplicate($ids, $model)
{
foreach ($ids as $id)
{
$model->duplicate($id);
}
$msg = JText::sprintf('%d items duplicated', count($ids));
JFactory::getApplication()->enqueueMessage($msg);
}
public function getItems($getall = false, $aliases = [])
{
// Load the list items.
if ($getall)
{
$db = $this->getDbo();
$query = $db->getQuery(true)
// Select the required fields from the table.
->select('a.*')
->from($db->quoteName('#__conditions', 'a'));
}
else
{
$query = $this->_getListQuery();
}
$sub_query = $this->_db->getQuery(true)
->select('count(*)')
->from('#__conditions_map as m')
->where('m.condition_id = a.id');
$query->select('(' . ((string) $sub_query) . ') as nr_of_uses');
if ($getall)
{
$this->_db->setQuery($query);
$items = $this->_db->loadObjectList('alias');
}
else
{
$items = $this->_getList($query, $this->getStart(), $this->getState('list.limit'));
}
return $items;
}
/**
* Build an SQL query to load the list data.
*
* @return JDatabaseQuery
*/
protected function getListQuery()
{
$db = $this->getDbo();
$query = $db->getQuery(true)
// Select the required fields from the table.
->select(
$this->getState(
'list.select',
'a.*'
)
)
->from($db->quoteName('#__conditions', 'a'));
$state = $this->getState('filter.state');
if (is_numeric($state))
{
$query->where($db->quoteName('a.published') . ' = ' . ( int ) $state);
}
elseif ($state == '')
{
$query->where('( ' . $db->quoteName('a.published') . ' IN ( 0,1,2 ) )');
}
$category = $this->getState('filter.category');
if ($category != '')
{
$query->where($db->quoteName('a.category') . ' = ' . $db->quote($category));
}
// Filter the list over the search string if set.
$search = $this->getState('filter.search');
if ( ! empty($search))
{
if (stripos($search, 'id:') === 0)
{
$query->where($db->quoteName('a.id') . ' = ' . ( int ) substr($search, 3));
}
else
{
$search = $db->quote('%' . $db->escape($search, true) . '%');
$query->where(
'( ' . $db->quoteName('a.alias') . ' LIKE ' . $search .
' OR ' . $db->quoteName('a.name') . ' LIKE ' . $search .
' OR ' . $db->quoteName('a.description') . ' LIKE ' . $search .
' OR ' . $db->quoteName('a.category') . ' LIKE ' . $search . ' )'
);
}
}
$query->select($db->quoteName('uc.name', 'editor'))
->join('LEFT', $db->quoteName('#__users', 'uc'), $db->quoteName('uc.id') . ' = ' . $db->quoteName('a.checked_out'));
// Add the list ordering clause.
$ordering = $this->getState('list.ordering', 'a.name');
$query->order($db->quoteName($db->escape($ordering)) . ' ' . $db->escape($this->getState('list.direction', 'ASC')));
return $query;
}
/**
* Method to get a store id based on model configuration state.
*
* This is necessary because the model is used by the component and
* different modules that might need different sets of data or different
* ordering requirements.
*
* @param string A prefix for the store id.
*
* @return string A store id.
*/
protected function getStoreId($id = '', $getall = 0, $alias = [])
{
// Compile the store id.
$id .= ':' . $this->getState('filter.search');
$id .= ':' . $this->getState('filter.state');
$id .= ':' . $getall;
$id .= ':' . json_encode($alias);
return parent::getStoreId($id);
}
/**
* Method to auto-populate the model state.
*
* Note. Calling getState in this method will result in recursion.
*
*/
protected function populateState($ordering = null, $direction = null)
{
// List state information.
parent::populateState('a.name', 'asc');
}
}

View File

@ -0,0 +1,121 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Model;
use Exception;
use Joomla\CMS\Form\FormFactoryInterface;
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
use Joomla\CMS\MVC\Model\AdminModel as JAdminModel;
use RegularLabs\Component\Conditions\Administrator\Helper\Cache;
use RegularLabs\Library\DB as RL_DB;
use RegularLabs\Library\Parameters as RL_Parameters;
defined('_JEXEC') or die;
class RuleModel extends JAdminModel
{
protected $name = 'rule';
/**
* @var string The prefix to use with controller messages.
*/
protected $text_prefix = 'RL';
/**
* @param array $config An array of configuration options (name, state, dbo, table_path, ignore_request).
* @param MVCFactoryInterface $factory The factory.
* @param FormFactoryInterface $formFactory The form factory.
*
* @throws Exception
*/
public function __construct(
$config = [],
MVCFactoryInterface $factory = null,
FormFactoryInterface $formFactory = null
)
{
parent::__construct($config, $factory, $formFactory);
$this->config = RL_Parameters::getComponent('conditions');
}
public function deleteByGroupIds($group_ids)
{
if (empty($group_ids))
{
return;
}
$query = $this->_db->getQuery(true)
->delete('#__conditions_rules')
->where(RL_DB::in(RL_DB::quoteName('group_id'), $group_ids));
$this->_db->setQuery($query);
$this->_db->execute();
$query = $this->_db->replacePrefix('ALTER TABLE ' . RL_DB::quoteName('#__conditions_rules') . ' AUTO_INCREMENT = 1');
$this->_db->setQuery($query);
$this->_db->execute();
}
public function getForm($data = [], $loadData = true)
{
return false;
}
/**
* @param array $data The form data.
*
* @return boolean True on success.
*/
public function save($data)
{
$this->setState($this->getName() . '.id', null);
$data = (array) $data;
$data['id'] = 0;
$data['params'] = json_encode($data['params']);
(new Cache())->resetAll();
return parent::save($data);
}
private function getRulesByGroupId(?int $group_id): array
{
$cache = new Cache;
if ($cache->exists())
{
return $cache->get();
}
$query = $this->_db->getQuery(true)
->select('*')
->from('#__conditions_rules as r')
->where('r.group_id = ' . (int) $group_id);
$this->_db->setQuery($query);
$rules = $this->_db->loadObjectList();
foreach ($rules as &$rule)
{
if ( ! isset($rule->params))
{
continue;
}
$rule->params = (object) json_decode($rule->params);
}
return $cache->set($rules);
}
}

View File

@ -0,0 +1,45 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Table;
use Exception;
use Joomla\CMS\Table\Table;
use Joomla\Database\DatabaseDriver;
defined('_JEXEC') or die;
class ConditionTable extends Table
{
public function __construct(DatabaseDriver $db)
{
parent::__construct('#__conditions', 'id', $db);
}
public function check(): bool
{
try
{
parent::check();
}
catch (Exception $e)
{
$this->setError($e->getMessage());
return false;
}
$this->name = trim($this->name);
$this->alias = trim($this->alias);
return true;
}
}

View File

@ -0,0 +1,44 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Table;
use Exception;
use Joomla\CMS\Table\Table;
use Joomla\Database\DatabaseDriver;
defined('_JEXEC') or die;
class GroupTable extends Table
{
public function __construct(DatabaseDriver $db)
{
parent::__construct('#__conditions_groups', 'id', $db);
}
public function check(): bool
{
try
{
parent::check();
}
catch (Exception $e)
{
$this->setError($e->getMessage());
return false;
}
$this->condition_id = (int) $this->condition_id;
return true;
}
}

View File

@ -0,0 +1,44 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\Table;
use Exception;
use Joomla\CMS\Table\Table;
use Joomla\Database\DatabaseDriver;
defined('_JEXEC') or die;
class RuleTable extends Table
{
public function __construct(DatabaseDriver $db)
{
parent::__construct('#__conditions_rules', 'id', $db);
}
public function check(): bool
{
try
{
parent::check();
}
catch (Exception $e)
{
$this->setError($e->getMessage());
return false;
}
$this->group_id = (int) $this->group_id;
return true;
}
}

View File

@ -0,0 +1,122 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\View\Item;
use Joomla\CMS\Form\Form as JForm;
use Joomla\CMS\Helper\ContentHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\View\GenericDataException;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
use Joomla\CMS\Toolbar\ToolbarHelper;
use RegularLabs\Library\Input as RL_Input;
use RegularLabs\Library\Parameters as RL_Parameters;
defined('_JEXEC') or die;
/**
* Item View
*/
class HtmlView extends BaseHtmlView
{
/**
* @var object
*/
protected $config;
/**
* @var JForm
*/
protected $form;
/**
* @var object
*/
protected $item;
/**
* @var object
*/
protected $state;
/**
* @param string $tpl The name of the template file to parse; automatically searches through the template paths.
*
* @return mixed False if unsuccessful, otherwise void.
*/
public function display($tpl = null)
{
$this->model = $this->getModel();
$this->form = $this->get('Form');
$this->item = $this->get('Item');
$this->state = $this->get('State');
$this->config = RL_Parameters::getComponent('conditions', $this->state->params);
$errors = $this->get('Errors');
// Check for errors.
if (count($errors))
{
throw new GenericDataException(implode("\n", $errors), 500);
}
$this->addToolbar();
parent::display($tpl);
}
/**
* @return void
*/
protected function addToolbar()
{
$isNew = ($this->item->id == 0);
$canDo = ContentHelper::getActions('com_conditions');
RL_Input::set('hidemainmenu', true);
ToolbarHelper::title(Text::_('CONDITIONS') . ': ' . Text::_('RL_ITEM'), 'conditions icon-reglab');
$toolbarButtons = [];
// If not checked out, can save the item.
if ($canDo->get('core.edit'))
{
ToolbarHelper::apply('item.apply');
$toolbarButtons[] = ['save', 'item.save'];
}
/**
* This component does not support Save as Copy due to uniqueness checks.
* While it can be done, it causes too much confusion if the user does
* not change the Old URL.
*/
if ($canDo->get('core.edit') && $canDo->get('core.create'))
{
$toolbarButtons[] = ['save2new', 'item.save2new'];
}
if ( ! $isNew && $canDo->get('core.create'))
{
$toolbarButtons[] = ['save2copy', 'item.save2copy'];
}
ToolbarHelper::saveGroup(
$toolbarButtons,
'btn-success'
);
if (empty($this->item->id))
{
ToolbarHelper::cancel('item.cancel');
}
else
{
ToolbarHelper::cancel('item.cancel', 'JTOOLBAR_CLOSE');
}
}
}

View File

@ -0,0 +1,179 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
namespace RegularLabs\Component\Conditions\Administrator\View\Items;
use Joomla\CMS\Factory as JFactory;
use Joomla\CMS\Form\Form as JForm;
use Joomla\CMS\Helper\ContentHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\View\GenericDataException;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
use Joomla\CMS\Pagination\Pagination;
use Joomla\CMS\Toolbar\Toolbar;
use Joomla\CMS\Toolbar\ToolbarHelper;
use Joomla\Registry\Registry;
use RegularLabs\Library\Parameters as RL_Parameters;
defined('_JEXEC') or die;
/**
* List View
*/
class HtmlView extends BaseHtmlView
{
/**
* @var array
*/
public $activeFilters;
/**
* @var JForm
*/
public $filterForm;
/**
* @var boolean
*/
protected $collect_urls_enabled;
/**
* @var boolean
*/
protected $enabled;
/**
* @var array
*/
protected $items;
/**
* @var Pagination
*/
protected $pagination;
/**
* @var Registry
*/
protected $params;
/**
* @var object
*/
protected $state;
/**
* @param string $tpl The name of the template file to parse; automatically searches through the template paths.
*
* @return mixed False if unsuccessful, otherwise void.
*
* @throws GenericDataException
*/
public function display($tpl = null)
{
$this->items = $this->get('Items');
$this->pagination = $this->get('Pagination');
$this->state = $this->get('State');
$this->config = RL_Parameters::getComponent('conditions');
$this->filterForm = $this->get('FilterForm');
$this->activeFilters = $this->get('ActiveFilters');
$this->hasCategories = $this->get('HasCategories');
// Check for errors.
if (count($errors = $this->get('Errors')))
{
throw new GenericDataException(implode("\n", $errors), 500);
}
$this->addToolbar();
return parent::display($tpl);
}
/**
* @return void
*/
protected function addToolbar()
{
$user = JFactory::getApplication()->getIdentity() ?: JFactory::getUser();
$canDo = ContentHelper::getActions('com_conditions');
$toolbar = Toolbar::getInstance('toolbar');
ToolbarHelper::title(Text::_('CONDITIONS') . ': ' . Text::_('RL_Items'), 'conditions icon-reglab');
if ($canDo->get('core.create'))
{
$toolbar->addNew('item.add');
}
if ($canDo->get('core.edit.state') || $user->authorise('core.admin'))
{
$dropdown = $toolbar->dropdownButton('status-group')
->text('JTOOLBAR_CHANGE_STATUS')
->toggleSplit(false)
->icon('icon-ellipsis-h')
->buttonClass('btn btn-action')
->listCheck(true);
$childBar = $dropdown->getChildToolbar();
if (
$canDo->get('core.edit.state')
&& $this->state->get('filter.state') !== ''
&& $this->state->get('filter.state') !== '1'
)
{
$childBar->publish('items.publish')->listCheck(true);
}
if ($canDo->get('core.edit.state') && $this->state->get('filter.state') !== '-2')
{
$childBar->trash('items.trash')->listCheck(true);
}
if ($canDo->get('core.delete') && $this->state->get('filter.state') === '-2')
{
$childBar->delete('items.delete')->listCheck(true);
}
if ($canDo->get('core.create'))
{
$childBar->standardButton('copy')
->text('JTOOLBAR_DUPLICATE')
->task('items.duplicate')
->listCheck(true);
}
if ($canDo->get('core.delete') && $this->state->get('filter.state') === '-2')
{
$toolbar->delete('items.delete')
->text('JTOOLBAR_EMPTY_TRASH')
->message('JGLOBAL_CONFIRM_DELETE')
->listCheck(true);
}
// if ($canDo->get('core.create'))
// {
// $childBar->standardButton('file-export')
// ->text('RL_EXPORT')
// ->task('items.export')
// ->listCheck(true);
// }
}
// if ($canDo->get('core.create'))
// {
// $toolbar->popupButton('file-import')
// ->icon('icon-file-import')
// ->text('RL_IMPORT')
// ->selector('importModal');
// }
if ($canDo->get('core.admin'))
{
$toolbar->preferences('com_conditions');
}
}
}

View File

@ -0,0 +1,99 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
defined('_JEXEC') or die;
use Joomla\CMS\Factory as JFactory;
use RegularLabs\Component\Conditions\Administrator\Helper\Summary;
use RegularLabs\Component\Conditions\Administrator\Model\ItemModel;
use RegularLabs\Library\Input as RL_Input;
if (JFactory::getApplication()->isClient('site'))
{
die();
}
echo (new Conditions)->render();
die;
class Conditions
{
private $extension = '';
private $message = '';
public function getCondition()
{
$id = RL_Input::getInt('id');
$enabled_types = RL_Input::getString('enabled_types');
if ($id)
{
return (new ItemModel)->getConditionById($id, false, $enabled_types);
}
$extension = RL_Input::getCmd('extension');
$item_id = RL_Input::getInt('item_id');
if ($extension && $item_id)
{
return (new ItemModel)->getConditionByExtensionItem($extension, $item_id, false, $enabled_types);
}
$data = [];
$form = RL_Input::getRaw('form', []);
foreach ($form as $key => $value)
{
$key = str_replace('jform[', '', $key);
$data[$key] = $value;
}
if (isset($data['extension']))
{
$this->extension = $data['extension'];
}
if (isset($data['message']))
{
$this->message = $data['message'];
}
if (isset($data['enabled_types']))
{
$enabled_types = $data['enabled_types'];
unset($data['enabled_types']);
}
return (new ItemModel)->getConditionFromData($data, $enabled_types);
}
public function render()
{
$condition = $this->getCondition();
$extension = $this->extension ?: RL_Input::getCmd('extension');
$message = $this->message ?: RL_Input::get('message', '');
if ($extension && $condition && $condition->published !== 1)
{
$condition = null;
}
return json_encode((object) [
'has_conditions' => ! empty($condition),
'id' => $condition->id ?? '',
'alias' => $condition->alias ?? '',
'name' => $condition->name ?? '',
'content' => Summary::render($condition, $extension, $message),
]);
}
}

View File

@ -0,0 +1,120 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
defined('_JEXEC') or die;
use Joomla\CMS\Access\Exception\NotAllowed;
use Joomla\CMS\Factory as JFactory;
use Joomla\CMS\HTML\HTMLHelper as JHtml;
use Joomla\CMS\Language\Text as JText;
use Joomla\CMS\Layout\LayoutHelper as JLayout;
use Joomla\CMS\Router\Route as JRoute;
use RegularLabs\Component\Conditions\Administrator\Helper\Helper;
use RegularLabs\Library\Document as RL_Document;
use RegularLabs\Library\Language as RL_Language;
$user = JFactory::getApplication()->getIdentity() ?: JFactory::getUser();
$canAccess = $user->authorise('core.admin', 'com_conditions');
$canEdit = $user->authorise('core.edit', 'com_conditions');
if ( ! $canAccess || ! $canEdit)
{
throw new NotAllowed(JText::_('JERROR_ALERTNOAUTHOR'), 403);
}
RL_Document::useScript('keepalive');
RL_Document::useScript('form.validate');
RL_Document::usePreset('choicesjs');
RL_Document::useScript('webcomponent.field-fancy-select');
RL_Document::script('regularlabs.regular');
RL_Document::script('regularlabs.admin-form');
RL_Document::script('regularlabs.admin-form-descriptions');
RL_Document::script('regularlabs.treeselect');
RL_Document::script('conditions.script');
$script = "document.addEventListener('DOMContentLoaded', function(){RegularLabs.Conditions.init()});";
RL_Document::scriptDeclaration($script, 'Conditions', true, 'after');
RL_Language::load('com_content', JPATH_ADMINISTRATOR);
?>
<form action="<?php echo JRoute::_('index.php?option=com_conditions&id=' . (int) $this->item->id); ?>"
method="post" name="adminForm" id="conditionsForm"
aria-label="<?php echo JText::_('COM_CONDITIONS_FORM_' . ((int) $this->item->id === 0 ? 'NEW' : 'EDIT'), true); ?>"
class="form-validate rl-form">
<?php echo JLayout::render('joomla.edit.title_alias', $this); ?>
<fieldset class="mt-3">
<?php echo JHtml::_('uitab.startTabSet', 'main', ['active' => 'details']); ?>
<?php echo JHtml::_('uitab.addTab', 'main', 'details', JText::_('CON_RULES')); ?>
<div class="hide-on-update-summary position-relative">
<div class="rl-spinner rl-spinner-lg"></div>
</div>
<div class="row show-on-update-summary hidden">
<div id="conditionsFormFields" class="col-lg-8">
<?php echo $this->form->renderFieldset('rules'); ?>
</div>
<div class="col-lg-4">
<h3><?php echo JText::_('CON_SUMMARY'); ?></h3>
<div id="rules_summary" class="position-relative">
<div id="rules_summary_content" class="hidden"></div>
</div>
</div>
</div>
<?php echo JHtml::_('uitab.endTab'); ?>
<?php
$title = JText::_('CON_USAGE')
. ' <span class="badge bg-secondary">' . $this->item->nr_of_uses . '</span>';
?>
<?php echo JHtml::_('uitab.addTab', 'main', 'variables', $title); ?>
<?php if (empty($this->item->usage)): ?>
<div class="alert alert-warning">
<?php echo JText::_('CON_NOT_USED'); ?>
</div>
<?php else: ?>
<p><?php echo JText::_('CON_USED_ON'); ?></p>
<?php foreach ($this->item->usage as $extension_name => $extension_usage) : ?>
<?php $extension_name = Helper::getExtensionName($extension_name); ?>
<h3><?php echo $extension_name; ?></h3>
<ul>
<?php foreach ($extension_usage as $usage_items) : ?>
<li>
<?php if ($usage_items->url): ?>
<a href="<?php echo $usage_items->url; ?>" target="_blank">
<?php echo $usage_items->item_name; ?>
</a>
<?php else: ?>
<?php echo $usage_items->item_name; ?>
<?php endif; ?>
<small>[<?php echo JText::_('JGLOBAL_FIELD_ID_LABEL'); ?>
: <?php echo $usage_items->item_id; ?>]</small>
<?php if ($usage_items->published !== 1): ?>
<span class="badge bg-danger"><?php echo Helper::getPublishStateString($usage_items->published); ?></span>
<?php endif; ?>
</li>
<?php endforeach; ?>
</ul>
<?php endforeach; ?>
<?php endif; ?>
<?php echo JHtml::_('uitab.endTab'); ?>
<?php echo JHtml::_('uitab.addTab', 'main', 'variables', JText::_('JDETAILS')); ?>
<?php echo $this->form->renderFieldset('details'); ?>
<?php echo JHtml::_('uitab.endTab'); ?>
<?php echo JHtml::_('uitab.endTabSet'); ?>
<input type="hidden" name="task" value="">
<?php echo JHtml::_('form.token'); ?>
</fieldset>
</form>

View File

@ -0,0 +1,17 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
defined('_JEXEC') or die;
?>
<div class="alert alert-error">
Oops, something went wromg!
</div>

View File

@ -0,0 +1,140 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
defined('_JEXEC') or die;
use Joomla\CMS\Access\Exception\NotAllowed;
use Joomla\CMS\Factory as JFactory;
use Joomla\CMS\HTML\HTMLHelper as JHtml;
use Joomla\CMS\Language\Text as JText;
use Joomla\CMS\Layout\LayoutHelper as JLayout;
use Joomla\CMS\Router\Route as JRoute;
use RegularLabs\Library\Document as RL_Document;
use RegularLabs\Library\Input as RL_Input;
use RegularLabs\Library\Language as RL_Language;
$user = JFactory::getApplication()->getIdentity() ?: JFactory::getUser();
$canEdit = $user->authorise('core.edit', 'com_conditions');
if ( ! $canEdit)
{
throw new NotAllowed(JText::_('JERROR_ALERTNOAUTHOR'), 403);
}
$extension = RL_Input::getCmd('extension');
$item_id = RL_Input::getInt('item_id');
$id = RL_Input::getInt('id');
$table = RL_Input::getCmd('table');
$name_column = RL_Input::getCmd('name_column');
$enabled_types = RL_Input::getString('enabled_types');
$message = RL_Input::get('message', '');
RL_Document::useScript('keepalive');
RL_Document::useScript('form.validate');
RL_Document::usePreset('choicesjs');
RL_Document::useScript('webcomponent.field-fancy-select');
RL_Document::script('regularlabs.regular');
RL_Document::script('regularlabs.admin-form');
RL_Document::script('regularlabs.admin-form-descriptions');
RL_Document::script('regularlabs.treeselect');
RL_Document::script('conditions.script');
$script = "document.addEventListener('DOMContentLoaded', function(){RegularLabs.Conditions.init()});";
RL_Document::scriptDeclaration($script, 'Conditions', true, 'after');
$update = '';
if ($extension && $item_id)
{
$update = 'parent.RegularLabs.Conditions.updateSummaryByExtension("' . $extension . '", ' . $item_id . ', "' . $message . '", "' . $enabled_types . '");';
}
if ($id)
{
$update = 'parent.RegularLabs.Conditions.updateSummaryByCondition(' . $id . ', "' . $extension . '", "' . $message . '", "' . $enabled_types . '");';
}
$script = '
document.addEventListener("DOMContentLoaded", function(){
window.parent.document.querySelectorAll(".modal-dialog .conditions-button").forEach((btn) => {
Regular.removeClass(btn, "hidden");
});
});';
if ($update)
{
$script .= '
document.addEventListener("DOMContentLoaded", function(){
const modal = window.parent.Joomla.Modal && window.parent.Joomla.Modal.getCurrent();
if (modal) {
modal.addEventListener("hidden.bs.modal", () => {
' . $update . '
});
}
});';
}
RL_Document::scriptDeclaration($script, 'ConditionsModal', true, 'after', true);
RL_Language::load('com_content', JPATH_ADMINISTRATOR);
$params = [
'id' => (int) $this->item->id,
'extension' => $extension,
'item_id' => $item_id,
'table' => $table,
'name_column' => $name_column,
'enabled_types' => $enabled_types,
'message' => $message,
'tmpl' => RL_Input::getString('tmpl'),
];
$append = http_build_query($params);
$url = 'index.php?option=com_conditions&' . $append;
?>
<?php if (count($this->item->usage) > 1) : ?>
<div class="alert alert-warning">
<?php echo JText::_('CON_WARNING_FOR_EDITING_MULTIPLE_USAGE'); ?>
</div>
<?php endif; ?>
<form action="<?php echo JRoute::_($url); ?>"
method="post" name="adminForm" id="conditionsForm"
aria-label="<?php echo JText::_('COM_CONDITIONS_FORM_' . ((int) $this->item->id === 0 ? 'NEW' : 'EDIT'), true); ?>"
class="form-validate rl-form">
<?php echo JLayout::render('joomla.edit.title_alias', $this); ?>
<div class="hide-on-update-summary position-relative">
<div class="rl-spinner rl-spinner-lg"></div>
</div>
<div class="row show-on-update-summary hidden">
<div id="conditionsFormFields" class="col-lg-8">
<?php echo $this->form->renderFieldset('rules'); ?>
</div>
<div class="col-lg-4">
<h3><?php echo JText::_('CON_SUMMARY'); ?></h3>
<div id="rules_summary" class="position-relative">
<div id="rules_summary_content" class="hidden"></div>
</div>
</div>
</div>
<input type="hidden" name="extension" value="<?php echo $extension; ?>">
<input type="hidden" name="item_id" value="<?php echo $item_id; ?>">
<input type="hidden" name="enabled_types" value="<?php echo $enabled_types; ?>">
<input type="hidden" name="message" value="<?php echo $message; ?>">
<input type="hidden" name="task" value="">
<?php echo JHtml::_('form.token'); ?>
</form>

View File

@ -0,0 +1,90 @@
<?php
/**
* @package Conditions
* @version 24.11.1459
*
* @author Peter van Westen <info@regularlabs.com>
* @link https://regularlabs.com
* @copyright Copyright © 2024 Regular Labs All Rights Reserved
* @license GNU General Public License version 2 or later
*/
defined('_JEXEC') or die;
use Joomla\CMS\Factory as JFactory;
use Joomla\CMS\Language\Text as JText;
use Joomla\CMS\Router\Route as JRoute;
use RegularLabs\Component\Conditions\Administrator\Helper\Helper;
use RegularLabs\Library\Input as RL_Input;
use RegularLabs\Library\StringHelper as RL_String;
$user = JFactory::getApplication()->getIdentity() ?: JFactory::getUser();
$canCreate = $user->authorise('core.create', 'com_conditions');
$canEdit = $user->authorise('core.edit', 'com_conditions');
$extension = RL_Input::getCmd('extension');
$item_id = RL_Input::getInt('item_id');
$table = RL_Input::getCmd('table');
$name_column = RL_Input::getCmd('name_column');
$enabled_types = RL_Input::getString('enabled_types');
$message = RL_Input::get('message', '');
$current_item_name = $this->item->usage[$extension][$item_id]->item_name ?? null;
$url = 'index.php?option=com_conditions'
. '&view=item'
. '&id=' . $this->item->id
. '&extension=' . $extension
. '&item_id=' . $item_id
. '&table=' . $table
. '&name_column=' . $name_column
. '&enabled_types=' . $enabled_types
. '&message=' . $message
. '&layout=modal_edit'
. '&tmpl=component';
?>
<div class="alert alert-warning">
<p><?php echo JText::_('CON_USED_ON'); ?></p>
<?php if ( ! empty($this->item->name)) : ?>
<h3><?php echo RL_String::escape($this->item->name); ?></h3>
<?php endif; ?>
<?php foreach ($this->item->usage as $extension_name => $extension_usage) : ?>
<?php $extension_name = Helper::getExtensionName($extension_name); ?>
<span class="badge badge-sm bg-secondary"><?php echo $extension_name; ?></span>
<ul class="mb-1">
<?php foreach ($extension_usage as $usage_item) : ?>
<?php $is_current = ($usage_item->extension == $extension && $usage_item->item_id == $item_id); ?>
<li>
<?php echo $is_current ? '<strong>' : ''; ?>
[<?php echo $usage_item->item_id; ?>] <?php echo $usage_item->item_name; ?>
<?php echo $is_current ? '</strong>' : ''; ?>
</li>
<?php endforeach; ?>
</ul>
<?php endforeach; ?>
</div>
<div class="text-center">
<?php if ($canCreate && $canEdit) : ?>
<p><?php echo JText::_('CON_WHAT_TO_DO'); ?></p>
<?php endif; ?>
<p>
<?php if ($canCreate) : ?>
<a class="btn btn-primary" title="<?php echo JText::_('CON_BUTTON_COPY', true); ?>"
href="<?php echo JRoute::_($url . '&task=item.copy'); ?>">
<span class="icon-copy" aria-hidden="true"></span>
<?php echo JText::sprintf('CON_BUTTON_CONFIRM_COPY', $current_item_name ? ': ' . $current_item_name : ''); ?>
</a>
<?php endif; ?>
<?php if ($canEdit) : ?>
<a class="btn btn-warning" title="<?php echo JText::_('CON_BUTTON_EDIT', true); ?>"
href="<?php echo JRoute::_($url . '&task=item.edit'); ?>">
<span class="icon-edit" aria-hidden="true"></span>
<?php echo JText::sprintf('CON_BUTTON_CONFIRM_EDIT', $current_item_name ? ': ' . $current_item_name : ''); ?>
</a>
<?php endif; ?>
</p>
</div>

Some files were not shown because too many files have changed in this diff Show More