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/acrit.cleanmaster/classes/general/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/cvetdv.ru/bitrix/modules/acrit.cleanmaster/classes/general/ccleanupload.php
<?php
/** @noinspection SqlResolve */
/** @noinspection SqlNoDataSourceInspection */

use \Acrit\Cleanmaster\Data\UploadBfileindexTable,
	\Acrit\Cleanmaster\Data\UploadFilelostTable,
	\Acrit\Cleanmaster\Helpers\UpoadFilterIterator;
use Bitrix\Main\Config\Option;

final class CCleanUpload extends TCleanMasterFunctions
{
	private     $documentRoot;
	public      $mediaCount;
	private     $knownFolders;

	// value used if no config by this setting
	public const PER_STEP_PROCESS_FILES = 2000;

	public function __construct()
	{
		$this->documentRoot = Bitrix\Main\Application::getDocumentRoot();
		$this->knownFolders = ['tmp', 'resize_cache', '1c_catalog', '1c_exchange', 'cleanmaster', 'uf', '.htaccess', 'medialibrary', 'rk'];
		foreach (['/bitrix/modules', '/local/modules'] as $p) {
			if (! is_dir($this->documentRoot . $p)) {
				continue;
			}

			$idir = new DirectoryIterator($this->documentRoot . $p);
			foreach ($idir as $v) {
				if ($v->isDot()) {
					continue;
				}
				if ($v->isDir()) {
					$this->knownFolders[] = $v->getBasename();
				}
			}
		}

		$this->mediaCount = (int)Option::get(\CCleanMain::MODULE_ID, 'CCleanUpload_PER_STEP_PROCESS_FILES', self::PER_STEP_PROCESS_FILES);
		if (!$this->mediaCount) {
			$this->mediaCount = self::PER_STEP_PROCESS_FILES;
		}
	}

	/**
	 * Сколько обрабатывать за шаг (2000 файлов)
	 * @return int
	 */
	public function GetStepCount(): int
	{
		return $this->mediaCount;
	}

	/**
	 * получить кол-во записей в таблице b_file
	 * @return integer
	 */
	public function GetCount(): int
	{
		global $DB;
		$arCount = $DB->Query("SELECT count(ID) AS CNT FROM b_file")->Fetch();
		return (int)$arCount['CNT'];
	}

	/**
	 * получить кол-во записей в таблице b_file
	 * @return integer
	 * @deprecated
	 */
	public function GetCountEx(): int
	{
		return 0;
	}

	/**
	 * Получить строки из b_file
	 *
	 * @param $step
	 *
	 * @return array|bool
	 */
	public function GetRows($step)
	{
		global $DB;
		$count = $this->GetStepCount();
		$start = $step * $count;

		$files = [];
		$dbFiles = $DB->Query("SELECT * FROM b_file LIMIT $count OFFSET $start");
		while ($arFile = $dbFiles->Fetch()) {
			$files[] = $arFile;
		}
		return is_array($files) ? $files : false;
	}

	/**
	 * Получить ВСЕ строки из b_file (cron)
	 * @return array|bool
	 */
	public function GetRowsFull()
	{
		global $DB;
		$files = [];

		$dbFiles = $DB->Query("SELECT * FROM b_file");
		while ($arFile = $dbFiles->Fetch()) {
			$files[] = $arFile;
		}
		return is_array($files) ? $files : false;
	}

	public function DeleteTempDir($step = false, $delete_resize_cache = 'N'): bool
	{
		if (file_exists($this->documentRoot . '/upload/tmp')) {
			DeleteDirFilesEx('/upload/tmp/');
		}

		if ($delete_resize_cache == 'Y') {
			// its used in admin lists
			if (file_exists($this->documentRoot . '/upload/resize_cache')) {
				DeleteDirFilesEx('/upload/resize_cache/');
			}

			// drop resize_cache need drop cache
			$cleanCache = new CCleanCache;
			$cleanCache->CacheClear();
		}

		if (file_exists($this->documentRoot . '/upload/1c_catalog')) {
			DeleteDirFilesEx('/upload/1c_catalog/');
		}

		$temp_upload = '/upload/cleanmaster/';
		$this->SetPermission($this->documentRoot . $temp_upload, 0777);
		DeleteDirFilesEx($temp_upload);

		return false;
	}

	/**
	 * Откат с папки /upload/cleanmaster/
	 */
	public function RevertTmpDir(): void
	{
		$path = $this->documentRoot . '/upload/cleanmaster';
		$idir = new RecursiveIteratorIterator(
			new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST
		);
		foreach ($idir as $v) {
			/* @var $v \SplFileInfo */
			if ($v->isFile()) {
				$p = str_replace('/upload/cleanmaster', '', $idir->key());
				CheckDirPath($p);
				copy($idir->key(), $p);
			}
		}
		$this->ClearTmpDir();
	}

	public function ClearTmpDir(): void
	{
		DeleteDirFilesEx('/upload/cleanmaster/');
	}

	public function fillBfileIndex($step, $noLimit = false)
	{
		$step = (int)$step;
		if ($step == 0) {
			UploadBfileindexTable::clearTable();
		}

		$cntSteps = $this->getCountStepsBfileIndex();

		if ($noLimit === true) {
			$records = $this->GetRowsFull();
		} else {
			$records = $this->GetRows($step);
		}

		foreach ($records as $record) {
			$record['F_PATH'] = \CFile::GetFileSRC($record, false, false);
			UploadBfileindexTable::add([
				'F_PATH' => $record['F_PATH'],
				'FILE_ID' => $record['ID']
			]);
		}

		$step++;
		if ($step > $cntSteps - 1) { // step from zero
			return false;
		}

		return $step;
	}

	public function getCountStepsBfileIndex(): float
	{
		$cntRows = $this->GetCount();
		$cntPerStep = $this->GetStepCount();
		$cntSteps = ceil($cntRows / $cntPerStep);

		return $cntSteps;
	}

	/**
	 * folder may be too big, optional to run method
	 * @return float
	 */
	public function getCountStepsDiagnosticData(): float
	{
		$cntFiles = 0;

		$directory = new \RecursiveDirectoryIterator($this->documentRoot . '/upload',
			\FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS
		);
		$filter = new UpoadFilterIterator($directory);
		$fsi = new \RecursiveIteratorIterator($filter);
		foreach ($fsi as $f) {
			$cntFiles++;
		}

		return ceil($cntFiles / $this->GetStepCount());
	}


	public function GetDiagnosticData($step, bool $noLimit = false): bool
	{
		$step = (int)$step;
		if ($step == 0) {
			$_SESSION['cleanmaster']['diagnostic']['upload']['dbSize'] = 0;
			$_SESSION['cleanmaster']['diagnostic']['upload']['dirs'] = [];
			//$_SESSION['cleanmaster']['diagnostic']['upload']['dirSize']['.'] = $this->GetUploadSize($this->documentRoot.'/upload/');
			UploadFilelostTable::clearTable();
			$_SESSION['cleanmaster']['diagnostic']['upload']['lost_file_size'] = 0;
		}

		$directory = new \RecursiveDirectoryIterator($this->documentRoot . '/upload',
			\FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS
		);
		$filter = new UpoadFilterIterator($directory);
		$fsi = new \RecursiveIteratorIterator($filter);


		$cntPerStep = $this->GetStepCount();
		$fileISkip = $step * $cntPerStep;
		$fileI = 0;

		$filenames = [];
		foreach ($fsi as $f) {
			/* @var $f SplFileInfo */
			if ($fileISkip > 0) {
				$fileISkip--;
				continue;
			}

			$filename = str_replace('\\', '/', $f->getRealPath());
			$filename = str_replace(realpath($this->documentRoot . '/upload'), '/upload', $filename);       // upload like symlink-folder

			$filenames[] = $filename;

			if (!$noLimit) {
				if ((++$fileI % $cntPerStep) === 0) {
					break;
				}
			}
		}

		if (count($filenames) > 0) {
			$filenamesRegistered = [];
			$rsRows = UploadBfileindexTable::getList([
				'select' => ['F_PATH'],
				'filter' => ['=F_PATH' => $filenames],
			]);
			while ($row = $rsRows->fetch()) {
				$filenamesRegistered[] = $row['F_PATH'];
			}
			$toDelete = array_diff($filenames, $filenamesRegistered);
			foreach ($toDelete as $filename) {
				UploadFilelostTable::add([
					'F_PATH' => $filename,
					'SIZE' => filesize($this->documentRoot . $filename)
				]);
			}
		}

		if ($fileISkip > 0) {
			$_SESSION['cleanmaster']['diagnostic']['upload']['lost_file_size'] = UploadFilelostTable::getLostSize();
		}
		return ($fileISkip == 0);
	}

	/**
	 * Для интерфейса, отчет какие файлы будут удалены
	 *
	 * @param $dirSizes = array() заранее известные размеры папок (если известны)
	 * @param $limit = 0 сколько строк выбрать сверху
	 * @param $subselectTmps = true
	 * @param bool $showStrangeFiles = true показывать найденные странные файлы в папке upload
	 *
	 * @return array
	 * @throws \Bitrix\Main\ArgumentException
	 */
	public function getDiagnosticListFiles($dirSizes = [], $limit = 0, $subselectTmps = true, $showStrangeFiles = true): array
	{
		$r = $ra = [];

		$arS = [
			'select' => ['*'],
			'order' => ['ID' => 'asc']
		];
		if ((int)$limit > 0) {
			$arS['limit'] = $limit;
		}
		$rows = UploadFilelostTable::getList($arS);
		while ($row = $rows->fetch()) {
			$r[] = $row['F_PATH'] . ' (' . \CFile::FormatSize($row['SIZE']) . ')';
			//$row['SIZE'] = 0; // recalc with getDiagnosticListFilesFullSize() method
			$ra[] = $row;
		}

		if ($subselectTmps) {
			$tmpDirsAll = [];
			$tmpDirs = [
				'/upload/tmp/',
				//  '/upload/resize_cache/',        // TODO folder is too big, make stepper on size of it
				'/upload/1c_catalog/',
				'/upload/cleanmaster/'
			];
			foreach ($tmpDirs as &$d) {
				$dt = str_replace(['/upload/', '/'], '', $d);
				if (isset($dirSizes[$dt])) {
					$size = $dirSizes[$dt];
				} else {
					$size = $this->GetDirSize($this->documentRoot . $d) * 1024 * 1024;
				}
				$tmpDirsAll[] = [
					'F_PATH' => $d,
					'SIZE' => $size
				];
				$d = $d . ' (' . \CFile::FormatSize($size) . ')';
			}
			unset($d);

			$r = array_merge($r, $tmpDirs);
			$ra = array_merge($ra, $tmpDirsAll);
			unset($tmpDirs, $tmpDirsAll);
		}

		if ($showStrangeFiles) {
			$tmpDirsAll = $tmpDirs = [];
			$idir = new DirectoryIterator($this->documentRoot . '/upload');
			foreach ($idir as $v) {
				if ($v->isDot() || in_array($v->getBasename(), $this->knownFolders)) {
					continue;
				}
				$size = 0;
				if ($v->isDir()) {
					$size = $this->GetDirSize($this->documentRoot . '/upload/' . $v->getBasename()) * 1024 * 1024;
				} else if ($v->isFile()) {
					$size = $v->getSize();
				}
				$tmpDirs[] = '/upload/' . $v->getBasename() . ' (' . \CFile::FormatSize($size) . ')';
				$tmpDirsAll[] = [
					'F_PATH' => '/upload/' . $v->getBasename(),
					'SIZE' => $size,
					'IS_MANUAL_CHECK' => 'Y'
				];
			}
			$r = array_merge($r, $tmpDirs);
			$ra = array_merge($ra, $tmpDirsAll);
			unset($tmpDirs, $tmpDirsAll);
		}

		$returMod = [
			'r' => $r,
			'ra' => $ra
		];

		return $returMod;
	}

	public function getDiagnosticListFilesFullSize(): float
	{
		global $DB;
		$r = $DB->Query('SELECT SUM(SIZE) AS `SUM` FROM ' . UploadFilelostTable::getTableName())->Fetch();
		return (float)$r['SUM'];
	}

	public function DeleteLostFiles($step, $noLimit = false)
	{
		$temp_upload = $this->documentRoot . '/upload/cleanmaster/';
		if (!file_exists($temp_upload)) {
			/** @noinspection MkdirRaceConditionInspection */
			mkdir($temp_upload);
			$this->SetPermission($temp_upload, 0777);
		}

		$params = [
			'select' => ['*'],
			'order' => ['ID' => 'asc'],
			'limit' => 200,
		];
		if ($noLimit === true) {
			unset($params['limit']);
		}
		$rows = UploadFilelostTable::getList($params);
		$bFinded = false;

		while ($row = $rows->fetch()) {
			$bFinded = true;

			CheckDirPath($temp_upload . $row['F_PATH']);
			copy($this->documentRoot . $row['F_PATH'], $temp_upload . $row['F_PATH']);
			unlink($this->documentRoot . $row['F_PATH']);
			UploadFilelostTable::delete($row['ID']);
		}

		return $bFinded;
	}

	public function getCountStepsDeleteLostFiles(): float
	{
		return ceil(UploadFilelostTable::getCntRows() / 200);
	}


	/**
	 * Получаем размер папок и сохраняем в сессию для диагностики
	 * (только временных папок tmp + resize_cache)
	 *
	 * @param     $path
	 * @param int $level
	 *
	 * @return float|int
	 * @deprecated
	 */
	private function GetUploadSize($path, $level = 1)
	{
		$files = scandir($path, SCANDIR_SORT_NONE);
		$size = 0;
		if (is_array($files)) {
			foreach ($files as $file) {
				if ($file == '.' || $file == '..' || ($level == 1 && !in_array($file, ['tmp', 'cleanmaster', 'resize_cache', '1c_catalog']))) {
					continue;
				}
				if (is_dir($path . $file)) {
					$dirSize = $this->GetUploadSize($path . $file . '/', $level + 1);
					if ($level == 1) {
						$_SESSION['cleanmaster']['diagnostic']['upload']['dirSize'][$file] = $dirSize;
					}
					$size += $dirSize;
				} else {
					$size += filesize($path . $file) / 1024 / 1024;
				}
			}
		}
		return $size;
	}


} // end class

Youez - 2016 - github.com/yon3zu
LinuXploit