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/rospirotorg.ru/bitrix/modules/sale/lib/location/search/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/sale/lib/location/search/word.php
<?php
/**
 * Bitrix Framework
 * @package Bitrix\Sale\Location
 * @subpackage sale
 * @copyright 2001-2014 Bitrix
 */
namespace Bitrix\Sale\Location\Search;

use Bitrix\Main;
use Bitrix\Main\DB;
use Bitrix\Main\Entity;
use Bitrix\Main\Localization\Loc;

use Bitrix\Sale\Location;
use Bitrix\Sale\Location\DB\BlockInserter;
use Bitrix\Sale\Location\DB\Helper;

Loc::loadMessages(__FILE__);

/**
 * Class WordTable
 *
 * DO NOT WRITE ANYTHING BELOW THIS
 *
 * <<< ORMENTITYANNOTATION
 * @method static EO_Word_Query query()
 * @method static EO_Word_Result getByPrimary($primary, array $parameters = [])
 * @method static EO_Word_Result getById($id)
 * @method static EO_Word_Result getList(array $parameters = [])
 * @method static EO_Word_Entity getEntity()
 * @method static \Bitrix\Sale\Location\Search\EO_Word createObject($setDefaultValues = true)
 * @method static \Bitrix\Sale\Location\Search\EO_Word_Collection createCollection()
 * @method static \Bitrix\Sale\Location\Search\EO_Word wakeUpObject($row)
 * @method static \Bitrix\Sale\Location\Search\EO_Word_Collection wakeUpCollection($rows)
 */
final class WordTable extends Entity\DataManager implements \Serializable
{
	protected $procData = 		array();
	protected BlockInserter $word2LocationInserter;
	protected BlockInserter $dictionaryInserter;
	protected BlockInserter $dictionaryResorter;

	protected $dictionaryIndex = 		array();

	const STEP_SIZE = 					10000;
	const MTU = 						9999;

	public function serialize(): ?string
	{
		return serialize($this->procData);
	}

	public function unserialize($data): void
	{
		$this->procData = unserialize($data, ['allowed_classes' => false]);
		$this->initInsertHandles();
	}

	public function __serialize()
	{
		return $this->procData;
	}

	public function __unserialize($data): void
	{
		if (is_array($data))
		{
			$this->procData = $data;
			$this->initInsertHandles();
		}
	}

	public static function getFilePath()
	{
		return __FILE__;
	}

	// this for keeping word dictionary
	public static function getTableName()
	{
		return 'b_sale_loc_search_word';
	}

	// this for keeping links between location-and-word-id
	public static function getTableNameWord2Location()
	{
		return 'b_sale_loc_search_w2l';
	}

	// this for merge, temporal table
	public static function getTableNamePositionTemporal()
	{
		return 'b_sale_loc_search_wt';
	}

	public function __construct($parameters)
	{
		$this->resetProcess();
		$this->initInsertHandles();

		if(is_array($parameters['TYPES']) && !empty($parameters['TYPES']))
		{
			$this->procData['ALLOWED_TYPES'] = array_unique($parameters['TYPES']);
		}
		if(is_array($parameters['LANGS']) && !empty($parameters['LANGS']))
		{
			$this->procData['ALLOWED_LANGS'] = array_unique($parameters['LANGS']);
		}

		$this->procData['CURRENT_LOCATION'] = false;
		$this->procData['CURRENT_LOCATION_WORDS'] = array();
	}

	public function initInsertHandles()
	{
		$this->word2LocationInserter = new BlockInserter(array(
			'tableName' => static::getTableNameWord2Location(),
			'exactFields' => array(
				'LOCATION_ID' => array('data_type' => 'integer'),
				'WORD_ID' => array('data_type' => 'integer')
			),
			'parameters' => array(
				'mtu' => static::MTU
			)
		));

		$this->dictionaryInserter = new BlockInserter(array(
			'entityName' => '\Bitrix\Sale\Location\Search\WordTable',
			'exactFields' => array(
				'WORD'
			),
			'parameters' => array(
				'mtu' => static::MTU,
				'autoIncrementFld' => 'ID',
				'CALLBACKS' => array(
					'ON_BEFORE_FLUSH' => array($this, 'onBeforeDictionaryFlush')
				)
			)
		));

		$this->dictionaryResorter = new BlockInserter(array(
			'tableName' => static::getTableNamePositionTemporal(),
			'exactFields' => array(
				'WORD_ID' => array('data_type' => 'integer'),
				'POSITION' => array('data_type' => 'integer')
			),
			'parameters' => array(
				'mtu' => static::MTU
			)
		));
	}

	public function resetProcess()
	{
		$this->procData = array(
			'OFFSET' => 					0,
			'POSITION' => 					0,
			'CURRENT_LOCATION' => 			false,
			'CURRENT_LOCATION_WORDS' => 	array()
		);
	}

	public static function cleanUpData()
	{
		$dbConnection = Main\HttpApplication::getConnection();

		Helper::dropTable(static::getTableName());

		$binary = mb_strtolower($dbConnection->getType()) == 'mysql' ? 'binary' : ''; // http://bugs.mysql.com/bug.php?id=34096

		// ORACE: OK, MSSQL: OK
		Main\HttpApplication::getConnection()->query("create table ".static::getTableName()." (

			ID ".Helper::getSqlForDataType('int')." not null ".Helper::getSqlForAutoIncrement().",
			WORD ".Helper::getSqlForDataType('varchar', 50)." ".$binary." not null,
			POSITION ".Helper::getSqlForDataType('int')." default '0',
			primary key (ID)
		)");

		Helper::createIndex(static::getTableName(), 'TMP', array('WORD'), true);
		Helper::dropTable(static::getTableNameWord2Location());

		// ORACLE: OK, MSSQL: OK
		Main\HttpApplication::getConnection()->query("create table ".static::getTableNameWord2Location()." (

			LOCATION_ID ".Helper::getSqlForDataType('int')." not null,
			WORD_ID ".Helper::getSqlForDataType('int')." not null,

			primary key (LOCATION_ID, WORD_ID)
		)");

		Helper::dropTable(static::getTableNamePositionTemporal());

		$dbConnection->query("create table ".static::getTableNamePositionTemporal()." (
			WORD_ID ".Helper::getSqlForDataType('int')." not null,
			POSITION ".Helper::getSqlForDataType('int')." default '0'
		)");
	}

	public static function createIndex()
	{
		Helper::dropIndexByName('IX_SALE_LOC_SEARCH_WORD_TMP', static::getTableName());
		Helper::createIndex(static::getTableName(), 'WP', array('WORD', 'POSITION'));
	}

	public static function parseWords($words)
	{
		$result = array();
		foreach($words as $k => &$word)
		{
			$word = mb_strtoupper(trim($word));
			$word = str_replace('%', '', $word);

			if($word == '')
				continue;

			$result[] = $word;
		}

		//natsort($result);

		return array_unique($result);
	}

	public static function parseString($query)
	{
		$query = mb_strtoupper(Trim($query));

		//$query = str_replace(array_keys(static::$blackList), static::$blackList, ' '.$query.' ');
		$query = str_replace(array(')', '(', '%', '_'), array('', '', '', ''), $query);

		$words = explode(' ', $query);

		return self::parseWords($words);
	}

	public function setOffset($offset)
	{
		$this->procData['OFFSET'] = $offset;
	}

	public function getOffset()
	{
		return $this->procData['OFFSET'];
	}

	public function setPosition($position)
	{
		$this->procData['POSITION'] = $position;
	}

	public function getPosition()
	{
		return $this->procData['POSITION'];
	}

	public function onBeforeDictionaryFlush()
	{
		$this->dictionaryIndex = array();
	}

	public static function getFilterForInitData($parameters = array())
	{
		$filter = array();

		if(!is_array($parameters))
			$parameters = array();

		if(is_array($parameters['TYPES']) && !empty($parameters['TYPES']))
			$filter['=LOCATION.TYPE_ID'] = array_unique($parameters['TYPES']);

		if(is_array($parameters['LANGS']) && !empty($parameters['LANGS']))
			$filter['=LANGUAGE_ID'] = array_unique($parameters['LANGS']);

		return $filter;
	}

	public function initializeData()
	{
		$res = Location\Name\LocationTable::getList(array(
			'select' => array(
				'NAME',
				'LOCATION_ID'
			),
			'filter' => static::getFilterForInitData(array(
				'TYPES' => $this->procData['ALLOWED_TYPES'],
				'LANGS' => $this->procData['ALLOWED_LANGS']
			)),
			'order' => array('LOCATION_ID' => 'asc'), // need to make same location ids stay together
			'limit' => static::STEP_SIZE,
			'offset' => $this->procData['OFFSET']
		));

		$cnt = 0;
		while($item = $res->fetch())
		{
			if($item['NAME'] <> '')
			{
				if($this->procData['CURRENT_LOCATION'] != $item['LOCATION_ID'])
				{
					$this->procData['CURRENT_LOCATION_WORDS'] = array();
				}

				$this->procData['CURRENT_LOCATION'] = $item['LOCATION_ID'];

				$words = static::parseString($item['NAME']);

				foreach($words as $k => &$word)
				{
					$wordHash = md5($word);

					$wordId = false;
					if(isset($this->dictionaryIndex[$wordHash])) // word is already added and in a hot index
					{
						$wordId = $this->dictionaryIndex[$wordHash];
					}
					else
					{
						$wordId = static::getIdByWord($word); // check if the word was added previously
					}

					if($wordId === false)
					{
						$wordId = $this->dictionaryInserter->insert(array(
							'WORD' => $word
						));
						$this->dictionaryIndex[$wordHash] = $wordId;
					}

					if($wordId !== false && !isset($this->procData['CURRENT_LOCATION_WORDS'][$wordId]))
					{
						$this->procData['CURRENT_LOCATION_WORDS'][$wordId] = true;

						$this->word2LocationInserter->insert(array(
							'LOCATION_ID' => intval($item['LOCATION_ID']),
							'WORD_ID' => intval($wordId)
						));
					}
				}
			}

			$cnt++;
		}

		$this->procData['OFFSET'] += static::STEP_SIZE;

		$this->dictionaryInserter->flush();
		$this->word2LocationInserter->flush();

		return !$cnt;
	}

	public function resort()
	{
		$res = Main\HttpApplication::getConnection()->query(
			Main\HttpApplication::getConnection()->getSqlHelper()->getTopSql("select ID, WORD from ".static::getTableName()." order by WORD asc, ID asc", self::STEP_SIZE, intval($this->procData['OFFSET']))
		);

		$cnt = 0;
		while($item = $res->fetch())
		{
			$this->procData['POSITION']++;

			$this->dictionaryResorter->insert(array(
				'WORD_ID' => $item['ID'],
				'POSITION' => $this->procData['POSITION']
			));

			$cnt++;
		}

		$this->procData['OFFSET'] += static::STEP_SIZE;

		$this->dictionaryResorter->flush();

		return !$cnt;
	}

	public static function mergeResort()
	{
		Helper::mergeTables(
			static::getTableName(),
			static::getTableNamePositionTemporal(),
			array('POSITION' => 'POSITION'),
			array('ID' => 'WORD_ID')
		);

		Main\HttpApplication::getConnection()->query("drop table ".static::getTableNamePositionTemporal());
	}

	public static function getIdByWord($word)
	{
		$word = trim((string)$word);
		if ($word === '')
		{
			return false;
		}

		$dbConnection = Main\HttpApplication::getConnection();

		$item = $dbConnection->query(
			"select ID from " . static::getTableName()
			. " where WORD = '" . $dbConnection->getSqlHelper()->forSql($word) . "'"
		)->fetch();

		$id = (int)($item['ID'] ?? 0);

		return $id ?: false;
	}

	public static function getBoundsByWord($word)
	{
		$word = trim($word);

		$dbConnection = Main\HttpApplication::getConnection();
		$sql = "select MIN(POSITION) as INF, MAX(POSITION) as SUP from ".static::getTableName()." where WORD like '".mb_strtoupper($dbConnection->getSqlHelper()->forSql($word))."%'";

		return $dbConnection->query($sql)->fetch();
	}

	public static function getWordsByBounds($inf, $sup)
	{
		return static::getList(array('filter' => array(
			'>=POSITION' => intval($inf),
			'<=POSITION' => intval($sup)
		), 'order' => array(
			'POSITION' => 'asc'
		)));
	}

	public static function getBoundsForPhrase($phrase)
	{
		if(is_string($phrase))
			$words = self::parseString($phrase);
		elseif(is_array($phrase))
			$words = self::parseWords($phrase);
		else
			return array();

		// check for empty request

		$bounds = array();
		$sizes = array();
		$i = 0;
		foreach($words as $word)
		{
			$bound = self::getBoundsByWord($word);
			if(!intval($bound['INF']) && !intval($bound['SUP'])) // no such word
				return array();

			$bounds[$i] = $bound;

			$sizes[] = $bound['SUP'] - $bound['INF'];

			$i++;
		}

		// resort bounds to have sorted smallest to largest
		//asort($sizes, SORT_NUMERIC);

		$boundsSorted = array();
		foreach($sizes as $j => $size)
			$boundsSorted[] = $bounds[$j];

		// todo: here drop nested intervals, if any

		return $boundsSorted;
	}

	public static function getMap()
	{
		return array(

			'ID' => array(
				'data_type' => 'integer',
				'primary' => true,
				'autocomplete' => true,
			),
			'WORD' => array(
				'data_type' => 'string',
			),
			'POSITION' => array(
				'data_type' => 'integer'
			),

			'CNT' => array(
				'data_type' => 'integer',
				'expression' => array(
					'count(*)'
				)
			),
		);
	}
}


Youez - 2016 - github.com/yon3zu
LinuXploit