Server IP : 80.87.202.40 / Your IP : 216.73.216.169 Web Server : Apache System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64 User : bitrix ( 600) PHP Version : 8.2.27 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/main/lib/ui/filter/ |
Upload File : |
<?php namespace Bitrix\Main\UI\Filter; use Bitrix\Main\Application; use Bitrix\Main\Context; use Bitrix\Main\HttpRequest; use Bitrix\Main\Type\Date; use Bitrix\Main\UI\Filter; /** * Class Options of main.ui.filter * @package Bitrix\Main\UI\Filter */ class Options { const DEFAULT_FILTER = "default_filter"; const TMP_FILTER = "tmp_filter"; protected $id; protected $options; protected $commonPresets; protected $useCommonPresets; protected $commonPresetsId; protected $request; protected ?string $currentFilterPresetId = null; /** * Options constructor. * @param string $filterId $arParams["FILTER_ID"] * @param array $filterPresets $arParams["FILTER_PRESETS"] * @param string $commonPresetsId $arParams["COMMON_PRESETS_ID"] Set if you want to use common presets */ public function __construct($filterId, $filterPresets = [], $commonPresetsId = null) { $this->id = $filterId; $this->options = $this->fetchOptions($this->id); $this->useCommonPresets = false; if (!empty($commonPresetsId) && is_string($commonPresetsId)) { $this->commonPresets = static::fetchCommonPresets($commonPresetsId); $this->useCommonPresets = true; $this->commonPresetsId = $commonPresetsId; $this->options["filters"] = $this->commonPresets["filters"] ?? null; $this->options["deleted_presets"] = $this->commonPresets["deleted_presets"] ?? null; } if (!isset($this->options["use_pin_preset"])) { $this->options["use_pin_preset"] = true; } if (!isset($this->options["deleted_presets"]) || !is_array($this->options["deleted_presets"])) { $this->options["deleted_presets"] = []; } if (!empty($filterPresets) && is_array($filterPresets)) { $this->options["default_presets"] = $filterPresets; } else { $this->options["default_presets"] = []; } if (!isset($this->options["default"]) || empty($this->options["default"]) || ($this->options["default"] === self::DEFAULT_FILTER && $this->options["use_pin_preset"])) { $this->options["default"] = self::findDefaultPresetId($this->options["default_presets"]); } if (!isset($this->options["filter"]) || empty($this->options["filter"]) || !is_string($this->options["filter"])) { $this->options["filter"] = $this->options["default"]; } if (!isset($this->options["filters"]) || !is_array($this->options["filters"])) { $this->options["filters"] = $this->options["default_presets"]; } // Move additional fields from options to session if (is_array($this->options["filters"])) { foreach ($this->options["filters"] as $presetId => $options) { if (isset($options["additional"]) && is_array($options["additional"])) { $this->setAdditionalPresetFields($presetId, $options["additional"]); unset($this->options["filters"][$presetId]["additional"]); } } } if (!empty($this->options["update_default_presets"]) && !empty($filterPresets) && is_array($filterPresets)) { $this->options["update_default_presets"] = false; $sort = 0; foreach ($filterPresets as $key => $defaultPreset) { $this->options["filters"][$key] = $defaultPreset; $this->options["filters"][$key]["sort"] = $sort; $sort++; } foreach ($this->options["filters"] as $key => $preset) { if (!array_key_exists($key, $filterPresets)) { $this->options["filters"][$key]["sort"] = $sort; $sort++; } } } } /** * @return string */ public function getCommonPresetsId() { return $this->commonPresetsId; } /** * @return bool */ public function isUseCommonPresets() { return $this->useCommonPresets; } /** * Gets filter id * @return string */ public function getId() { return $this->id; } /** * Sets filter presets * @param array $presets */ public function setPresets($presets = []) { $this->options["filters"] = $presets; } /** * Sets current preset id * @param string $presetId */ public function setCurrentPreset($presetId = "default_filter") { $this->options["filter"] = $presetId; } /** * Gets default presets from filter options * @return array|null */ public function getDefaultPresets() { return $this->options["default_presets"]; } /** * Gets presets * @return array|null */ public function getPresets() { return $this->options["filters"]; } /** * Sets default preset id * @param string $presetId */ public function setDefaultPreset($presetId = "default_filter") { $this->options["default"] = $presetId; } /** * Checks is need use pinned preset * @return bool */ public function isUsePinPreset() { return $this->options["use_pin_preset"]; } /** * Sets default presets * @param array $presets */ public function setDefaultPresets($presets = []) { $this->options["default_presets"] = $presets; } /** * Sets deleted presets array * @param array $deletedPresets */ public function setDeletedPresets($deletedPresets = []) { $this->options["deleted_presets"] = $deletedPresets; } /** * Sets use_pin_preset values * @param boolean $value */ public function setUsePinPreset($value = true) { $this->options["use_pin_preset"] = $value; } /** * Gets common presets from database * @param string $id Common presets id $arParams["COMMON_PRESETS_ID"] * @return array|bool */ public static function fetchCommonPresets($id) { global $USER; $options = \CUserOptions::getOption("main.ui.filter.presets", $id, [], (int)$USER?->getID()); return $options; } /** * Gets filter options from database * @param string $id Filter id $arParams["FILTER_ID"] * @return array|bool */ public function fetchOptions($id) { global $USER; $storage = $this->getStorage(); $userId = (int)$USER?->getID(); if ($userId > 0 || !isset($storage[$this->getId()]["options"])) { $options = []; if ($userId > 0) { $options = \CUserOptions::getOption("main.ui.filter", $id, [], $userId); } if (empty($options)) { $options = \CUserOptions::getOption("main.ui.filter.common", $id, [], 0); } } else { $options = $storage[$this->getId()]["options"]; } return $options; } protected function getRequest() { return Context::getCurrent()->getRequest(); } protected function getStorage() { return Application::getInstance()->getLocalSession('main.ui.filter'); } /** * Finds default preset in presets array * @param array $presets * @return string Default preset id */ public static function findDefaultPresetId($presets = []) { $result = "default_filter"; if (!empty($presets) && is_array($presets)) { foreach ($presets as $presetId => $preset) { if (isset($preset["default"]) && $preset["default"]) { $result = $presetId; } } } return $result; } /** * Gets filter options * @return array */ public function getOptions() { return $this->options; } /** * Makes preset as default * @param string $presetId Preset id */ public function pinPreset($presetId = "default_filter") { if ($presetId === "default_filter") { $this->options["use_pin_preset"] = false; } else { $this->options["use_pin_preset"] = true; } $this->options["default"] = $presetId; } /** * Checks is need whether to set fields from query * @param HttpRequest $request * * @return bool */ public static function isSetFromRequest(HttpRequest $request) { $applyFilter = $request->get("apply_filter"); $isAjaxRequest = $request->get("ajax_request"); return $applyFilter !== null && $isAjaxRequest === null && !$request->isAjaxRequest(); } /** * Fetches field values from request * @param array $fields * @param HttpRequest $request * * @return array|null */ public static function fetchSettingsFromQuery($fields, HttpRequest $request) { $result = ["fields" => [], "rows" => []]; foreach ($fields as $field) { $id = $field["id"]; $fromId = $id . "_from"; $toId = $id . "_to"; $quarterId = $id . "_quarter"; $yearId = $id . "_year"; $monthId = $id . "_month"; $daysId = $id . "_days"; $nameId = $id . "_name"; $labelId = $id . "_label"; $dateselId = $id . "_datesel"; $numselId = $id . "_numsel"; $type = $field["type"] ?? null; $isEmpty = $id . "_isEmpty"; $hasAnyValue = $id . "_hasAnyValue"; if ($type == "date") { if ($request[$dateselId] !== null && ($request[$fromId] !== null || $request[$toId] !== null || $request[$quarterId] !== null || $request[$yearId] !== null || $request[$daysId] !== null || $request[$monthId] !== null)) { $result["fields"][$dateselId] = $request[$dateselId]; $result["fields"][$fromId] = $request[$fromId] !== null ? $request[$fromId] : ""; $result["fields"][$toId] = $request[$toId] !== null ? $request[$toId] : ""; $result["fields"][$yearId] = $request[$yearId] !== null ? $request[$yearId] : ""; $result["fields"][$monthId] = $request[$monthId] !== null ? $request[$monthId] : ""; $result["fields"][$daysId] = $request[$daysId] !== null ? $request[$daysId] : ""; $result["rows"][] = $id; } } else { if ($type == "number") { if ($request[$numselId] !== null && ($request[$fromId] !== null || $request[$toId])) { $result["fields"][$numselId] = $request[$numselId]; $result["fields"][$fromId] = $request[$fromId] !== null ? $request[$fromId] : ""; $result["fields"][$toId] = $request[$toId] !== null ? $request[$toId] : ""; $result["rows"][] = $id; } } else { if ($type == "custom_entity") { if ($request[$id] !== null) { if ($request[$id] !== null || $request[$labelId] !== null) { $result["fields"][$labelId] = ($request[$nameId] !== null ? $request[$nameId] : $request[$labelId]); } $result["fields"][$id] = $request[$id]; $result["rows"][] = $id; } } else { if ($type == "dest_selector" || $type == "entity_selector") { if ($request[$id] !== null) { $result["fields"][$id] = $request[$id]; if (isset($request[$labelId])) { $result["fields"][$labelId] = $request[$labelId]; } $result["rows"][] = $id; } } else { if ($request[$id] !== null) { $result["fields"][$id] = $request[$id]; $result["rows"][] = $id; } } } } } if (isset($request[$isEmpty])) { $result['fields'][$isEmpty] = $request[$isEmpty]; $result["rows"][] = $id; } if (isset($request[$hasAnyValue])) { $result['fields'][$hasAnyValue] = $request[$hasAnyValue]; $result["rows"][] = $id; } } if ($request["FIND"] !== null) { $result["fields"]["FIND"] = $request["FIND"]; } if (empty($result["fields"]) && empty($result["rows"])) { $result = null; } return $result; } /** * Gets session filter * @return mixed */ public function getSessionFilterId() { $storage = $this->getStorage(); return $storage[$this->getId()]["filter"] ?? null; } public function isSetOutside(): bool { $storage = $this->getStorage(); return filter_var( $storage[$this->getId()]["isSetOutside"] ?? false, FILTER_VALIDATE_BOOLEAN ); } /** * Gets additional preset fields * @param string $presetId * @return array */ public function getAdditionalPresetFields($presetId) { $storage = $this->getStorage(); $additional = $storage[$this->getId()]["filters"][$presetId]["additional"] ?? []; return is_array($additional) ? $additional : []; } /** * Sets additional fields * @param string $presetId * @param array $additional */ public function setAdditionalPresetFields($presetId, $additional = []) { $storage = $this->getStorage(); $storage[$this->getId()]["filters"][$presetId]["additional"] = $additional; } /** * Gets default filter * @return mixed */ public function getDefaultFilterId() { return $this->options["default"]; } /** * Gets current applied filter id * @return mixed */ public function getCurrentFilterId() { $sessionFilterId = ($this->getCurrentFilterPresetId() ?? $this->getSessionFilterId()); $defaultFilterId = $this->getDefaultFilterId(); return !empty($sessionFilterId) ? $sessionFilterId : $defaultFilterId; } protected function trySetFilterFromRequest($fields = []) { $request = $this->getRequest(); if (self::isSetFromRequest($request)) { $settings = self::fetchSettingsFromQuery($fields, $this->getRequest()); $clear = strtoupper($request->get("clear_filter")) == "Y"; if ($settings !== null || $clear) { $presetId = $clear ? self::DEFAULT_FILTER : self::TMP_FILTER; $this->setFilterSettings($presetId, $settings); $this->save(); } } } /** * Gets filter settings by preset id * @param $presetId * @return array|null */ public function getFilterSettings($presetId) { return $this->options["filters"][$presetId] ?? null; } /** * Fetches filter fields from filter settings * @param array $filterSettings * @param array $additionalFields * @return array */ protected static function fetchFieldsFromFilterSettings($filterSettings = [], $additionalFields = []) { $filterFields = []; if (is_array($filterSettings)) { if (is_array($filterSettings["fields"])) { $filterFields = $filterSettings["fields"]; } if (is_array($additionalFields)) { $filterFields = array_merge($filterFields, $additionalFields); } } return $filterFields; } /** * @param string $key * @return bool */ public static function isDateField($key = "") { return is_string($key) && str_ends_with($key, "_datesel"); } /** * Fetches date field values * @param string $key * @param array $filterFields * @return array * @throws \Bitrix\Main\ObjectException */ public static function fetchDateFieldValue($key = "", $filterFields = []) { $date = []; $date[$key] = $filterFields[$key]; $cleanKey = str_replace("_datesel", "", $key); self::calcDates($cleanKey, $filterFields, $date); if (!isset($date[$cleanKey . "_from"]) && !isset($date[$cleanKey . "_to"])) { unset($date[$cleanKey . "_datesel"]); unset($date[$cleanKey . "_to"]); unset($date[$cleanKey . "_from"]); } return $date; } /** * Fetches number field values * @param string $key * @param array $filterFields * * @return array */ public static function fetchNumberFieldValue($key = "", $filterFields = []) { $number = []; $number[$key] = $filterFields[$key]; $cleanKey = str_replace("_numsel", "", $key); if (array_key_exists($cleanKey . "_from", $filterFields)) { $number[$cleanKey . "_from"] = $filterFields[$cleanKey . "_from"]; } if (array_key_exists($cleanKey . "_to", $filterFields)) { $number[$cleanKey . "_to"] = $filterFields[$cleanKey . "_to"]; } if ($number[$cleanKey . "_from"] === "" && $number[$cleanKey . "_to"] === "") { unset($number[$cleanKey . "_from"]); unset($number[$cleanKey . "_to"]); unset($number[$cleanKey . "_numsel"]); } return $number; } public static function isNumberField($key = "") { return is_string($key) && str_ends_with($key, "_numsel"); } public static function fetchFieldValuesFromFilterSettings($filterSettings = [], $additionalFields = [], $sourceFields = []) { $filterFields = self::fetchFieldsFromFilterSettings($filterSettings, $additionalFields); $resultFields = []; foreach ($filterFields as $key => $field) { $isStrictField = false; foreach ($sourceFields as $sourceField) { if (isset($sourceField["id"]) && $key === $sourceField["id"] && isset($sourceField["strict"])) { $isStrictField = true; } } if ($field !== "") { if (self::isDateField($key)) { $date = self::fetchDateFieldValue($key, $filterFields); $resultFields = array_merge($resultFields, $date); } elseif (self::isNumberField($key)) { $number = self::fetchNumberFieldValue($key, $filterFields); $resultFields = array_merge($resultFields, $number); } elseif (!str_ends_with($key, "_from") && !str_ends_with($key, "_to")) { if (str_ends_with($key, "_isEmpty")) { $resultFields[substr($key, 0, -8)] = false; } elseif (str_ends_with($key, "_hasAnyValue")) { $resultFields['!' . substr($key, 0, -12)] = false; } else { $resultFields[$key] = $field; } } } } return $resultFields; } /** * @param string $presetId * @return bool */ public static function isDefaultFilter($presetId = "") { return $presetId === self::DEFAULT_FILTER; } /** * Gets current filter values * @param array $sourceFields Filter fields $arParams["FILTER"] * @return array */ public function getFilter($sourceFields = []) { $result = []; $this->trySetFilterFromRequest($sourceFields); $currentPresetId = $this->getCurrentFilterId(); if (!self::isDefaultFilter($currentPresetId)) { $filterSettings = $this->getFilterSettings($currentPresetId); $additionalFields = $this->getAdditionalPresetFields($currentPresetId); $fieldsValues = self::fetchFieldValuesFromFilterSettings($filterSettings, $additionalFields, $sourceFields); $result = $fieldsValues; $searchString = $this->getSearchString(); if (!empty($result) || $searchString !== "") { $result["PRESET_ID"] = $currentPresetId; $result["FILTER_ID"] = $currentPresetId; $result["FILTER_APPLIED"] = true; $result["FIND"] = $searchString; } } return $result; } /** * Gets current filter values that available for DB seach * @param array $sourceFields Filter fields $arParams["FILTER"] * @return array */ public function getFilterLogic($sourceFields = []) { $filter = $this->getFilter($sourceFields); $applied = ($filter["FILTER_APPLIED"] ?? false); if ($applied === true) { return Type::getLogicFilter($filter, $sourceFields); } return []; } /** * Gets filter search string * @return string */ public function getSearchString() { $storage = $this->getStorage(); $search = $storage[$this->id]["filter_search"] ?? ''; return is_string($search) ? $search : ""; } /** * Saves filter optionsGet */ public function save() { global $USER; if ($this->isUseCommonPresets()) { $presets = [ "filters" => $this->options["filters"], "deleted_presets" => $this->options["deleted_presets"], ]; if ($USER->isAuthorized()) { \CUserOptions::setOption("main.ui.filter.presets", $this->getCommonPresetsId(), $presets); } } if ($USER->isAuthorized()) { \CUserOptions::setOption("main.ui.filter", $this->getId(), $this->options); } else { $storage = $this->getStorage(); $storage[$this->getId()]["options"] = $this->options; } } /** * Gets filter options for all users * @return bool|\CDBResult */ public function getAllUserOptions() { return \CUserOptions::getList(null, ["CATEGORY" => "main.ui.filter", "NAME" => $this->getId()]); } /** * @return bool */ public static function isCurrentUserEditOtherSettings() { global $USER; return $USER->CanDoOperation("edit_other_settings"); } /** * Saves filter options for all users */ public function saveForAll() { global $USER; if (self::isCurrentUserEditOtherSettings()) { $allUserOptions = $this->getAllUserOptions(); if ($allUserOptions) { $currentOptions = $this->options; $forAllPresets = []; foreach ($currentOptions["filters"] as $key => $preset) { if ($preset["for_all"]) { $forAllPresets[$key] = $preset; } } while ($userOptions = $allUserOptions->fetch()) { $currentUserOptions = unserialize($userOptions["VALUE"], ['allowed_classes' => false]); if (is_array($currentUserOptions)) { if (!self::isCommon($userOptions)) { $currentUserOptions["deleted_presets"] = $currentOptions["deleted_presets"]; $currentUserOptions["filters"] = $forAllPresets; if (!$USER->CanDoOperation("edit_other_settings", $userOptions["USER_ID"])) { $currentUserOptions["default_presets"] = $forAllPresets; } } $this->saveOptionsForUser($currentUserOptions, $userOptions["USER_ID"]); } } $this->saveCommon(); } } } /** * Checks whether the parameters are common * @param $options * @return bool */ public static function isCommon($options) { return isset($options["USER_ID"]) && $options["USER_ID"] == 0; } /** * Saves options for user with $userId * @param array $options * @param $userId */ public function saveOptionsForUser($options, $userId) { if ($this->isUseCommonPresets()) { $presets = [ "filters" => $options["filters"], "deleted_presets" => $options["deleted_presets"], ]; \CUserOptions::SetOption("main.ui.filter.presets", $this->getCommonPresetsId(), $presets, null, $userId); } $userOptions = \CUserOptions::GetOption("main.ui.filter", $this->getId(), ["filters" => [], "default_presets" => []], $userId); if (is_array($options["deleted_presets"])) { foreach ($options["deleted_presets"] as $key => $isDeleted) { if (array_key_exists($key, $userOptions["filters"])) { unset($userOptions["filters"][$key]); } } } $options["filters"] = array_merge($userOptions["filters"], $options["filters"]); \CUserOptions::SetOption("main.ui.filter", $this->getId(), $options, null, $userId); } /** * Saves current options as common */ public function saveCommon() { $presets = []; $options = $this->getOptions(); foreach ($options["filters"] as $key => $preset) { if ($preset["for_all"]) { $presets[$key] = $preset; } } $options["filters"] = $presets; \CUserOptions::setOption("main.ui.filter.common", $this->id, $options, true); } /** * Sets filter preset rows * @param string $presetId * @param $rows */ public function setFilterRows($presetId, $rows) { $aColsTmp = explode(",", $rows); $aCols = []; foreach ($aColsTmp as $col) { if (($col = trim($col)) <> "") { $aCols[] = $col; } } if ($presetId <> '') { $this->options["filters"][$presetId]["filter_rows"] = implode(",", $aCols); } else { $this->options["filter_rows"] = implode(",", $aCols); } } public function removeRowFromPreset(string $presetId, string $rowName): bool { $rowsString = $this->options["filters"][$presetId]["filter_rows"] ?? ''; if ($rowsString === '') { return false; } $rows = explode(",", $rowsString); $pos = array_search($rowName, $rows, true); if ($pos !== false) { unset($rows[$pos]); $this->options["filters"][$presetId]["filter_rows"] = implode(",", $rows); return true; } return false; } /** * Restores filter options to default * @param array $settings */ public function restore($settings = []) { if (!empty($settings)) { foreach ($settings as $key => $preset) { $this->setFilterSettings($key, $preset, false); if (array_key_exists($key, $this->options["deleted_presets"])) { unset($this->options["deleted_presets"][$key]); } } $this->options["default"] = self::findDefaultPresetId($this->options["default_presets"]); $this->options["use_pin_preset"] = true; $this->options["filter"] = $this->options["default"]; $storage = $this->getStorage(); unset($storage[$this->id]["filter"]); } } /** * @param array $settings */ public function setFilterSettingsArray($settings = []) { if (!empty($settings)) { foreach ($settings as $key => $preset) { if ($key !== "current_preset" && $key !== "common_presets_id") { $this->setFilterSettings($key, $preset, false); } } $this->options["filter"] = $settings["current_preset"]; $request = $this->getRequest(); if ( isset($request["params"]["forAll"]) && ( $request["params"]["forAll"] === "true" || $request["params"]["forAll"] === true ) ) { $this->saveForAll(); } } } /** * @param string $presetId * @param $settings * @param bool $currentPreset * @param bool $useRequest */ public function setFilterSettings($presetId, $settings, $currentPreset = true, $useRequest = true) { if (!empty($presetId)) { $storage = $this->getStorage(); if ($currentPreset) { $request = $this->getRequest(); $params = $request->getPost('params'); $params = is_array($params) ? $params : []; $isApplyFilter = ( ($request->get("apply_filter") == "Y" || $request->get("apply_filter") == "y") || (isset($params["apply_filter"]) && ($params["apply_filter"] == "Y" || $params["apply_filter"] == "y")) ); $isClearFilter = ( ($request->get("clear_filter") == "Y" || $request->get("clear_filter") == "y") || (isset($params["clear_filter"]) && ($params["clear_filter"] == "Y" || $params["clear_filter"] == "y")) ); $isWithPreset = ( ($request->get("with_preset") == "Y" || $request->get("with_preset") == "y") || (isset($params["with_preset"]) && ($params["with_preset"] == "Y" || $params["with_preset"] == "y")) ); $currentPresetId = $this->getCurrentFilterId(); if ( ($useRequest && ($isApplyFilter || $isClearFilter) && (!$isWithPreset || $currentPresetId === static::DEFAULT_FILTER) ) || $useRequest === false ) { $storage[$this->id]["filter"] = $presetId; $storage[$this->id]["isSetOutside"] = $params["isSetOutside"] ?? false; } } if (!isset($this->options["filters"][$presetId]) || !is_array($this->options["filters"][$presetId])) { $this->options["filters"][$presetId] = []; } if (!empty($settings["name"])) { $this->options["filters"][$presetId]["name"] = $settings["name"]; } if (isset($settings["for_all"])) { $this->options["filters"][$presetId]["for_all"] = $settings["for_all"] === "true"; } if (isset($settings["sort"]) && is_numeric($settings["sort"])) { $this->options["filters"][$presetId]["sort"] = $settings["sort"]; } if (isset($settings["fields"]) && is_array($settings["fields"])) { if (array_key_exists("FIND", $settings["fields"])) { $storage[$this->id]["filter_search"] = $settings["fields"]["FIND"]; unset($settings["fields"]["FIND"]); } if ($presetId == "default_filter") { $this->options["filters"][$presetId]["fields"] = []; } else { $this->options["filters"][$presetId]["fields"] = $settings["fields"]; $additionalFields = isset($settings["additional"]) && is_array($settings["additional"]) ? $settings["additional"] : []; $this->setAdditionalPresetFields($presetId, $additionalFields); } } if (!isset($settings["fields"]) && isset($settings["clear_filter"]) && $settings["clear_filter"] === 'Y') { $this->options["filters"][$presetId]["fields"] = []; } if (!empty($settings["name"])) { $this->options["filters"][$presetId]["name"] = $settings["name"]; } if (isset($settings["rows"])) { $rows = $settings["rows"]; if (is_array($rows)) { $result = []; foreach ($rows as $id) { $id = trim($id); if ($id !== "") { $result[] = $id; } } $this->options["filters"][$presetId]["filter_rows"] = implode(",", $result); } elseif (is_string($settings["rows"])) { $this->options["filters"][$presetId]["filter_rows"] = $settings["rows"]; } } } } /** * Deletes preset by preset id * @param string $presetId * @param bool $isDefault */ public function deleteFilter($presetId, $isDefault = false) { if ($isDefault) { $this->options["deleted_presets"][$presetId] = true; } unset($this->options["filters"][$presetId]); } /** * Checks preset is deleted * @param string $presetId * @return bool */ public function isDeletedPreset($presetId) { return array_key_exists($presetId, $this->options["deleted_presets"]); } /** * Setup Default Filter Settings * @param array $fields Default Filter Fields. * @param array $rows Default Filter Rows. */ public function setupDefaultFilter(array $fields, array $rows) { $this->setFilterSettings("tmp_filter", ["fields" => $fields, "rows" => $rows], true, false); $this->save(); } /** * Calculate date value * * @param string $fieldId * @param array $source Source values * @param array $result Result values * @throws \Bitrix\Main\ObjectException */ public static function calcDates($fieldId, $source, &$result) { switch ($source[$fieldId . "_datesel"]) { case DateType::YESTERDAY : { $dateTime = Filter\DateTimeFactory::createToday(); $result[$fieldId . "_datesel"] = DateType::YESTERDAY; $result[$fieldId . "_month"] = $dateTime->month(); $result[$fieldId . "_quarter"] = $dateTime->quarter(); $result[$fieldId . "_year"] = $dateTime->year(); $result[$fieldId . "_from"] = $dateTime->offset("- 1 days"); $result[$fieldId . "_to"] = $dateTime->offset("- 1 second"); break; } case DateType::CURRENT_DAY : { $dateTime = Filter\DateTimeFactory::createToday(); $result[$fieldId . "_datesel"] = DateType::CURRENT_DAY; $result[$fieldId . "_month"] = $dateTime->month(); $result[$fieldId . "_quarter"] = $dateTime->quarter(); $result[$fieldId . "_year"] = $dateTime->year(); $result[$fieldId . "_from"] = $dateTime->toString(); $result[$fieldId . "_to"] = $dateTime->offset("+ 1 days - 1 second"); break; } case DateType::TOMORROW : { $dateTime = Filter\DateTimeFactory::createToday(); $result[$fieldId . "_datesel"] = DateType::TOMORROW; $result[$fieldId . "_month"] = $dateTime->month(); $result[$fieldId . "_year"] = $dateTime->year(); $result[$fieldId . "_quarter"] = $dateTime->quarter(); $result[$fieldId . "_from"] = $dateTime->offset("+ 1 days"); $result[$fieldId . "_to"] = $dateTime->offset("+ 2 days - 1 second"); break; } case DateType::CURRENT_WEEK : { $dateTime = Filter\DateTimeFactory::createCurrentWeekMonday(); $result[$fieldId . "_datesel"] = DateType::CURRENT_WEEK; $result[$fieldId . "_month"] = $dateTime->month(); $result[$fieldId . "_year"] = $dateTime->year(); $result[$fieldId . "_quarter"] = $dateTime->quarter(); $result[$fieldId . "_from"] = $dateTime->toString(); $result[$fieldId . "_to"] = $dateTime->offset("7 days - 1 second"); break; } case DateType::NEXT_WEEK : { $dateTime = Filter\DateTimeFactory::createNextWeekMonday(); $result[$fieldId . "_datesel"] = DateType::NEXT_WEEK; $result[$fieldId . "_month"] = $dateTime->month(); $result[$fieldId . "_year"] = $dateTime->year(); $result[$fieldId . "_quarter"] = $dateTime->quarter(); $result[$fieldId . "_from"] = $dateTime->toString(); $result[$fieldId . "_to"] = $dateTime->offset("7 days - 1 second"); break; } case DateType::CURRENT_MONTH : { $dateTime = Filter\DateTimeFactory::createFirstDayOfCurrentMonth(); $result[$fieldId . "_datesel"] = DateType::CURRENT_MONTH; $result[$fieldId . "_month"] = $dateTime->month(); $result[$fieldId . "_year"] = $dateTime->year(); $result[$fieldId . "_quarter"] = $dateTime->quarter(); $result[$fieldId . "_from"] = $dateTime->toString(); $result[$fieldId . "_to"] = $dateTime->offset("1 month - 1 second"); break; } case DateType::NEXT_MONTH : { $dateTime = Filter\DateTimeFactory::createFirstDayOfNextMonth(); $result[$fieldId . "_datesel"] = DateType::NEXT_MONTH; $result[$fieldId . "_month"] = $dateTime->month(); $result[$fieldId . "_year"] = $dateTime->year(); $result[$fieldId . "_quarter"] = $dateTime->quarter(); $result[$fieldId . "_from"] = $dateTime->toString(); $result[$fieldId . "_to"] = $dateTime->offset("1 month - 1 second"); break; } case DateType::CURRENT_QUARTER : { $dateTime = Filter\DateTimeFactory::createToday(); $result[$fieldId . "_datesel"] = DateType::QUARTER; $result[$fieldId . "_month"] = $dateTime->month(); $result[$fieldId . "_quarter"] = $dateTime->quarter(); $result[$fieldId . "_year"] = $dateTime->year(); $result[$fieldId . "_from"] = $dateTime->quarterStart(); $result[$fieldId . "_to"] = $dateTime->quarterEnd(); break; } case DateType::LAST_7_DAYS : { $dateTime = Filter\DateTimeFactory::createToday(); $result[$fieldId . "_datesel"] = DateType::LAST_7_DAYS; $result[$fieldId . "_month"] = $dateTime->month(); $result[$fieldId . "_quarter"] = $dateTime->quarter(); $result[$fieldId . "_year"] = $dateTime->year(); $result[$fieldId . "_from"] = $dateTime->offset("- 7 days"); $result[$fieldId . "_to"] = $dateTime->offset("1 days - 1 second"); break; } case DateType::LAST_30_DAYS : { $dateTime = Filter\DateTimeFactory::createToday(); $result[$fieldId . "_datesel"] = DateType::LAST_30_DAYS; $result[$fieldId . "_month"] = $dateTime->month(); $result[$fieldId . "_quarter"] = $dateTime->quarter(); $result[$fieldId . "_year"] = $dateTime->year(); $result[$fieldId . "_from"] = $dateTime->offset("- 30 days"); $result[$fieldId . "_to"] = $dateTime->offset("1 days - 1 second"); break; } case DateType::LAST_60_DAYS : { $dateTime = Filter\DateTimeFactory::createToday(); $result[$fieldId . "_datesel"] = DateType::LAST_60_DAYS; $result[$fieldId . "_month"] = $dateTime->month(); $result[$fieldId . "_quarter"] = $dateTime->quarter(); $result[$fieldId . "_year"] = $dateTime->year(); $result[$fieldId . "_from"] = $dateTime->offset("- 60 days"); $result[$fieldId . "_to"] = $dateTime->offset("1 days - 1 second"); break; } case DateType::LAST_90_DAYS : { $dateTime = Filter\DateTimeFactory::createToday(); $result[$fieldId . "_datesel"] = DateType::LAST_90_DAYS; $result[$fieldId . "_month"] = $dateTime->month(); $result[$fieldId . "_quarter"] = $dateTime->quarter(); $result[$fieldId . "_year"] = $dateTime->year(); $result[$fieldId . "_from"] = $dateTime->offset("- 90 days"); $result[$fieldId . "_to"] = $dateTime->offset("1 days - 1 second"); break; } case DateType::MONTH : { $month = $source[$fieldId . "_month"]; $year = $source[$fieldId . "_year"]; if (!empty($month) && !empty($year)) { $dateTime = new Filter\DateTime(mktime(0, 0, 0, $month, 1, $year)); $result[$fieldId . "_datesel"] = DateType::MONTH; $result[$fieldId . "_month"] = $dateTime->month(); $result[$fieldId . "_quarter"] = $dateTime->quarter(); $result[$fieldId . "_year"] = $dateTime->year(); $result[$fieldId . "_from"] = $dateTime->toString(); $result[$fieldId . "_to"] = $dateTime->offset("1 month - 1 second"); } break; } case DateType::NEXT_DAYS : { if (is_numeric($source[$fieldId . "_days"])) { $dateTime = Filter\DateTimeFactory::createToday(); $days = (int)$source[$fieldId . "_days"]; $days = $days > 0 ? ($days + 1) : $days; $result[$fieldId . "_datesel"] = DateType::NEXT_DAYS; $result[$fieldId . "_month"] = $dateTime->month(); $result[$fieldId . "_quarter"] = $dateTime->quarter(); $result[$fieldId . "_days"] = $source[$fieldId . "_days"]; $result[$fieldId . "_year"] = $dateTime->year(); $result[$fieldId . "_from"] = $dateTime->offset("1 days"); $result[$fieldId . "_to"] = $dateTime->offset($days . " days - 1 second"); } break; } case DateType::PREV_DAYS : { if (is_numeric($source[$fieldId . "_days"])) { $dateTime = Filter\DateTimeFactory::createToday(); $days = (int)$source[$fieldId . "_days"]; $days = max($days, 0); $result[$fieldId . "_datesel"] = DateType::PREV_DAYS; $result[$fieldId . "_month"] = $dateTime->month(); $result[$fieldId . "_quarter"] = $dateTime->quarter(); $result[$fieldId . "_days"] = $source[$fieldId . "_days"]; $result[$fieldId . "_year"] = $dateTime->year(); $result[$fieldId . "_from"] = $dateTime->offset("- " . $days . " days"); $result[$fieldId . "_to"] = $dateTime->offset("1 days -1 second"); } break; } case AdditionalDateType::PREV_DAY : { if (is_numeric($source[$fieldId . "_days"])) { $dateTime = Filter\DateTimeFactory::createToday(); $days = (int)$source[$fieldId . "_days"]; $result[$fieldId . "_days"] = $source[$fieldId . "_days"]; $result[$fieldId . "_from"] = $dateTime->offset(-$days . " days"); $result[$fieldId . "_to"] = $dateTime->offset(-($days - 1) . " days -1 second"); } break; } case AdditionalDateType::NEXT_DAY : case AdditionalDateType::AFTER_DAYS : { if (is_numeric($source[$fieldId . "_days"])) { $dateTime = Filter\DateTimeFactory::createToday(); $days = (int)$source[$fieldId . "_days"]; $result[$fieldId . "_days"] = $source[$fieldId . "_days"]; $result[$fieldId . "_from"] = $dateTime->offset($days . " days"); $result[$fieldId . "_to"] = $dateTime->offset(($days + 1) . " days -1 second"); } break; } case AdditionalDateType::MORE_THAN_DAYS_AGO : { if (is_numeric($source[$fieldId . "_days"])) { $dateTime = Filter\DateTimeFactory::createToday(); $days = (int)$source[$fieldId . "_days"]; $result[$fieldId . "_days"] = $source[$fieldId . "_days"]; $result[$fieldId . "_from"] = $dateTime->offset(-($days + 1) . " days"); $result[$fieldId . "_to"] = $dateTime->offset(-$days . " days -1 second"); } break; } case DateType::QUARTER : { $quarter = $source[$fieldId . "_quarter"]; $year = $source[$fieldId . "_year"]; if (!empty($quarter) && !empty($year)) { $dateTime = new Filter\DateTime(MakeTimeStamp(Quarter::getStartDate($quarter, $year))); $result[$fieldId . "_datesel"] = DateType::QUARTER; $result[$fieldId . "_quarter"] = $dateTime->quarter(); $result[$fieldId . "_year"] = $dateTime->year(); $result[$fieldId . "_month"] = $dateTime->month(); $result[$fieldId . "_from"] = $dateTime->quarterStart(); $result[$fieldId . "_to"] = $dateTime->quarterEnd(); } break; } case DateType::YEAR : { $year = $source[$fieldId . "_year"]; if (!empty($year)) { $dateTime = new Filter\DateTime(mktime(0, 0, 0, 1, 1, $year)); $result[$fieldId . "_datesel"] = DateType::YEAR; $result[$fieldId . "_year"] = $dateTime->year(); $result[$fieldId . "_from"] = $dateTime->toString(); $result[$fieldId . "_to"] = $dateTime->offset("1 year - 1 second"); } break; } case DateType::EXACT : { $sourceDate = $source[$fieldId . "_from"]; if (!empty($sourceDate)) { $date = new Date($sourceDate); $dateTime = new Filter\DateTime(MakeTimeStamp($sourceDate)); $result[$fieldId . "_datesel"] = DateType::EXACT; if ($dateTime->getTimestamp() > $date->getTimestamp()) { $result[$fieldId . "_from"] = $dateTime->toString(); $result[$fieldId . "_to"] = $dateTime->toString(); } else { $result[$fieldId . "_from"] = $dateTime->toString(); $result[$fieldId . "_to"] = $dateTime->offset("1 days - 1 second"); } } break; } case DateType::LAST_WEEK : { $dateTime = Filter\DateTimeFactory::createLastWeekMonday(); $result[$fieldId . "_datesel"] = DateType::LAST_WEEK; $result[$fieldId . "_from"] = $dateTime->toString(); $result[$fieldId . "_to"] = $dateTime->offset("7 days - 1 second"); break; } case DateType::LAST_MONTH : { $dateTime = Filter\DateTimeFactory::createFirstDayOfLastMonth(); $result[$fieldId . "_datesel"] = DateType::LAST_MONTH; $result[$fieldId . "_year"] = $dateTime->year(); $result[$fieldId . "_month"] = $dateTime->month(); $result[$fieldId . "_from"] = $dateTime->toString(); $result[$fieldId . "_to"] = $dateTime->offset("1 month - 1 second"); break; } case DateType::RANGE : { $startSourceDate = $source[$fieldId . "_from"]; $endSourceDate = $source[$fieldId . "_to"]; $result[$fieldId . "_from"] = ""; $result[$fieldId . "_to"] = ""; if (!empty($startSourceDate)) { $startDateTime = new Filter\DateTime(MakeTimeStamp($startSourceDate)); $result[$fieldId . "_datesel"] = DateType::RANGE; $result[$fieldId . "_from"] = $startDateTime->toString(); } if (!empty($endSourceDate)) { $endDate = Date::createFromTimestamp(MakeTimeStamp($endSourceDate)); $endDateTime = new Filter\DateTime(MakeTimeStamp($endSourceDate)); $result[$fieldId . "_datesel"] = DateType::RANGE; if ($endDateTime->getTimestamp() > $endDate->getTimestamp()) { $result[$fieldId . "_to"] = $endDateTime->toString(); } else { $result[$fieldId . "_to"] = $endDateTime->offset("1 days - 1 second"); } } break; } } } /** * Resets current applied filter */ public function reset() { $storage = $this->getStorage(); $storage[$this->id] = null; } /** * Destroys this filter options */ public function destroy() { $filterId = $this->getId(); \CUserOptions::deleteOption("main.ui.filter", $filterId); \CUserOptions::deleteOption("main.ui.filter.presets", $filterId); $storage = $this->getStorage(); unset($storage[$filterId]); } public static function getRowsFromFields($fields = []) { $rows = []; foreach ($fields as $key => $field) { $rows[] = str_replace( [ "_datesel", "_numsel", "_from", "_to", "_days", "_month", "_quarter", "_id", "_year", "_name", "_label", "_value", "_days", "_months", "_years", "_isEmpty", "_hasAnyValue", ], "", $key ); } return array_unique($rows); } /** * Fetches preset fields list * @param array $preset * @return array */ public static function fetchPresetFields($preset) { if (isset($preset["filter_rows"]) && is_string($preset["filter_rows"])) { $fields = explode(",", $preset["filter_rows"]); return array_unique($fields); } return static::getRowsFromFields($preset["fields"]); } /** * Gets used fields * @return array */ public function getUsedFields() { $fields = []; // Fetch fields from user presets foreach ($this->getPresets() as $preset) { $presetFields = static::fetchPresetFields($preset); $fields = array_merge($fields, $presetFields); } $defaultPresetFieldsOrder = []; // Fetch fields from default presets foreach ($this->getDefaultPresets() as $preset) { $presetFields = static::fetchPresetFields($preset); $fields = array_merge($fields, $presetFields); if (isset($preset['default'])) { $defaultPresetFieldsOrder = $presetFields; } } $fields = array_unique($fields); if (!empty($defaultPresetFieldsOrder)) { // fields order should be defined by default filter preset $fields = array_unique(array_merge($defaultPresetFieldsOrder, $fields)); } return $fields; } /** * @return string|null */ public function getCurrentFilterPresetId(): ?string { return $this->currentFilterPresetId; } /** * @param string|null $presetId * @return Options */ public function setCurrentFilterPresetId(?string $presetId): Options { $this->currentFilterPresetId = $presetId; return $this; } }