acf
This commit is contained in:
		| @ -0,0 +1,393 @@ | ||||
| <?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; | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user