403Webshell
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/cvetdv.ru/bitrix/modules/sale/lib/location/admin/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/cvetdv.ru/bitrix/modules/sale/lib/location/admin/helper.php
<?
/**
 * This class is for internal use only, not a part of public API.
 * It can be changed at any time without notification.
 *
 * @access private
 */

namespace Bitrix\Sale\Location\Admin;

use Bitrix\Main;
use Bitrix\Main\Config;
use Bitrix\Main\Localization\Loc;
use Bitrix\Sale\Location;

abstract class Helper
{
	const DEBUG_MODE_OPT = 'location2_debug_mode';

	const IMPORT_PAGE_URL = 'sale_location_import.php';
	const REINDEX_PAGE_URL = 'sale_location_reindex.php';
	const MIGRATION_PAGE_URL = 'sale_location_migration.php';

	const LOCATION_LINK_DATA_CACHE_TAG = 'sale-location-data';

	#####################################
	#### Entity settings
	#####################################

	abstract public static function getEntityRoadMap();

	public static function getEntityRoadCode()
	{
		return 'main';
	}

	// this should be overlapped for each ancestor
	public static function getColumns($page)
	{
		// in the middle of extension, should be like this:
		//return array_merge(parent::getColumns(), self::getMap());

		return self::getMap($page);
	}

	// get part of the whole field map for responsibility zone of the current entity
	// call this only with self::
	public static function getMap($page)
	{
		static $flds;

		if($flds == null)
			$flds = static::readMap(self::getEntityRoadCode(), $page);

		return $flds;
	}

	#####################################
	#### CRUD wrappers
	#####################################

	// columns shown in all grids
	public static function getListGridColumns()
	{
		$columns = static::getColumns('list');
		foreach($columns as &$col)
			$col['DEFAULT'] = true;

		return $columns;
	}

	// columns shown in all filters
	public static function getFilterColumns()
	{
		$columns = static::getColumns('list');
		foreach($columns as &$col)
			$col['DEFAULT'] = true;

		return $columns;
	}

	// columns shown in all forms
	public static function getDetailPageRows()
	{
		return static::getColumns('list');
	}

	// generalized filter to orm filter proxy
	public static function getParametersForList($proxed)
	{
		$columns = self::getMap('list'); // columns only for 'main' class

		$parameters = array();

		// filter
		$filter = array();
		if (!empty($proxed['FILTER']) && is_array($proxed['FILTER']))
		{
			foreach($columns as $code => $fld)
			{
				if (!isset($proxed['FILTER'][$code]))
				{
					continue;
				}
				if($fld['data_type'] == 'integer' || $fld['data_type'] == 'float')
				{
					// range or list expected
					if(is_array($proxed['FILTER'][$code]))
					{
						$from = (string)($proxed['FILTER'][$code]['FROM'] ?? null);
						$to = (string)($proxed['FILTER'][$code]['TO'] ?? null);
						if ($from !== '' && $to !== '') // range
						{
							$filter['><'.$code] = array($from, $to);
						}
						elseif ($from !== '') // greather than
						{
							$filter['>='.$code] = $from;
						}
						elseif ($to !== '') // less than
						{
							$filter['<='.$code] = $to;
						}
						unset(
							$to,
							$from,
						);
					}
					elseif(mb_strlen($proxed['FILTER'][$code]))
					{
						$filter['='.$code] = (string)$proxed['FILTER'][$code];
					}
				}
				else
				{
					if($proxed['FILTER'][$code] <> '')
					{
						$filter[static::getFilterModifier($fld['data_type']).$code] = $proxed['FILTER'][$code];
					}
				}
			}
		}

		if(!empty($filter))
			$parameters['filter'] = $filter;

		// select
		foreach($columns as $code => $col)
			$parameters['select'][] = $code;

		// order
		if (!empty($proxed['ORDER']) && is_array($proxed['ORDER']))
			$parameters['order'] = $proxed['ORDER'];

		// nav (unused)
		if (!empty($proxed['NAV']) && is_array($proxed['NAV']))
		{
			$page = (int)($proxed['NAV']['PAGE_NUM'] ?? 0);
			$lop = (int)($proxed['NAV']['LOP'] ?? 0);
			if ($page && $lop)
			{
				$roadMap = static::getEntityRoadMap();
				$road = $roadMap[self::getEntityRoadCode()]['name'];
				$class = $road . 'Table';

				$count = $class::getList([
					'filter' => is_array($parameters['filter']) ? $parameters['filter'] : [],
					'select' => ['CNT'],
					'runtime' => [
						'CNT' => [
							'data_type' => 'integer',
							'expression' => [
								'count(%u)',
								'ID'
							]
						]
					]
				])->fetch();

				$bounds = Main\DB\Paginator::calculateQueryLimits($count['CNT'], $page, $lop, false);
				$parameters['offset'] = $bounds[0];
				$parameters['limit'] = $bounds[1];
			}
		}

		return $parameters;
	}

	/*
	* $parameters: array of keys: FILTER (generalized), ID, OPERATION
	*/
	public static function performGridOperations($parameters)
	{
		$result = array(
			'sucess' => true,
			'errors' => array()
		);

		@set_time_limit(0);

		if (!empty($parameters['ID']) && is_array($parameters['ID']))
		{
			$parameters['ID'] = array_unique($parameters['ID']);
			foreach($parameters['ID'] as $id)
			{
				$res = static::delete($id);
				if(!$res['success'])
				{
					$result['success'] = false;
					$result['errors'] = array_merge($result['errors'], $res['errors']);
				}
			}
		}
		elseif (isset($parameters['FILTER']) && is_array($parameters['FILTER'])) // filter can be empty
		{
			$entityClass = static::getEntityClass();
			$parameters = Helper::getParametersForList($parameters); // from generalized to orm

			$glParams = array('select' => array('ID'));

			if(is_array($parameters['filter']) && !empty($parameters['filter']))
				$glParams['filter'] = $parameters['filter'];

			$resItems = $entityClass::getList($glParams);

			while ($item = $resItems->fetch())
			{

				/* Locations have tree-style structure so
				 * we could have deleted some of them
				 * during previous iterations. Let's check this.
				*/
				if(!$entityClass::getById($item['ID'])->fetch())
					continue;
				/**/

				$res = static::delete($item['ID']);
				if(!$res['success'])
				{
					$result['success'] = false;
					$result['errors'] = array_merge($result['errors'], $res['errors']);
				}
			}
		}

		return $result;
	}

	// get data to display in a form
	public static function getFormData($id)
	{
		$parameters = static::proxyListRequest('detail');
		$parameters['filter']['='.static::getPrimaryFieldName()] = $id;

		$formData = static::getList($parameters)->fetch();

		if(!is_array($formData) || empty($formData))
			throw new Main\SystemException(Loc::getMessage('SALE_LOCATION_E_ITEM_NOT_FOUND'));

		return $formData;
	}

	public static function makeSafeDisplay(&$value, $code)
	{
		$columns = static::getColumns('');

		$value = (string)$value;
		if(!empty($columns[$code]))
		{
			if ($value === '' && isset($columns[$code]['default']))
			{
				$value = (string)$columns[$code]['default'];
			}

			switch($columns[$code]['data_type'])
			{
				case 'integer':
					$value = (int)$value;
					break;
				case 'float':
					$value = (float)$value;
					break;
				default:
					$value = htmlspecialcharsbx($value);
			}
		}
		else
			$value = htmlspecialcharsbx($value);

		return $value;
	}

	##############################################
	##############################################
	##############################################

	public static function validateUpdateRequest($data)
	{
		return array();
	}

	// this function could be much more complicated in the derivative classes
	public static function proxyUpdateRequest($data)
	{
		unset($data['ID']); // drop id if presents

		$proxed = array();
		$columns = static::getColumns('list');

		foreach($columns as $code => $void)
		{
			if(isset($data[$code]))
				$proxed[$code] = $data[$code];
		}

		return $proxed;
	}

	// an adapter from CAdminList + CAdminFilter to ORM getList() logic
	// deprecated: too strong relation with admin grid, replaced with getParametersForList
	public static function proxyListRequest($page)
	{
		global $by;
		global $order;

		$columns = self::getMap($page); // columns only for 'main' class

		$parameters = array('filter' => array());

		foreach($columns as $code => $col)
			$parameters['select'][] = $code;

		$filter = array();
		if(self::checkUseFilter())
		{
			foreach($columns as $code => $fld)
			{
				$from = 'find_'.$code.'_1';
				$to = 'find_'.$code.'_2';

				if ($fld['data_type'] === 'integer' && (isset($GLOBALS[$from]) || isset($GLOBALS[$to])))
				{
					// range expected

					$valueFrom = trim((string)($GLOBALS[$from] ?? ''));
					$valueTo = trim((string)($GLOBALS[$to] ?? ''));

					if ($valueFrom !== '' && $valueTo !== '') // range
					{
						$filter['><'.$code] = [(int)$valueFrom, (int)$valueTo];
					}
					elseif ($valueFrom !== '') // greather than
					{
						$filter['>='.$code] = (int)$valueFrom;
					}
					elseif ($valueTo !== '') // less than
					{
						$filter['<='.$code] = (int)$valueTo;
					}
				}
				else
				{
					$value = trim((string)($GLOBALS['find_'.$code] ?? ''));
					if ($value !== '')
					{
						$filter[static::getFilterModifier($fld['data_type']).$code] = $value;
					}
				}
			}
		}

		if(!empty($filter))
			$parameters['filter'] = $filter;
		if($by <> '')
		{
			$columns = static::getColumns($page); // check if that column really exists, for the whole extension hierarchy

			if(isset($columns[$by]))
			{
				$parameters['order'] = array($by => isset($order)? $order : 'asc');
			}
		}

		return $parameters;
	}

	// crud over entity: add
	public static function add($data)
	{
		$success = true;
		$id = false;
		$entityClass = static::getEntityClass();

		$data = static::convertToArray($data);

		$data = static::proxyUpdateRequest($data);
		$errors = static::validateUpdateRequest($data);

		if(empty($errors))
		{
			$res = $entityClass::add($data);
			if(!$res->isSuccess())
			{
				$success = false;
				$errors = $res->getErrorMessages();
			}
			else
				$id = $res->getId();
		}
		else
			$success = false;

		return array(
			'success' => $success,
			'errors' => $errors,
			'id' => $id
		);
	}

	// crud over entity: update
	public static function update($primary, $data)
	{
		$success = true;
		$entityClass = static::getEntityClass();

		$data = static::convertToArray($data);
		$data = static::proxyUpdateRequest($data);
		$errors = static::validateUpdateRequest($data);

		if(empty($errors))
		{
			$res = $entityClass::update($primary, $data);
			if(!$res->isSuccess())
			{
				$success = false;
				$errors = $res->getErrorMessages();
			}
		}
		else
			$success = false;

		return array(
			'success' => $success,
			'errors' => $errors
		);
	}

	// crud over entity: delete
	public static function delete($primary)
	{
		$success = true;
		$errors = array();
		$entityClass = static::getEntityClass();

		$res = $entityClass::delete($primary);
		if(!$res->isSuccess())
		{
			$success = false;
			$errors = $res->getErrorMessages();
		}

		return array(
			'success' => $success,
			'errors' => $errors
		);
	}

	// function calculates limit and offset for sql select query, based on current request and session
	// variables, then forms fake old-style database result
	public static function getList($parameters = array(), $tableId = false, $navigation = 20, $params = array())
	{
		$entityClass = static::getEntityClass();
		$navNum = ($GLOBALS['NavNum'] ?? 0) + 1;
		$unique = md5($GLOBALS['APPLICATION']->GetCurPage());
		$showAll = ($_SESSION[$unique.'SESS_ALL_'.$navNum] ?? null) || ($GET['SHOWALL_'.$navNum] ?? null);
		$isAdminSection = defined('ADMIN_SECTION') && ADMIN_SECTION === true;
		$tableId = trim((string)$tableId);

		if (($params["uiMode"] ?? null))
		{
			$result = new \CSaleProxyAdminUiResult($parameters, $entityClass, $tableId);
		}
		elseif($isAdminSection && $tableId !== '')
		{
			$result = new \CSaleProxyAdminResult($parameters, $entityClass, $tableId); // being in admin and knowing table, do admin result api call
		}
		else
		{
			$result = new \CSaleProxyResult($parameters, $entityClass); // otherwise - public api call
		}

		if(!$showAll && $navigation !== false)
		{
			if($navigation === true)
			{
				$result->NavStart();
			}
			else
			{
				$result->NavStart($navigation);
			}
		}
		else
		{
			$result->NavStart();
		}

		// temporal fix
		$result->bShowAll = false;

		return $result;
	}

	public static function convertToArray($data)
	{
		if(!is_array($data))
		{
			$converted = array();
			foreach($data as $key => $value)
				$converted[$key] = $value;

			$data = $converted;
		}

		foreach($data as &$value)
		{
			if(is_string($value))
				$value = trim($value);
		}

		return $data;
	}

	// deprecated: not optimal
	public static function getIdsByFilter($listFilter)
	{
		$ids = array();
		$entityClass = static::getEntityClass();

		$res = $entityClass::getList(array(
			'select' => array('ID'),
			'filter' => is_array($listFilter) ? $listFilter : array()
		));
		while($item = $res->fetch())
		{
			$ids[] = intval($item['ID']);
		}

		return $ids;
	}

	public static function getPrimaryFieldName()
	{
		$map = static::getEntityRoadMap();

		return (string)($map['main']['primaryFieldName'] ?? '') !== '' ? $map['main']['primaryFieldName'] : 'ID';
	}

	// returns element name by it`s primary
	public static function getNameToDisplay($id)
	{
		if(!($id = intval($id)))
			return '';

		$entityClass = static::getEntityClass('main');

		$item = $entityClass::getById($id)->fetch();
		return $item['CODE'];
	}

	public static function getListUrl($parameters = array())
	{
		return self::getUrl(static::LIST_PAGE_URL, $parameters);
	}

	public static function getEditUrl($parameters = array())
	{
		return self::getUrl(static::EDIT_PAGE_URL, $parameters);
	}

	public static function getImportUrl()
	{
		return self::getUrl(static::IMPORT_PAGE_URL, array());
	}

	public static function getReindexUrl()
	{
		return self::getUrl(static::REINDEX_PAGE_URL, array());
	}

	public static function getMigrationUrl()
	{
		return self::getUrl(static::MIGRATION_PAGE_URL, array());
	}

	public static function getUrl($page, $parameters = array())
	{
		if(!is_array($parameters))
			$parameters = array();

		$parameters['lang'] = LANGUAGE_ID;

		$selfFolderUrl = (defined("SELF_FOLDER_URL") ? SELF_FOLDER_URL : "/bitrix/admin/");

		$packed = self::packUrlParameters($parameters);
		return $selfFolderUrl.$page.($packed <> ''? '?'.$packed : '');
	}

	#####################################
	#### Utilily methods for CRUD
	#####################################

	// deprecated: too strong relation with admin grid
	public static function checkUseFilter()
	{
		return ($GLOBALS['filter'] ?? null) === 'Y' && !$GLOBALS['del_filter'];
	}

	public static function readMap($entityRoadCode, $page = 'list')
	{
		$roads = static::getEntityRoadMap();
		$road = $roads[$entityRoadCode];

		if(!$road['name'])
			throw new Main\SystemException('Undefined entity name in entity map');

		if($page == '')
			$page = 'list';

		$flds = array();
		$class = $road['name'].'Table';
		$excluded = $road['pages'][$page]['excludedColumns'] ?? null;
		$included = $road['pages'][$page]['includedColumns'] ?? null;

		$map = $class::getMap();
		if (!empty($road['additional']) && is_array($road['additional']))
		{
			$map = array_merge($map, $road['additional']);
		}

		foreach ($map as $fldCode => $fldDesc)
		{
			if (is_array($excluded) && in_array($fldCode, $excluded))
			{
				continue;
			}

			if (is_array($included) && !in_array($fldCode, $included))
			{
				continue;
			}

			if (
				is_array($fldDesc)
				&& (
					(isset($fldDesc['title']) && mb_strlen($fldDesc['title']))
					|| (isset($fldDesc['required']) && $fldDesc['required'])
					|| (isset($fldDesc['primary']) && $fldDesc['primary'])
					|| $fldCode === 'ID'
				)
			)
			{
				$title = trim((string)($fldDesc['title'] ?? ''));
				$fldDesc['title'] = $title !== ''? htmlspecialcharsbx($title) : $fldCode;
				$fldDesc['ownerEntity'] = $road['name']; // map can be cumulative, from several entites, so we need to know who is an owner
				$flds[$fldCode] = $fldDesc;
			}
		}

		return $flds;
	}

	protected static function getFilterModifier($type)
	{
		return $type == 'string' ? '?' : '=';
	}

	protected static function packUrlParameters($parameters = array())
	{
		$params = array();
		foreach($parameters as $param => $value)
		{
			if($value <> '')
			{
				if(mb_strpos($param, '=') === 0)
				{
					// value goes as-is, unsafe
					$param = mb_substr($param, 1);
				}
				else
				{
					$value = urlencode($value);
				}

				$params[] = urlencode($param).'='.$value;
			}
		}

		return implode('&', $params);
	}

	protected static function getEntityClass($code = '')
	{
		$entityRoad = static::getEntityRoadMap();
		$entityName = $entityRoad[$code <> ''? $code : self::getEntityRoadCode()]['name'];

		if(!$entityName)
			throw new Main\SystemException('Undefined entity name in helper');

		return $entityName.'Table';
	}

	public static function getWidgetAppearance()
	{
		$appearance = Config\Option::get("sale", "sale_location_selector_appearance");

		if(!mb_strlen($appearance) || !in_array($appearance, array('search', 'steps')))
			return 'steps';

		return $appearance;
	}

	protected static function normalizeList($list, $expectNumeric = true)
	{
		$list = array_unique(array_values($list));
		foreach($list as $i => $id)
		{
			if($expectNumeric)
			{
				if(intval($id) != $id)
					unset($list[$i]);

				$list[$i] = intval($id);
				if(!$list[$i])
					unset($list[$i]);
			}
			else
			{
				if($list[$i] == '')
					unset($list[$i]);
			}
		}

		return $list;
	}

	// proxy between $_REQUEST and resulting array to save links between entites and locations
	public static function prepareLinksForSaving($connectorClass, $links)
	{
		$useIds = !$connectorClass::getUseCodes();
		$useGroups = $connectorClass::getUseGroups();
		$l = $connectorClass::DB_LOCATION_FLAG;
		$g = $connectorClass::DB_GROUP_FLAG;

		if(isset($links[$l]))
		{
			if(is_string($links[$l]))
				$links[$l] = explode(':', $links[$l]);
		}
		else
			$links[$l] = array();

		$links[$l] = self::normalizeList($links[$l], $useIds);

		if(!$useGroups)
			unset($links[$g]);
		else
		{
			if(isset($links[$g]))
			{
				if(is_string($links[$g]))
					$links[$g] = explode(':', $links[$g]);
			}
			else
				$links[$g] = array();

			$links[$g] = self::normalizeList($links[$g], $useIds);
		}

		return $links;
	}

	public static function resetLocationsForEntity($entityId, $locations, $entityName, $expectCodes = false)
	{
		$locList = array();

		if(is_array($locations) && !empty($locations))
		{
			foreach($locations as $loc)
			{
				if($loc['LOCATION_TYPE'] == 'L')
					$locList[Location\Connector::DB_LOCATION_FLAG][] = $loc['LOCATION_ID'];
				elseif($loc['LOCATION_TYPE'] == 'G')
					$locList[Location\Connector::DB_GROUP_FLAG][] = $loc['LOCATION_ID'];
			}
		}

		$entityClass = $entityName.'Table';

		try
		{
			if(!empty($locList) && !$expectCodes)
			{
				$locList[Location\Connector::DB_LOCATION_FLAG] = $entityClass::normalizeLocationList($locList[Location\Connector::DB_LOCATION_FLAG]);

				$gf = Location\Connector::DB_GROUP_FLAG;
				if(!empty($locList[$gf]))
				{
					$groupCodes = array();
					$locList[$gf] = array_flip($locList[$gf]);
					// here we must get codes by ids for groups. There will be no thousands of groups, so we can do the following:
					$res = Location\GroupTable::getList(array('select' => array('ID', 'CODE')));
					while($item = $res->fetch())
					{
						if(isset($locList[$gf][$item['ID']]))
							$groupCodes[$item['CODE']] = 1;
					}

					$locList[$gf] = array_keys($groupCodes);
				}
			}

			$entityClass::resetMultipleForOwner($entityId, $locList);
		}
		catch(Exception $e)
		{
		}
	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit