%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /proc/self/root/home/bitrix/www/bitrix/modules/sale/lib/location/search/
Upload File :
Create Path :
Current File : //proc/self/root/home/bitrix/www/bitrix/modules/sale/lib/location/search/chain.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__);

final class ChainTable extends Entity\DataManager implements \Serializable
{
	const STEP_SIZE = 	10000;
	const MTU = 		9999;

	protected $procData = 		array();
	protected $indexInserter = 	null;

	public static function getFilePath()
	{
		return __FILE__;
	}

	public static function getTableName()
	{
		return 'b_sale_loc_search_chain';
	}

	public function serialize()
	{
		return serialize($this->procData);
	}
	public function unserialize($data)
	{
		$this->procData = unserialize($data);
		$this->initInsertHandles();
	}

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

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

		$typeSort = array();
		$res = Location\TypeTable::getList(array('select' => array('ID', 'CODE', 'DISPLAY_SORT')));

		$this->procData['TYPES'] = array();
		$this->procData['TYPE_SORT'] = array();

		while($item = $res->fetch())
		{
			if(!is_array($this->procData['ALLOWED_TYPES']) || (is_array($this->procData['ALLOWED_TYPES']) && in_array($item['ID'], $this->procData['ALLOWED_TYPES'])))
				$this->procData['TYPES'][$item['CODE']] = $item['ID'];

			$this->procData['TYPE_SORT'][$item['ID']] = $item['DISPLAY_SORT'];
		}

		$this->procData['TYPES_BACK'] = array_flip($this->procData['TYPES']);

		$this->initInsertHandles();
	}

	public function initInsertHandles()
	{
		$this->indexInserter = new BlockInserter(array(
			'entityName' => '\Bitrix\Sale\Location\Search\ChainTable',
			'exactFields' => array(
				'LOCATION_ID', 'RELEVANCY', 'POSITION'
			),
			'parameters' => array(
				'mtu' => static::MTU
			)
		));
	}

	public function resetProcess()
	{
		$this->procData = array(
			'OFFSET' => 	0,
			'DEPTH' => 	0,
			'PATH' => 			array(),
		);
	}

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

	public static function cleanUpData()
	{
		Helper::dropTable(static::getTableName());

		Main\HttpApplication::getConnection()->query("create table ".static::getTableName()." (

			LOCATION_ID ".Helper::getSqlForDataType('int').",
			RELEVANCY ".Helper::getSqlForDataType('int')." default '0',
			POSITION ".Helper::getSqlForDataType('int')." default '0',

			primary key (POSITION, LOCATION_ID)

		)");
	}

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

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

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

		return $filter;
	}

	protected static function rarefact($sorts, $window = 10000)
	{
		if(!intval($window))
			$window = 10000;

		$rSorts = array();
		$w = $window;
		if(is_array($sorts))
		{
			asort($sorts);

			foreach($sorts as $id => $sort)
			{
				$rSorts[$id] = $w;
				$w += $window;
			}
		}

		return $rSorts;
	}

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

		$res = Location\LocationTable::getList(array(
			'select' => array(
				'ID', 
				'TYPE_ID',
				'DEPTH_LEVEL',
				'SORT'
			),
			//'filter' => static::getFilterForInitData(array('TYPES' => $this->procData['ALLOWED_TYPES'])),
			'order' => array(
				'LEFT_MARGIN' => 'asc'
			),
			'limit' => self::STEP_SIZE,
			'offset' => $this->procData['OFFSET']
		));

		$this->procData['TYPE_SORT'] = $this->rarefact($this->procData['TYPE_SORT']);

		$cnt = 0;
		while($item = $res->fetch())
		{
			// tmp!!!!
			//$name = Location\Name\LocationTable::getList(array('select' => array('NAME'), 'filter' => array('=LOCATION_ID' => $item['ID'], '=LANGUAGE_ID' => 'ru')))->fetch();

			if($item['DEPTH_LEVEL'] < $this->procData['DEPTH'])
			{
				$newPC = array();

				foreach($this->procData['PATH'] as $dl => $id)
				{
					if($dl >= $item['DEPTH_LEVEL'])
						break;

					$newPC[$dl] = $id;
				}

				$this->procData['PATH'] = $newPC;
			}

			$this->procData['PATH'][$item['DEPTH_LEVEL']] = array(
				'TYPE' => $item['TYPE_ID'],
				'ID' => $item['ID']
			);

			if(is_array($this->procData['ALLOWED_TYPES']) && in_array($item['TYPE_ID'], $this->procData['ALLOWED_TYPES']))
			{
				$data = array(
					'LOCATION_ID' => $item['ID'],
					'RELEVANCY' => $this->procData['TYPE_SORT'][$item['TYPE_ID']] + $item['SORT'],// * $item['DEPTH_LEVEL'], // tmp, will be more complicated calc here later
				);
				$wordsAdded = array();

				/*
				_dump_r('############################');
				_dump_r('LOCATION: '.$name['NAME']);
				_dump_r('TYPE RELEVANCY: '.$data['RELEVANCY']);
				_dump_r('PATH:');
				_dump_r($this->procData['PATH']);
				*/

				$this->procData['DEPTH'] = $item['DEPTH_LEVEL'];

				// pre-load missing words
				$wordCount = 0;
				foreach($this->procData['PATH'] as &$pathItem)
				{
					if(!isset($pathItem['WORDS'])) // words were not loaded previously for this part of the path
					{
						$sql = "
							select WS.POSITION from ".WordTable::getTableNameWord2Location()." WL
								inner join ".WordTable::getTableName()." WS on WL.WORD_ID = WS.ID
							where
								WL.LOCATION_ID = '".intval($pathItem['ID'])."'
						";

						$wordRes = $dbConnection->query($sql);

						$pathItem['WORDS'] = array();
						while($wordItem = $wordRes->fetch())
						{
							$pathItem['WORDS'][] = $wordItem['POSITION'];
						}
						$pathItem['WORDS'] = array_unique($pathItem['WORDS']);
					}

					$wordCount += count($pathItem['WORDS']);
				}

				// count words
				//_dump_r('Words total: '.$wordCount);

				$wOffset = 0;
				foreach($this->procData['PATH'] as &$pathItem)
				{
					foreach($pathItem['WORDS'] as $i => $position)
					{
						$wordWeight = $wordCount - $wOffset;

						$tmpData = $data;
						$tmpData['RELEVANCY'] += $wordWeight;

						//_dump_r('	Word relevancy: '.$data['RELEVANCY'].' ==>> '.$tmpData['RELEVANCY']);

						if(!isset($wordsAdded[$position]))
						{
							$this->indexInserter->insert(array_merge(array('POSITION' => $position), $tmpData));
							$wordsAdded[$position] = true;
						}

						$wOffset++;
					}
				}
				unset($pathItem);

			}

			$cnt++;
		}

		$this->indexInserter->flush();

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

		return !$cnt;
	}

	public static function createIndex()
	{
		Helper::createIndex(static::getTableName(), 'LPR', array('LOCATION_ID', 'POSITION', 'RELEVANCY'));
	}

	public static function getMap()
	{
		return array(

			'LOCATION_ID' => array(
				'data_type' => 'integer',
				'primary' => true
			),
			'POSITION' => array(
				'data_type' => 'integer',
				'primary' => true
			),

			'RELEVANCY' => array(
				'data_type' => 'integer',
			)
		);
	}
}


Zerion Mini Shell 1.0