393 lines
12 KiB
PHP
393 lines
12 KiB
PHP
<?php
|
|
|
|
/**
|
|
* @author Tassos.gr <info@tassos.gr>
|
|
* @link https://www.tassos.gr
|
|
* @copyright Copyright © 2024 Tassos All Rights Reserved
|
|
* @license GNU GPLv3 <http://www.gnu.org/licenses/gpl.html> or later
|
|
*/
|
|
|
|
namespace NRFramework\Conditions;
|
|
|
|
defined('_JEXEC') or die;
|
|
|
|
use Joomla\CMS\Layout\LayoutHelper;
|
|
use NRFramework\Conditions\ConditionsHelper;
|
|
use NRFramework\Extension;
|
|
use Joomla\CMS\Language\Text;
|
|
use Joomla\CMS\Uri\Uri;
|
|
use Joomla\CMS\HTML\HTMLHelper;
|
|
use Joomla\CMS\Form\Form;
|
|
|
|
class ConditionBuilder
|
|
{
|
|
public static function pass($rules)
|
|
{
|
|
$rules = self::prepareRules($rules);
|
|
|
|
if (empty($rules))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return ConditionsHelper::getInstance()->passSets($rules);
|
|
}
|
|
|
|
/**
|
|
* Prepare rules object to run checks
|
|
*
|
|
* @return void
|
|
*/
|
|
public static function prepareRules($rules = [])
|
|
{
|
|
if (!is_array($rules))
|
|
{
|
|
return [];
|
|
}
|
|
|
|
$rules_ = [];
|
|
|
|
foreach ($rules as $key => $group)
|
|
{
|
|
if (isset($group['enabled']) AND !(bool) $group['enabled'])
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// A group without rules, doesn't make sense.
|
|
if (!isset($group['rules']) OR (isset($group['rules']) AND empty($group['rules'])))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
$validRules = [];
|
|
|
|
foreach ($group['rules'] as $rule)
|
|
{
|
|
// Make sure rule has a name.
|
|
if (!isset($rule['name']) OR (isset($rule['name']) AND empty($rule['name'])))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// Rule is invalid if both value and params properties are empty
|
|
if (!isset($rule['value']) && !isset($rule['params']))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// Skip disabled rules
|
|
if (isset($rule['enabled']) && !(bool) $rule['enabled'])
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// We don't need this property.
|
|
unset($rule['enabled']);
|
|
|
|
// Prepare rule value if necessary
|
|
if (isset($rule['value']))
|
|
{
|
|
$rule['value'] = self::prepareTFRepeaterValue($rule['value']);
|
|
}
|
|
|
|
// Verify operator
|
|
if (!isset($rule['operator']) OR (isset($rule['operator']) && empty($rule['operator'])))
|
|
{
|
|
$rule['operator'] = isset($rule['params']['operator']) ? $rule['params']['operator'] : '';
|
|
}
|
|
|
|
$validRules[] = $rule;
|
|
}
|
|
|
|
if (count($validRules) > 0)
|
|
{
|
|
$group['rules'] = $validRules;
|
|
|
|
if (!isset($group['matching_method']) OR (isset($group['matching_method']) AND empty($group['matching_method'])))
|
|
{
|
|
$group['matching_method'] = 'all';
|
|
}
|
|
|
|
unset($group['enabled']);
|
|
$rules_[] = $group;
|
|
}
|
|
}
|
|
|
|
return $rules_;
|
|
}
|
|
|
|
/**
|
|
* Parse the value of the TF Repeater Input field.
|
|
*
|
|
* @param array $selection
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public static function prepareTFRepeaterValue($selection)
|
|
{
|
|
// Only proceed when we have an array of arrays selection.
|
|
if (!is_array($selection))
|
|
{
|
|
return $selection;
|
|
}
|
|
|
|
$first = array_values($selection)[0];
|
|
|
|
if (!is_array($first))
|
|
{
|
|
return $selection;
|
|
}
|
|
|
|
if (!isset($first['value']))
|
|
{
|
|
return $selection;
|
|
}
|
|
|
|
$new_selection = [];
|
|
|
|
foreach ($selection as $value)
|
|
{
|
|
/**
|
|
* We expect a `value` key for TFInputRepeater fields or a key,value pair
|
|
* for plain arrays.
|
|
*/
|
|
if (!isset($value['value']))
|
|
{
|
|
/**
|
|
* If no value exists, it means that the passed $assignment->selection is a key,value pair array so we use the value
|
|
* as our returned selection.
|
|
*
|
|
* This happens when we pass a key,value pair array as $assignment->selection when we expect a TFInputRepeater value
|
|
* so we need to take this into consideration.
|
|
*/
|
|
$new_selection[] = $value;
|
|
continue;
|
|
}
|
|
|
|
// value must not be empty
|
|
if (is_scalar($value['value']) && empty(trim($value['value'])))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
$new_selection[] = count($value) === 1 ? $value['value'] : $value;
|
|
}
|
|
|
|
return $new_selection;
|
|
}
|
|
|
|
/**
|
|
* Returns the TGeoIP plugin modal.
|
|
*
|
|
* @return string
|
|
*/
|
|
public static function getGeoModal()
|
|
{
|
|
// Do not proceed if the database is up-to-date
|
|
if (!\NRFramework\Extension::geoPluginNeedsUpdate())
|
|
{
|
|
return;
|
|
}
|
|
|
|
HTMLHelper::_('bootstrap.modal');
|
|
|
|
$modalName = 'tf-geodbchecker-modal';
|
|
|
|
// The TGeoIP Plugin URL
|
|
$url = Uri::base(true) . '/index.php?option=com_plugins&view=plugin&tmpl=component&layout=modal&extension_id=' . \NRFramework\Functions::getExtensionID('tgeoip', 'system');
|
|
|
|
$options = [
|
|
'title' => Text::_('NR_EDIT'),
|
|
'url' => $url,
|
|
'height' => '400px',
|
|
'backdrop' => 'static',
|
|
'bodyHeight' => '70',
|
|
'modalWidth' => '70',
|
|
'footer' => '<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" data-dismiss="modal" aria-hidden="true">'
|
|
. Text::_('JLIB_HTML_BEHAVIOR_CLOSE') . '</button>
|
|
<button type="button" class="btn btn-success" aria-hidden="true"
|
|
onclick="jQuery(\'#' . $modalName . ' iframe\').contents().find(\'#applyBtn\').click();">'
|
|
. Text::_('JAPPLY') . '</button>',
|
|
];
|
|
|
|
return HTMLHelper::_('bootstrap.renderModal', $modalName, $options);
|
|
}
|
|
|
|
/**
|
|
* Prepares the given rules list.
|
|
*
|
|
* @param array $list
|
|
*
|
|
* @return array
|
|
*/
|
|
public static function prepareXmlRulesList($list)
|
|
{
|
|
if (is_array($list))
|
|
{
|
|
$list = implode(',', array_map('trim', $list));
|
|
}
|
|
else if (is_string($list))
|
|
{
|
|
$list = str_replace(' ', '', $list);
|
|
}
|
|
|
|
return $list;
|
|
}
|
|
|
|
/**
|
|
* Adds a new condition item or group.
|
|
*
|
|
* @param string $controlGroup The name of the input used to store the data.
|
|
* @param string $groupKey The group index ID.
|
|
* @param string $conditionKey The added condition item index ID.
|
|
* @param array $condition The condition name we are adding.
|
|
* @param string $include_rules The list of included conditions that override the available conditions.
|
|
* @param string $exclude_rules The list of excluded conditions that override the available conditions.
|
|
* @param bool $exclude_rules_pro Whether the excluded rules should appear as Pro missing features.
|
|
*
|
|
* @return string
|
|
*/
|
|
public static function add($controlGroup, $groupKey, $conditionKey, $condition = null, $include_rules = [], $exclude_rules = [], $exclude_rules_pro = false)
|
|
{
|
|
$controlGroup_ = $controlGroup . "[$groupKey][rules][$conditionKey]"; // @Todo - rename input namespace to 'conditions'
|
|
$form = self::getForm('conditionbuilder/base.xml', $controlGroup_, $condition);
|
|
$form->setFieldAttribute('name', 'include_rules', is_array($include_rules) ? implode(',', $include_rules) : $include_rules);
|
|
$form->setFieldAttribute('name', 'exclude_rules', is_array($exclude_rules) ? implode(',', $exclude_rules) : $exclude_rules);
|
|
$form->setFieldAttribute('name', 'exclude_rules_pro', $exclude_rules_pro);
|
|
|
|
$options = [
|
|
'name' => $controlGroup_,
|
|
'enabled' => !isset($condition['enabled']) ? true : (string) $condition['enabled'] == '1',
|
|
'toolbar' => $form,
|
|
'groupKey' => $groupKey,
|
|
'conditionKey' => $conditionKey,
|
|
'options' => ''
|
|
];
|
|
|
|
if (isset($condition['name']))
|
|
{
|
|
$optionsHTML = self::renderOptions($condition['name'], $controlGroup_, $condition);
|
|
$options['condition_name'] = $condition['name'];
|
|
$options['options'] = $optionsHTML;
|
|
}
|
|
|
|
return self::getLayout('conditionbuilder_row', $options);
|
|
}
|
|
|
|
/**
|
|
* Render condition item settings.
|
|
*
|
|
* @param string $name The name of the condition item.
|
|
* @param string $controlGroup The name of the input used to store the data.
|
|
* @param object $formData The data that will be bound to the form.
|
|
*
|
|
* @return string
|
|
*/
|
|
public static function renderOptions($name, $controlGroup = null, $formData = null)
|
|
{
|
|
if (!$form = self::getForm('conditions/' . strtolower(str_replace('\\', '/', $name)) . '.xml', $controlGroup, $formData))
|
|
{
|
|
return;
|
|
}
|
|
|
|
$form->setFieldAttribute('note', 'ruleName', $name);
|
|
|
|
return $form->renderFieldset('general');
|
|
}
|
|
|
|
/**
|
|
* Handles loading condition builder given a payload.
|
|
*
|
|
* @param array $payload
|
|
*
|
|
* @return string
|
|
*/
|
|
public static function initLoad($payload = [])
|
|
{
|
|
if (!$payload)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!isset($payload['data']) &&
|
|
!isset($payload['name']))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!$data = json_decode($payload['data']))
|
|
{
|
|
return;
|
|
}
|
|
|
|
// transform object to assosiative array
|
|
$data = json_decode(json_encode($data), true);
|
|
|
|
// html of condition builder
|
|
$html = '';
|
|
|
|
$include_rules = isset($payload['include_rules']) ? $payload['include_rules'] : [];
|
|
$exclude_rules = isset($payload['exclude_rules']) ? $payload['exclude_rules'] : [];
|
|
$exclude_rules_pro = isset($payload['exclude_rules_pro']) ? $payload['exclude_rules_pro'] : false;
|
|
|
|
foreach ($data as $groupKey => $groupConditions)
|
|
{
|
|
$payload = [
|
|
'name' => $payload['name'],
|
|
'groupKey' => $groupKey,
|
|
'groupConditions' => $groupConditions,
|
|
'include_rules' => $include_rules,
|
|
'exclude_rules' => $exclude_rules,
|
|
'exclude_rules_pro' => $exclude_rules_pro
|
|
];
|
|
|
|
$html .= self::getLayout('conditionbuilder_group', $payload);
|
|
|
|
}
|
|
|
|
return $html;
|
|
}
|
|
|
|
/**
|
|
* Render a layout given its name and payload.
|
|
*
|
|
* @param string $name
|
|
* @param array $payload
|
|
*
|
|
* @return string
|
|
*/
|
|
public static function getLayout($name, $payload)
|
|
{
|
|
return LayoutHelper::render($name, $payload, JPATH_PLUGINS . '/system/nrframework/layouts');
|
|
}
|
|
|
|
/**
|
|
* Returns the form by binding given data.
|
|
*
|
|
* @param string $name
|
|
* @param string $controlGroup
|
|
* @param array $data
|
|
*
|
|
* @return object
|
|
*/
|
|
private static function getForm($name, $controlGroup, $data = null)
|
|
{
|
|
if (!file_exists(JPATH_PLUGINS . '/system/nrframework/xml/' . $name))
|
|
{
|
|
return;
|
|
}
|
|
|
|
$form = new Form('cb', ['control' => $controlGroup]);
|
|
|
|
$form->addFieldPath(JPATH_PLUGINS . '/system/nrframework/fields');
|
|
$form->loadFile(JPATH_PLUGINS . '/system/nrframework/xml/' . $name);
|
|
|
|
if (!is_null($data))
|
|
{
|
|
$form->bind($data);
|
|
}
|
|
|
|
return $form;
|
|
}
|
|
} |