<?php
  /**
   * @version     1.0.1
   * @package     Joomla
   * @subpackage  Formea
   * @author      Feseur Sdn Bhd
   * @copyright   Copyright (C) 2010 - 2024 Feseur Sdn Bhd
   * @license     GNU/GPL, see LICENSE.php
   */


  defined('_JEXEC') or die();

  // no direct access
  use Feseur\Library\FsrResponse;
  use Joomla\CMS\Factory;
  use Joomla\CMS\Filesystem\File;
  use Joomla\CMS\Language\Text;
  use Joomla\CMS\WebAsset\WebAssetManager;
  use Joomla\Component\Formea\Administrator\Helper\FormeaHelper;
  use Joomla\Component\Formea\Site\Helper\FormeaGeneralHelper;
  use Joomla\Component\Formea\Site\Libraries\FormeaCore;
  use Joomla\Component\Formea\Site\Libraries\FormeaElement;
  use Joomla\Component\Formea\Site\Libraries\FormeaForm;
  use Joomla\Component\Formea\Site\Libraries\FormeaGridItem;
  use Joomla\Database\DatabaseDriver;

  class FormeaConditionals extends FormeaCore
  {
    private $calculationPath;
    private $core;


    public function __construct($config)
    {
      parent::__construct($config);
      $this->calculationPath = JPATH_ROOT . '/components/com_formea/plugins/core/Conditionals/';
      $app = Factory::getApplication();
      /** @var WebAssetManager $wa */
      $wa = $app->getDocument()->getWebAssetManager();
      $registry = $wa->getRegistry();
      $registry->addRegistryFile('components/com_formea/plugins/core/Conditionals/joomla.asset.json');
    }

    public function drawPageElementAttribute($formId, $currentIdx, $totalPages)
    {
      $pageAttributes = [];
      $pageClass = ['content', 'multipage_' . $this->formUniqueString . '_' . $currentIdx];
      $pageAttributes['role'] = 'tabpanel';
      $pageAttributes['aria-labelledby'] = 'fm_pg_' . $this->formUniqueString . '_' . $currentIdx . '_trigger';

      return [
        'pageAttributes' => $pageAttributes,
        'pageClass' => $pageClass,
      ];
    }

    protected function getCore()
    {
      if (empty($this->core)) {
        $core = FormeaGeneralHelper::getCoreExtension($this->id);
        if (!empty($core)) {
          $params = $core->params;
          if ($this->styleId > 0) {
            $style = FormeaGeneralHelper::getExtensionStyle($this->styleId);
            if (!empty($style)) {
              $params = $style->params;
            }
          }
          $core->params = new Joomla\Registry\Registry($params);
        }
        $this->core = $core;
      }

      return $this->core;
    }

    public function getGeneratedScript()
    {
      $script = '';
      //$expressions = $this->formParams->get('expressions');
      $enabled = (int)$this->formParams->get('enabled', 0);
      if ($enabled > 0) {
        $script .= ' document.addEventListener("DOMContentLoaded",function(){ ';
        $script .= " formeaCoreConditionalFields('#formea_form_" . $this->formUniqueString . "',{";
        $script .= "rules: 'inline', dynamic: true,});";
        $script .= '});';
      }

      return $script;
    }

    public function getLoadableScript()
    {
      return [
        "site.formea-conditionals.js"
      ];
    }

    public function getLoadableStyle()
    {
      return [
      ];
    }

    public function getElementInfo($config = [])
    {
      $elements = [];
      $availableFields = [];
      if (isset($config['element'])) {
        $elements = $config['element'];

        $elementIds = [];
        $groupIds = [];
        $totalElement = count($elements);
        for ($i = 0; $i < $totalElement; $i++) {
          if ((int)$elements[$i]['item_type'] == 2) {
            $elementIds[] = (int)$elements[$i]['id'];
          } elseif ((int)$elements[$i]['item_type'] == 3) {
            $groupIds[] = (int)$elements[$i]['group_id'];
          }
        }
        if (empty($groupIds)) {
          $groupIds[] = -100;
        }
        if (empty($elementIds)) {
          $elementIds[] = -100;
        }
        //var_dump($elementIds);die;
        $container = Factory::getContainer();
        /** @var \Joomla\Database\DatabaseDriver $db */
        $db = $container->get('DatabaseDriver');
        $query = $db->getQuery(true);
        $elementColumn = [
          'a.id AS id',
          'a.id AS element_id',
          'a.type',
          'a.title',
          'a.alias',
          'a.state',
          'b.title AS elementTypeTitle',
          'b.value_type',
          'b.id AS eltype_id',
          '0 AS isGroup',
          '0 AS group_id',
          'a.created_date',
        ];
        $query->clear();
        $query->select($elementColumn);
        //TODO:no need form, get direct from unatored e
        $query->from($db->quoteName('#__formea_elements', 'a'))->innerJoin(
          $db->quoteName('#__formea_eltypes', 'b') . ' ON ' . $db->quoteName('a.type') . ' = ' .
          $db->quoteName('b.name')
        );
        //$query->where($db->quoteName('b.value_type') . ' > ' . $db->quote(-1));
        $query->where($db->quoteName('a.id') . ' IN (' . implode(',', $elementIds) . ')');

        $groupedText = Text::_('COM_FORMEA_GROUPED_ELEMENTS');

        $groupColumns = [
          'a.id AS id',
          '-1 AS element_id',
          '\'' . $groupedText . '\' AS type',
          'a.title',
          'a.alias',
          'a.state',
          '\'' . $groupedText . '\' AS elementTypeTitle',
          '-1 AS value_type',
          '-1 AS eltype_id',
          '1 AS isGroup',
          'a.id AS group_id',
          'a.created_date',
        ];
        $qroupQuery = $db->getQuery(true);
        $qroupQuery->select($groupColumns);
        $qroupQuery->from($db->quoteName('#__formea_groups', 'a'));
        $qroupQuery->where($db->quoteName('a.id') . ' IN (' . implode(',', $groupIds) . ')');

        $query->unionAll($qroupQuery);

        $query->order('created_date ASC');
        $db->setQuery($query);
        $elements = $db->loadObjectList();

        $totalElements = count($elements);
        for ($i = 0; $i < $totalElements; $i++) {
          $values = [];
          if ($elements[$i]->isGroup == 0) {
            $formeaElement = new FormeaElement([
              'element_id' => $elements[$i]->element_id,
              'isPreview' => true
            ]);
            $_values = $formeaElement->getValues(true, true);
            if (!empty($_values)) {
              foreach ($_values as $langCode => $val) {
                if (in_array($elements[$i]->value_type, [1, 2])) {
                  foreach ($val['option_lists'] as $optionVal) {
                    if (!empty($optionVal->val)) {
                      $values[] = $optionVal->val;
                    }
                  }
                } else {
                  if (!empty($val['defval'])) {
                    $values[] = $val['defval'];
                  }
                }
              }
            }
          }
          $availableFields[] = [
            'id' => $elements[$i]->id,
            'text' => $elements[$i]->title,
            'val' => '[' . $elements[$i]->alias . ']',
            'value_type' => $elements[$i]->value_type,
            'element_type' => $elements[$i]->elementTypeTitle,
            'item_type' => ($elements[$i]->isGroup > 0) ? 3 : 2,
            'selected' => false,
            'suggestions' => $values
          ];
        }
      }

      return [
        'availableFields' => $availableFields
      ];
    }

    public function initFormEdit($config = [])
    {

      $app = Factory::getApplication();
      $lang = $app->getLanguage();
      $langTag = $lang->getTag();
      $container = Factory::getContainer();
      /** @var DatabaseDriver $db */
      $db = $container->get('DatabaseDriver');
      $query = $db->getQuery(true);

      if (\Joomla\CMS\Filesystem\Folder::exists(FORMEA_CORE_PATH . '/Conditionals/language/' . $langTag)) {
        $langStringIni = parse_ini_file(FORMEA_CORE_PATH . '/Conditionals/language/' . $langTag . '/Conditionals.ini');
        $lang->load('Conditionals', FORMEA_CORE_PATH . '/Conditionals', $langTag);
      } else {
        $langStringIni = parse_ini_file(FORMEA_CORE_PATH . '/Conditionals/language/en-GB/Conditionals.ini');
        $lang->load('Conditionals', FORMEA_CORE_PATH . '/Conditionals', 'en-GB');
      }

//      $intro = Text::_('CONDITIONALS_FORMEA_FORM_EDIT_INTRO');
      $intro = '';
      $elements = [];
      $conditionLists = [];
      $expressionLists = [];
      if ($this->formId > 0) {
        $elementColumn = [
          'c.id AS id',
          'c.id AS element_id',
          'a.type',
          'a.title',
          'c.alias',
          'c.state',
          'b.title AS elementTypeTitle',
          'b.value_type',
          'c.id AS eltype_id',
          '0 AS isGroup',
          '0 AS group_id',
          'c.created_date',
        ];
        $query->clear();
        $query->select($elementColumn);
        $query->from($db->quoteName('#__formea_form_elements', 'a'))->innerJoin(
          $db->quoteName('#__formea_eltypes', 'b') . ' ON ' . $db->quoteName('a.type') . ' = ' .
          $db->quoteName('b.name')
        )->innerJoin(
          $db->quoteName('#__formea_elements', 'c') . ' ON ' . $db->quoteName('a.element_id') . ' = ' .
          $db->quoteName('c.id')
        );
        $query->where($db->quoteName('a.form_id') . ' = ' . $db->quote($this->formId));
        $query->where($db->quoteName('a.group_id') . ' = ' . $db->quote(0));
        $query->where($db->quoteName('b.value_type') . ' > ' . $db->quote(-2));

        $groupedText = Text::_('COM_FORMEA_GROUPED_ELEMENTS');

        $groupColumns = [
          'b.id AS id',
          '-1 AS element_id',
          '\'' . $groupedText . '\' AS type',
          'b.title',
          'b.alias',
          'b.state',
          '\'' . $groupedText . '\' AS elementTypeTitle',
          '-1 AS value_type',
          '-1 AS eltype_id',
          '1 AS isGroup',
          'b.id AS group_id',
          'b.created_date',
        ];
        $qroupQuery = $db->getQuery(true);
        $qroupQuery->select($groupColumns);
        $qroupQuery->from($db->quoteName('#__formea_form_groups', 'a'))->innerJoin(
          $db->quoteName('#__formea_groups', 'b') . ' ON ' .
          $db->quoteName('a.group_id') . ' = ' . $db->quoteName('b.id')
        )->where($db->quoteName('a.form_id') . ' = ' . $db->quote($this->formId))
          ->where($db->quoteName('a.group_type') . ' = ' . $db->quote(0));

        $query->unionAll($qroupQuery);

        $query->order('created_date ASC');
        $db->setQuery($query);
        $elements = $db->loadObjectList();

        //get expression
        $query->clear();

        $query->select('*');
        $query->from($db->quoteName('#__formea_form_cores'));
        $query->where($db->quoteName('form_id') . ' = ' . $db->quote($this->formId));
        $query->where($db->quoteName('corename') . ' = ' . $db->quote('Conditionals'));
        $db->setQuery($query);
        $coreForm = $db->loadObject();
        if (!empty($coreForm)) {
          $params = new \Joomla\Registry\Registry($coreForm->params);
          $calcParams = $params->get('rules');

          if (!empty($calcParams)) {

            $conditionLists = json_decode($calcParams);
          }
        }

      }

      $availableFields = [];
      $totalElements = count($elements);
      for ($i = 0; $i < $totalElements; $i++) {
        $values = [];
        if ($elements[$i]->isGroup == 0) {
          $formeaElement = new FormeaElement([
            'element_id' => $elements[$i]->element_id,
            'isPreview' => true
          ]);
          $_values = $formeaElement->getValues(true, true);
          if (!empty($_values)) {
            foreach ($_values as $langCode => $val) {
              if (in_array($elements[$i]->value_type, [1, 2])) {
                foreach ($val['option_lists'] as $optionVal) {
                  if (!empty($optionVal->val)) {
                    $values[] = $optionVal->val;
                  }
                }
              } else {
                if (!empty($val['defval'])) {
                  $values[] = $val['defval'];
                }
              }
            }
          }
        }
        $availableFields[] = [
          'element_id' => $elements[$i]->element_id,
          'id' => $elements[$i]->id,
          'text' => $elements[$i]->title,
          'val' => '[' . $elements[$i]->alias . ']',
          'value_type' => $elements[$i]->value_type,
          'element_type' => $elements[$i]->elementTypeTitle,
          'item_type' => ($elements[$i]->isGroup > 0) ? 3 : 2,
          'selected' => false,
          'suggestions' => $values
        ];
      }


      $totalConditionLists = count($conditionLists);
      for ($j = 0; $j < $totalConditionLists; $j++) {
        $tempAvailableFields = json_decode(json_encode($availableFields));

        $totalReadyFields = count($conditionLists[$j]->fields);
        for ($l = 0; $l < $totalReadyFields; $l++) {
          $filteredField = $this->_findReadyElement($tempAvailableFields, $conditionLists[$j]->fields[$l]->id, $conditionLists[$j]->fields[$l]->item_type);
          if (!empty($filteredField)) {
            foreach ($filteredField as $_field) {
              $_field->selected = true;
            }
          }

        }

        $conditionLists[$j]->availableFields = $tempAvailableFields;
        $conditionLists[$j]->availableFieldOpen = false;
        $conditionLists[$j]->availableFieldClosing = false;
        $totalRules = count($conditionLists[$j]->rules);
        for ($k = 0; $k < $totalRules; $k++) {
          $conditionLists[$j]->rules[$k]->availableFields = $availableFields;
          $conditionLists[$j]->rules[$k]->valOpen = false;
          $conditionLists[$j]->rules[$k]->valClosing = false;
        }
      }
      $actionLists = [
        [
          'text' => Text::_('CONDITIONALS_FORMEA_SHOW'),
          'val' => 'show',
          'selected' => false
        ],
        [
          'text' => Text::_('CONDITIONALS_FORMEA_HIDE'),
          'val' => 'hide',
          'selected' => false
        ],
        [
          'text' => Text::_('CONDITIONALS_FORMEA_ENABLE'),
          'val' => 'enable',
          'selected' => false
        ],
        [
          'text' => Text::_('CONDITIONALS_FORMEA_DISABLE'),
          'val' => 'disable',
          'selected' => false
        ],
      ];

      $logicLists = [
        [
          'text' => Text::_('CONDITIONALS_FORMEA_LOGIC_OR_DESC'),
          'val' => 'or',
          'selected' => false
        ],
        [
          'text' => Text::_('CONDITIONALS_FORMEA_LOGIC_AND_DESC'),
          'val' => 'and',
          'selected' => false
        ],
      ];

      $operatorLists = [
        ['text' => Text::_('CONDITIONAL_FORMEA_IS'), 'val' => 'is', 'selected' => false],
        ['text' => Text::_('CONDITIONAL_FORMEA_ISNOT'), 'val' => 'isnot', 'selected' => false],
        ['text' => Text::_('CONDITIONAL_FORMEA_GREATERTHAN'), 'val' => 'greaterthan', 'selected' => false],
        ['text' => Text::_('CONDITIONAL_FORMEA_LESSTHAN'), 'val' => 'lessthan', 'selected' => false],
        ['text' => Text::_('CONDITIONAL_FORMEA_CONTAINS'), 'val' => 'contains', 'selected' => false],
        ['text' => Text::_('CONDITIONAL_FORMEA_DOESNOTCONTAIN'), 'val' => 'doesnotcontain', 'selected' => false],
        ['text' => Text::_('CONDITIONAL_FORMEA_BEGINSWITH'), 'val' => 'beginswith', 'selected' => false],
        ['text' => Text::_('CONDITIONAL_FORMEA_DOESNOTBEGINWITH'), 'val' => 'doesnotbeginwith', 'selected' => false],
        ['text' => Text::_('CONDITIONAL_FORMEA_ENDSWITH'), 'val' => 'endswith', 'selected' => false],
        ['text' => Text::_('CONDITIONAL_FORMEA_DOESNOTENDWITH'), 'val' => 'doesnotendwith', 'selected' => false],
        ['text' => Text::_('CONDITIONAL_FORMEA_ISEMPTY'), 'val' => 'isempty', 'selected' => false],
        ['text' => Text::_('CONDITIONAL_FORMEA_ISNOTEMPTY'), 'val' => 'isnotempty', 'selected' => false]
      ];


      $ret = [
        'conditionLists' => $conditionLists,
        'langString' => $langStringIni,
        'availableFields' => $availableFields,
        'actionLists' => $actionLists,
        'logicLists' => $logicLists,
        'operatorLists' => $operatorLists,
        'intro' => $intro,
      ];

      return $ret;
    }

    private function _findReadyElement($elements, $targetId, $targetItemType)
    {
      $filteredObjects = array_filter($elements, function ($object) use ($targetId, $targetItemType) {
        return $object->id === $targetId && $object->item_type === $targetItemType;
      });

      return $filteredObjects;
    }

    /**
     * @param FormeaElement $element
     *
     *
     * @since version
     */
    public function getInputAttributes($element)
    {

      $enabled = (int)$this->formParams->get('enabled', 0);
      $attributes = [];

      if ($enabled > 0) {
        $conditionLists = $this->formParams->get('rules');

        if (!empty($conditionLists)) {
          $conditionLists = json_decode($conditionLists);
          $totalConditions = 0;
          if (is_array($conditionLists)) {
            $totalConditions = count($conditionLists);
          }

          //lets find if this element should have a rule
          for ($i = 0; $i < $totalConditions; $i++) {

            $item_type = 2;
            if ($element->isGroup) {
              $item_type = 3;
            }
            $filteredObject = $this->_findReadyElement($conditionLists[$i]->fields, $element->id, $item_type);

            if (!empty($filteredObject)) {

              $_rules = [];
              $totalRules = count($conditionLists[$i]->rules);
              for ($j = 0; $j < $totalRules; $j++) {
                $isGroup = false;
                $group_id = 0;
                if ((int)$conditionLists[$i]->rules[$j]->field->item_type == 3) {
                  $isGroup = true;
                  $group_id = $conditionLists[$i]->rules[$j]->field->id;
                }
                $_element = new FormeaElement([
                  'isGroup' => $isGroup,
                  'group_id' => $group_id,
                  'element_id' => $conditionLists[$i]->rules[$j]->field->id
                ]);
                $_rules[] = [
                  'name' => $_element->getElementFormattedName(),
                  'operator' => $conditionLists[$i]->rules[$j]->operator,
                  'value' => $conditionLists[$i]->rules[$j]->value
                ];
              }
              $conditionRule = $this->_formatRules($conditionLists[$i]->action, $_rules, $conditionLists[$i]->logic,
                '.fm_element_' . $this->formId . '_' . $element->id);
              if (!empty($conditionRule)) {
                $attributes['data-formea-conditional-rules'] = htmlspecialchars($conditionRule);
              }
            }
          }

        }

      }

      return $attributes;

    }

    /**
     * @param FormeaGridItem $gridItem
     *
     * @return array
     *
     * @since version
     */
    public function getInputGroupContainerAttributes($gridItem)
    {
      $enabled = (int)$this->formParams->get('enabled', 0);
      $attributes = [];

      if ($enabled > 0) {
        $conditionLists = $this->formParams->get('rules');
        if (!empty($conditionLists)) {
          $conditionLists = json_decode($conditionLists);
          $totalConditions = count($conditionLists);

          //lets find if this element should have a rule
          for ($i = 0; $i < $totalConditions; $i++) {

            $item_type = 2;
            if ($gridItem->isGroup) {
              $item_type = 3;
            }
            $filteredObject = $this->_findReadyElement($conditionLists[$i]->fields, $gridItem->group_id, $item_type);
            if (!empty($filteredObject)) {
              $_rules = [];
              $totalRules = count($conditionLists[$i]->rules);
              for ($j = 0; $j < $totalRules; $j++) {
                $isGroup = false;
                $group_id = 0;
                if ((int)$conditionLists[$i]->rules[$j]->field->item_type == 3) {
                  $isGroup = true;
                  $group_id = $conditionLists[$i]->rules[$j]->field->id;
                }
                $_element = new FormeaElement([
                  'isGroup' => $isGroup,
                  'group_id' => $group_id,
                  'element_id' => $conditionLists[$i]->rules[$j]->field->id
                ]);
                $_rules[] = [
                  'name' => $_element->getElementFormattedName(),
                  'operator' => $conditionLists[$i]->rules[$j]->operator,
                  'value' => $conditionLists[$i]->rules[$j]->value
                ];
              }
              $conditionRule = $this->_formatRules($conditionLists[$i]->action, $_rules, $conditionLists[$i]->logic,
                '.fm_grouped_element_' . $this->formId . '_' . $gridItem->id);
              if (!empty($conditionRule)) {
                $attributes['data-formea-conditional-rules'] = htmlspecialchars($conditionRule);
              }
            }
          }
        }
      }

      return $attributes;
    }

    private function _formatRules($action, $rules, $logic = 'or', $container = '.default-field-container')
    {
      return json_encode(array(
        'container' => $container,
        'action' => $action,
        'logic' => $logic,
        'rules' => $rules,
      ));
    }

    public function checkElementBeforeSubmissions($elements)
    {
      $enabled = (int)$this->formParams->get('enabled', 0);
      if ($enabled > 0) {
        $conditionLists = $this->formParams->get('rules');
        if (!empty($conditionLists)) {
          $conditionLists = json_decode($conditionLists);
          $totalElements = count($elements);
          for ($i = 0; $i < $totalElements; $i++) {
            $elements[$i] = $this->_checkElementBeforeSubmission($elements[$i], $elements, $conditionLists);
          }
        }
      }
      return $elements;
    }

    private function _checkElementBeforeSubmission($element, $elements, $conditionLists)
    {
      $totalConditions = count($conditionLists);

      //lets find if this element should have a rule
      for ($i = 0; $i < $totalConditions; $i++) {

        $item_type = 2;
        if ((int)$element->group_id > 0) {
          $item_type = 3;
        }
        $filteredObject = $this->_findReadyElement($conditionLists[$i]->fields, $element->group_id, $item_type);
        if (!empty($filteredObject)) {

          $_rules = [];
          $totalRules = count($conditionLists[$i]->rules);
          $isConditionMet = false;
          $logic = $conditionLists[$i]->logic;
          $action = $conditionLists[$i]->action;
          for ($j = 0; $j < $totalRules; $j++) {
            $isGroup = false;
            $group_id = 0;
            if ((int)$conditionLists[$i]->rules[$j]->field->item_type == 3) {
              $isGroup = true;
              $group_id = $conditionLists[$i]->rules[$j]->field->id;
            }
            $isRuleMet = false;
            $elementConfig = [
              'isGroup' => $isGroup,
              'group_id' => $group_id,
              'element_id' => $conditionLists[$i]->rules[$j]->field->id
            ];
            $_element = new FormeaElement($elementConfig);
            $elementConfig['alias'] = $_element->alias;
            $rule = [
              'name' => $_element->getElementFormattedName(),
              'operator' => $conditionLists[$i]->rules[$j]->operator,
              'value' => $conditionLists[$i]->rules[$j]->value
            ];

            $isRuleMet = $this->_evaluateRule($rule, $elementConfig, $elements);
            $_rules[] = $rule;
            if ($isRuleMet === false && 'and' == $logic) {
              $isConditionMet = false;
              break;
            } else if ($isRuleMet && 'or' == $logic) {
              $isConditionMet = true;
              break;
            }
            $isConditionMet = $isRuleMet;
          }
          if (!$isConditionMet) {
            $element->byPassValidation = true;
          }
        }
      }

      return $element;
    }

    private function _evaluateRule($rule, $elementConfig, $elements)
    {
      $name = $rule['name'];
      $operator = $rule['operator'];
      $value = $rule['value'];
      $element = $this->_getElementByGroupIdAndAlias($elements, (int)$elementConfig['group_id'], $elementConfig['element_id']);
      if (!empty($element)) {
        $element = array_values($element);
        if (isset($element[0])) {
          $triggerValue = '';
          if (is_array($element[0]->submitted_value)) {
            $triggerValue = implode('|', $element[0]->submitted_value);
          } else {
            $triggerValue = $element[0]->submitted_value;
          }
          return $this->compareValues($operator, $triggerValue, $value);
        }
      }
      return false;
    }

    private function compareValues($operator, $triggerValue, $value)
    {
      $searchVal = strtolower($triggerValue);
      $targetVal = strtolower($value);
      switch ($operator) {
        case "is":
          return $targetVal === $searchVal;
        case "isnot":
          return $targetVal !== $searchVal;
        case "greaterthan":
          return is_numeric($searchVal) && is_numeric($targetVal) ? (float)$searchVal > (float)$targetVal : false;
        case "lessthan":
          return is_numeric($searchVal) && is_numeric($targetVal) ? (float)$searchVal < (float)$targetVal : false;
        case "contains":
          return strpos($searchVal, $targetVal) !== false;
        case "doesnotcontain":
          return strpos($searchVal, $targetVal) === false;
        case "beginswith":
          return strpos($searchVal, $targetVal) === 0;
        case "doesnotbeginwith":
          return strpos($searchVal, $targetVal) !== 0;
        case "endswith":
          $length = strlen($targetVal);
          if ($length == 0) return true; // An empty string always ends with itself.
          return substr($searchVal, -$length) === $targetVal;
        case "doesnotendwith":
          $length = strlen($targetVal);
          if ($length == 0) return false; // An empty string always ends with itself.
          return substr($searchVal, -$length) !== $targetVal;
        case "isempty":
          return $searchVal === "";
        case "isnotempty":
          return $searchVal !== "";
        default:
          return false;
      }

    }


    /**
     * @param $elements
     * @param $targetGroupId
     * @param $targetName
     *
     * @return array
     *
     * @since version
     */
    private function _getElementByGroupIdAndAlias($elements, $targetGroupId, $element_id)
    {
      $filteredObjects = array_filter($elements, function ($object) use ($targetGroupId, $element_id) {
        return $object->group_id === $targetGroupId && $object->element_id === $element_id;
      });

      return $filteredObjects;
    }

  }
