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/util/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/sale/lib/location/util/process.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\Util;

use Bitrix\Main;

abstract class Process
{
	const JUST_SHOW_STAGES = 	false;
	const MIN_TIME_LIMIT = 		5;
	const DEBUG_MODE = 			false;
	const DEBUG_FOLDER = 		'%BX_ROOT%/tmp/';
	const DEBUG_FILE = 			'%SESSION_KEY%_process.txt';
	const LOCK_FILE = 			'%SESSION_KEY%_lock';

	const CALLBACK_TYPE_MANUAL =  	'manual';
	const CALLBACK_TYPE_QUOTA = 	'quota';

	protected $stages = 		array();
	protected $stagesByCode = 	array();
	protected $stage = 			0;
	protected $step = 			0;
	protected $data = 			array();
	protected $time = 			0;
	protected $timeLimit = 		20; // in seconds
	protected $sessionKey = 	'long_process';
	protected $useLock = 		false;

	protected $options = 		array();

	public function __construct($options = array())
	{
		if (isset($options['INITIAL_TIME']))
			$this->time = (int)$options['INITIAL_TIME'];
		else
			$this->time = time();

		$this->useLock = (bool)($options['USE_LOCK'] ?? null);
		$this->options = $options;

		$this->restore();

		if (isset($options['STEP']) && $options['STEP'] == 0)
		{
			$this->reset();
		}

		$this->logMessage('#############################', false);
		$this->logMessage('HIT STARTED '.$this->getTimeStampString(), false);

		$timeLimit = (int)($options['TIME_LIMIT'] ?? 0);
		if ($timeLimit > 0)
		{
			$this->setTimeLimit($timeLimit);
		}

		$this->saveStartTime();
		$this->saveMemoryPeak();
	}

	public function addStage($params)
	{
		if (empty($params['CODE']) || empty($params['CALLBACK']))
		{
			throw new Main\SystemException('Not enought params to add stage');
		}

		$ss = (int)($params['STEP_SIZE'] ?? 0);
		$order = count($this->stages);
		$type = (string)($params['TYPE'] ?? '');
		if ($type === '')
		{
			$type = static::CALLBACK_TYPE_MANUAL;
		}

		$beforeCallback = (string)($params['ON_BEFORE_CALLBACK'] ?? '');
		if ($beforeCallback === '')
		{
			$beforeCallback = false;
		}
		$afterCallback = (string)($params['ON_AFTER_CALLBACK'] ?? '');
		if ($afterCallback === '')
		{
			$afterCallback = false;
		}

		$this->stages[] = [
			'STEP_SIZE' => $ss ?: 1,
			'PERCENT' => (int)($params['PERCENT'] ?? 0),
			'CODE' => $params['CODE'],
			'ORDER' => $order,
			'TYPE' => $type,
			'CALLBACK' => $params['CALLBACK'],
			'SUBPERCENT_CALLBACK' => $params['SUBPERCENT_CALLBACK'] ?? null,
			'ON_BEFORE_CALLBACK' => $beforeCallback,
			'ON_AFTER_CALLBACK' => $afterCallback,
		];
		$this->stagesByCode[$params['CODE']] =& $this->stages[count($this->stages) - 1];
	}

	public function restore()
	{
		if(!isset($_SESSION[$this->sessionKey]['STAGE']))
			$_SESSION[$this->sessionKey]['STAGE'] = 0;

		if(!isset($_SESSION[$this->sessionKey]['STEP']))
			$_SESSION[$this->sessionKey]['STEP'] = 0;

		if(!isset($_SESSION[$this->sessionKey]['DATA']))
			$_SESSION[$this->sessionKey]['DATA'] = array();

		$this->stage =& $_SESSION[$this->sessionKey]['STAGE'];
		$this->step =& $_SESSION[$this->sessionKey]['STEP'];
		$this->data =& $_SESSION[$this->sessionKey]['DATA'];
	}

	// reset current condition
	public function reset()
	{
		$this->stage = 0;
		$this->step = 0;
		$this->data = array();

		$this->clearLogFile();

		$this->saveStartTime();
		$this->saveMemoryPeak();
	}

	public function performStage()
	{
		return $this->performIteration();
	}

	public function performIteration()
	{
		if($this->stage == 0 && $this->step == 0)
		{
			$this->lockProcess();

			if(static::DEBUG_MODE)
			{
				$logDir = $this->getLogFileDir();
				if(!file_exists($logDir))
					mkdir($logDir, 755, true);

				$this->logMessage('PROCESS STARTED, STAGE '.$this->stages[0]['CODE']);
			}
		}

		$this->onBeforePerformIteration();

		if(!isset($this->stages[$this->stage]))
			throw new Main\SystemException('No more stages to perform');

		if(self::JUST_SHOW_STAGES)
			$this->nextStage();
		else
		{
			$stage = $this->stage;

			if($this->stages[$stage]['ON_BEFORE_CALLBACK'] != false)
				call_user_func(array($this, $this->stages[$stage]['ON_BEFORE_CALLBACK']));

			if($this->stages[$this->stage]['TYPE'] == static::CALLBACK_TYPE_MANUAL)
				call_user_func(array($this, $this->stages[$this->stage]['CALLBACK']));
			elseif($this->stages[$this->stage]['TYPE'] == static::CALLBACK_TYPE_QUOTA)
			{
				while($this->checkQuota())
				{
					$result = call_user_func(array($this, $this->stages[$this->stage]['CALLBACK']));
					$this->nextStep();

					if($result)
						break;
				}

				if($result)
					$this->nextStage();
			}

			if($this->stages[$stage]['ON_AFTER_CALLBACK'] != false)
				call_user_func(array($this, $this->stages[$stage]['ON_AFTER_CALLBACK']));
		}

		$this->onAfterPerformIteration();
		$percent = $this->getPercent();

		$this->saveMemoryPeak();

		$this->logMessage('HIT ENDED '.$this->getTimeStampString(), false);

		if($percent == 100)
			$this->unLockProcess();

		return $percent;
	}

	/////////////////////////////////////////////////
	/// Staging
	/////////////////////////////////////////////////

	public function setStepSize($code, $stepSize)
	{
		if(!isset($this->stagesByCode[$code]))
			throw new Main\SystemException('Unknown stage code passed');

		if(($stepSize = intval($stepSize)) <= 0)
			throw new Main\SystemException('Bad step size passed');

		$this->stagesByCode[$code]['STEP_SIZE'] = $stepSize;
	}

	// move to next stage
	public function nextStage()
	{
		$this->stage++;
		$this->step = 0;

		if ($this->stage < count($this->stages))
		{
			$stageCode = $this->stages[$this->stage]['CODE'] ?? 'UNDEFINED for '.$this->stage;
		}
		else
		{
			$stageCode = 'FINAL';
		}

		$this->logMessage(
			'### NEXT STAGE >>> ' . $stageCode
			. ' in ' . $this->getElapsedTimeString()
			. ', mem peak = ' . $this->getMemoryPeakString() . ' mb'
		);
	}

	// move to next step
	public function nextStep()
	{
		$this->step++;
	}

	public function isStage($code)
	{
		return $this->stages[$this->stage]['CODE'] == $code;
	}

	protected function stageCompare($code, $way)
	{
		$currIndex = $this->stages[$this->stage]['ORDER'];
		$stageIndex = $this->stagesByCode[$code]['ORDER'];

		if($currIndex == $stageIndex) return true;

		if($way) // gt
			return $currIndex > $stageIndex;
		else // lt
			return $currIndex < $stageIndex;
	}

	// $this->stage <= $code
	public function stageLT($code)
	{
		return $this->stageCompare($code, false);
	}

	// $code <= $this->stage
	public function stageGT($code)
	{
		return $this->stageCompare($code, true);
	}

	public function setStage($stage)
	{
		foreach($this->stages as $sId => $info)
		{
			if($info['CODE'] == $stage)
			{
				$this->stage = $sId;
				$this->step = 0;
				break;
			}
		}
	}

	public function onBeforePerformIteration()
	{
	}

	public function onAfterPerformIteration()
	{
	}

	public function getStageCode()
	{
		return $this->stages[$this->stage]['CODE'] ?? '';
	}
	public function getCurrStageIndex()
	{
		return $this->stage;
	}

	public function getStep()
	{
		return $this->step;
	}

	public function getStage($code)
	{
		return $this->stagesByCode[$code];
	}

	public function getCurrStageStepSize()
	{
		return $this->stages[$this->stage]['STEP_SIZE'];
	}

	/////////////////////////////////////////////////
	/// Percentage
	/////////////////////////////////////////////////

	public function getStagePercent($sNum = false)
	{
		if ($sNum === false)
		{
			$stage = $this->stages[$this->stage]['PERCENT'] ?? 0;
		}
		else
		{
			if (is_numeric($sNum))
			{
				$stage = $this->stages[$sNum]['PERCENT'] ?? 0;
			}
			else
			{
				$stage = $this->stagesByCode[$sNum]['PERCENT'] ?? 0;
			}
		}

		return $stage ?: 0;
	}

	public function getPercentBetween($codeFrom, $codeTo)
	{
		return $this->getStagePercent($codeTo) - $this->getStagePercent($codeFrom);
	}

	public function getPercentFromToCurrent($codeFrom){
		return $this->getStagePercent($this->stage - 1) - $this->getStagePercent($codeFrom);
	}

	public function getCurrentPercentRange()
	{
		return $this->getStagePercent($this->stage) - $this->getStagePercent($this->stage - 1);
	}

	public function getPercent()
	{
		$percent = $this->stage > 0 ? $this->stages[$this->stage - 1]['PERCENT'] : 0;

		$addit = 0;
		$cb = (string)($this->stages[$this->stage]['SUBPERCENT_CALLBACK'] ?? '');
		if ($cb !== '' && method_exists($this, $cb))
		{
			$addit = $this->$cb();
		}

		return $percent + $addit;
	}

	public function calcSubPercent($range)
	{
		if(!$range) return 0;

		return round(($this->step / $range)*($this->getStagePercent($this->stage) - $this->getStagePercent($this->stage - 1)));
	}

	public function getSubPercentByTotalAndDone($total, $done = 0)
	{
		if(!$done || !$total)
			return 0;

		$pRange = $this->getCurrentPercentRange();
		$part = round($pRange * ($done / $total));

		return $part >= $pRange ? $pRange : $part;
	}

	/////////////////////////////////////////////////
	/// Quotas info
	/////////////////////////////////////////////////

	public function checkQuota()
	{
		return (time() - $this->time) < $this->timeLimit;
	}

	public function setTimeLimit($timeLimit)
	{
		$timeLimit = (int)$timeLimit;
		if ($timeLimit > 0)
		{
			$this->timeLimit = max($timeLimit, static::MIN_TIME_LIMIT);
		}
	}

	public function getMemoryPeak()
	{
		return $this->data['memory_peak'];
	}

	protected function saveStartTime()
	{
		if (!isset($this->data['process_time']))
		{
			$this->data['process_time'] = time();
		}
	}

	protected function saveMemoryPeak()
	{
		$mp = memory_get_peak_usage(false);

		if (!isset($this->data['memory_peak']))
		{
			$this->data['memory_peak'] = $mp;
		}
		else
		{
			if ($this->data['memory_peak'] < $mp)
			{
				$this->data['memory_peak'] = $mp;
			}
		}
	}

	/////////////////////////////////////////////////
	/// Logging
	/////////////////////////////////////////////////

	public function clearLogFile()
	{
		$logDir = $this->getLogFileDir();

		if(!Main\IO\Directory::isDirectoryExists($logDir))
			Main\IO\Directory::createDirectory($logDir);

		$logFile = $this->getLogFilePath();

		Main\IO\File::putFileContents($logFile, '');
	}

	public function getLogFileDir()
	{
		return $_SERVER['DOCUMENT_ROOT'].'/'.str_replace('%BX_ROOT%', BX_ROOT, self::DEBUG_FOLDER);
	}

	public function getLogFilePath()
	{
		return $this->getLogFileDir().str_replace('%SESSION_KEY%', $this->sessionKey, self::DEBUG_FILE);
	}

	public function logMessage($message = '', $addTimeStamp = true)
	{
		if(!static::DEBUG_MODE || !mb_strlen($message))
			return;

		file_put_contents(
			$this->getLogFilePath(),
			($addTimeStamp ? $this->getTimeStampString().' ' : '').$message.PHP_EOL,
			FILE_APPEND
		);
	}

	public function logMemoryUsage()
	{
		$this->logMessage('MEMORY USAGE: '.(memory_get_usage(false) / (1024 * 1024)).' MB', false);
	}

	public function logFinalResult()
	{
		$this->logMessage('ALL DONE!');

		$this->logMessage('TOTAL PROCESS TIME: '.$this->getElapsedTimeString(), false);
		$this->logMessage('MEMORY PEAK (mb): '.$this->getMemoryPeakString(), false);
	}

	/////////////////////////////////////////////////
	/// Lock
	/////////////////////////////////////////////////

	public function getLockFilePath()
	{
		return $this->getLogFileDir().str_replace('%SESSION_KEY%', $this->sessionKey, self::LOCK_FILE);
	}

	public function lockProcess()
	{
		if(!$this->useLock)
			return;

		file_put_contents($this->getLockFilePath(), '1');
	}

	public function unLockProcess()
	{
		if(!$this->useLock)
			return;

		$file = $this->getLockFilePath();
		if(file_exists($file))
			unlink($file);
	}

	public function checkProcessLocked()
	{
		return $this->useLock && file_exists($this->getLockFilePath());
	}

	/////////////////////////////////////////////////
	/// Diagnostics tools
	/////////////////////////////////////////////////

	protected function getHitTime()
	{
		return time() - $this->time;
	}

	protected function getProcessTime()
	{
		return time() - $this->data['process_time'];
	}

	protected function getProcessTimeString()
	{
		return $this->getTimeString($this->getProcessTime());
	}

	protected function getHitTimeString()
	{
		return $this->getTimeString($this->getHitTime());
	}

	protected function getElapsedTimeString()
	{
		return $this->getProcessTimeString();
	}

	protected function getTimeString($time = 0)
	{
		$h = floor($time / 3600);
		$m = floor(($time - $h * 3600) / 60);
		$s = $time - $h * 3600 - $m * 60;

		if(mb_strlen($m) == 1)
			$m = '0'.$m;

		if(mb_strlen($s) == 1)
			$s = '0'.$s;

		return $h.':'.$m.':'.$s;
	}

	protected function getTimeStampString()
	{
		return '['.date('H:i:s').']';
	}

	protected function getMemoryPeakString()
	{
		return $this->getMemoryPeak() / 1048576;
	}

	/////////////////////////////////////////////////
	/// Util
	/////////////////////////////////////////////////

	public function getData()
	{
		return $this->data;
	}

	// special case for array
	protected function getBlock($from)
	{
		$step = $this->step;

		for($i = 0; $i < $step; $i++)
			next($from);

		$block = array();
		$hadSmth = false;

		for($i = $step; $i <= $step + $this->getCurrStageStepSize(); $i++)
		{
			$code = key($from);

			if(!isset($code))
			{
				break;
			}

			$elem = current($from);
			next($from);

			$hadSmth = true;
			$block[$code] = $elem;

			$this->nextStep();
		}

		if(!$hadSmth)
		{
			$this->nextStage();
			return false;
		}

		return $block;
	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit