<commit_before><?php
class kUploadTokenMgr
{
	const NO_EXTENSION_IDENTIFIER = 'noex';
	const AUTO_FINALIZE_CACHE_TTL = 2592000; //Thirty days in seconds
	const MAX_AUTO_FINALIZE_RETIRES = 5;
	const MAX_APPEND_TIME = 5;
	const MAX_CHUNKS_WAITING_FOR_CONCAT_ALLOWED = 1000;
	const CHUNK_SIZE = 102400;
	const ENTRY = 'entry';
	const FLAVOR = 'flavorAsset';

	/**
	 * @var UploadToken
	 */
	protected $_uploadToken;
	
	/**
	 * @var bool
	 */
	private $_autoFinalize;
	
	/**
	 * @var bool
	 */
	private $_finalChunk;
	
	/**
	 * @var kBaseCacheWrapper
	 */
	private $_autoFinalizeCache;
	
	/**
	 * @var bool
	 * Is direct upload to shared storage enabled
	 */
	private static $sharedUploadModeEnabled;
	
	/**
	 * SharedStorageOptions
	 * @var kFileTransferMgr
	 */
	private static $sharedStorageOptions;
	
	/**
	 * Construct new upload token manager for the upload token object
	 * @param UploadToken $uploadToken
	 */
	public function __construct(UploadToken $uploadToken, $finalChunk = true)
	{
		KalturaLog::info("Init for upload token id [{$uploadToken->getId()}]");
		$this->_uploadToken = $uploadToken;
		$this->_finalChunk = $finalChunk;
		
		$remoteChunkUploadDir = kConf::get("remote_chunk_upload_dir", "runtime_config", null);
		$uploadTempPath = $this->_uploadToken->getUploadTempPath();
		if($uploadTempPath && strpos($uploadTempPath, $remoteChunkUploadDir))
		{
			self::initStorageOptions($this->_uploadToken->getId());
		}
	}
	
	private static function initStorageOptions($uploadTokenId)
	{
		self::$sharedStorageOptions = kConf::get("shared_storage_client_config", "runtime_config", array());
		
		//If we received empty array or sharedStorageBaseDir is not defined us legacy nfs upload
		if(!count(self::$sharedStorageOptions) || !isset(self::$sharedStorageOptions['s3Region']) || !isset(self::$sharedStorageOptions['sharedStorageBaseDir']))
		{
			KalturaLog::debug("Failed to load shared storage client config, will revert to using NFS for shared storage");
			self::$sharedUploadModeEnabled = false;
			return;
		}
		
		self::$sharedStorageOptions['uploadTokenId'] = $uploadTokenId;
		self::$sharedUploadModeEnabled = true;
	}
	
	private function initUploadTokenMemcache()
	{
		$cache = kCacheManager::getSingleLayerCache(kCacheManager::CACHE_TYPE_UPLOAD_TOKEN);
		if (!$cache)
			throw new kUploadTokenException("Cache instance required for AutoFinalize functionality Could not initiated", kUploadTokenException::UPLOAD_TOKEN_AUTO_FINALIZE_CACHE_NOT_INITIALIZED);
		
		$this->_autoFinalizeCache = $cache;
		$this->_autoFinalizeCache->add($this->_uploadToken->getId() . ".retries", self::MAX_AUTO_FINALIZE_RETIRES, 86400);
	}
	
	/**
	 * Set default values and save the new upload token
	 */
	public function saveAsNewUploadToken()
	{
		$this->_uploadToken->setStatus(UploadToken::UPLOAD_TOKEN_PENDING);
		$this->_uploadToken->setUploadedFileSize(null);
		$this->_uploadToken->setUploadTempPath(null);
		$this->_uploadToken->setUserIp(requestUtils::getRemoteAddress());
		$this->_uploadToken->setDc(kDataCenterMgr::getCurrentDcId());
		$this->_uploadToken->save();
	}
	
	/**
	 * Get the current upload token used by the manager
	 */
	public function getUploadToken()
	{
		return $this->_uploadToken;
	}
	
	/**
	 * Upload a file to the current upload token
	 * @param file $fileData
	 * @param bool $resume
	 * @param bool $finalChunk
	 * @param int $resumeAt
	 * @throw kUploadTokenException
	 */
	public function uploadFileToToken($fileData, $resume = false, $resumeAt = -1)
	{
		$this->_autoFinalize = $this->_uploadToken->getAutoFinalize();
		if($this->_autoFinalize)
		{
			$this->initUploadTokenMemcache();
		}
		
		$allowedStatuses = array(UploadToken::UPLOAD_TOKEN_PENDING, UploadToken::UPLOAD_TOKEN_PARTIAL_UPLOAD);
		if (!in_array($this->_uploadToken->getStatus(), $allowedStatuses, true))
			throw new kUploadTokenException("Invalid upload token status", kUploadTokenException::UPLOAD_TOKEN_INVALID_STATUS);

		$this->updateFileName($fileData);
		
		try
		{
			$this->checkIfFileIsValid($fileData, $resumeAt, $this->_finalChunk);
		}
		catch(kUploadTokenException $ex)
		{
			if($ex->getCode() == kUploadTokenException::UPLOAD_TOKEN_FILE_IS_EMPTY)
			{
				return;
			}
			
			if(!$resume && $this->_finalChunk)
			{
				kFlowHelper::handleUploadFailed($this->_uploadToken);
			}
			
			$this->tryMoveToErrors($fileData);
			throw $ex;
		}
		
		if ($resume)
		{
			$fileSize = $this->handleResume($fileData, $resumeAt);
		}
		else
		{
			$this->handleMoveFile($fileData);
			$fileSize = kFile::fileSize($this->_uploadToken->getUploadTempPath());
		}
		
		if ($this->_finalChunk)
		{
			if(myUploadUtils::isFileTypeRestricted($this->_uploadToken->getUploadTempPath(), $fileData['name']) && $fileSize)
			{
				kFlowHelper::handleUploadFailed($this->_uploadToken);
				throw new kUploadTokenException("Restricted upload token file type", kUploadTokenException::UPLOAD_TOKEN_FILE_TYPE_RESTRICTED);
			}
			$this->_uploadToken->setStatus(UploadToken::UPLOAD_TOKEN_FULL_UPLOAD);
		}
		else
		{
			//We return null file size when we want to fail the upload since it reached max chunks waiting for concat
			$this->_uploadToken->setStatus(!is_null($fileSize) ? UploadToken::UPLOAD_TOKEN_PARTIAL_UPLOAD : UploadToken::UPLOAD_TOKEN_ERROR);
		}
		
		$this->_uploadToken->setUploadedFileSize($fileSize);
		$this->_uploadToken->setDc(kDataCenterMgr::getCurrentDcId());
		
		$this->_uploadToken->save();
		
		$entry = $this->getAttachedEntry();
		if ($entry && $entry->getType() == entryType::MEDIA_CLIP && !$entry->getMediaType())
		{
			$entry->setMediaType($this->getMediaType());
			$entry->save();
		}
	}
	<commit_msg>PLAT-23764: Add "manage EP" to partner list actions<commit_after><?php
class kUploadTokenMgr
{
	const NO_EXTENSION_IDENTIFIER = 'noex';
	const AUTO_FINALIZE_CACHE_TTL = 2592000; //Thirty days in seconds
	const MAX_AUTO_FINALIZE_RETIRES = 5;
	const MAX_APPEND_TIME = 5;
	const MAX_CHUNKS_WAITING_FOR_CONCAT_ALLOWED = 1000;
	const CHUNK_SIZE = 102400;
	const ENTRY = 'entry';
	const FLAVOR = 'flavorAsset';

	/**
	 * @var UploadToken
	 */
	protected $_uploadToken;
	
	/**
	 * @var bool
	 */
	private $_autoFinalize;
	
	/**
	 * @var bool
	 */
	private $_finalChunk;
	
	/**
	 * @var kBaseCacheWrapper
	 */
	private $_autoFinalizeCache;
	
	/**
	 * @var bool
	 * Is direct upload to shared storage enabled
	 */
	private static $sharedUploadModeEnabled;
	
	/**
	 * SharedStorageOptions
	 * @var kFileTransferMgr
	 */
	private static $sharedStorageOptions;
	
	/**
	 * Construct new upload token manager for the upload token object
	 * @param UploadToken $uploadToken
	 */
	public function __construct(UploadToken $uploadToken, $finalChunk = true)
	{
		KalturaLog::info("Init for upload token id [{$uploadToken->getId()}]");
		$this->_uploadToken = $uploadToken;
		$this->_finalChunk = $finalChunk;
		
		$remoteChunkUploadDir = kConf::get("remote_chunk_upload_dir", "runtime_config", null);
		$uploadTempPath = $this->_uploadToken->getUploadTempPath();
		if($uploadTempPath && strpos($uploadTempPath, $remoteChunkUploadDir))
		{
			self::initStorageOptions($this->_uploadToken->getId());
		}
	}
	
	private static function initStorageOptions($uploadTokenId)
	{
		self::$sharedStorageOptions = kConf::get("shared_storage_client_config", "runtime_config", array());
		
		//If we received empty array or sharedStorageBaseDir is not defined us legacy nfs upload
		if(!count(self::$sharedStorageOptions) || !isset(self::$sharedStorageOptions['s3Region']) || !isset(self::$sharedStorageOptions['sharedStorageBaseDir']))
		{
			KalturaLog::debug("Failed to load shared storage client config, will revert to using NFS for shared storage");
			self::$sharedUploadModeEnabled = false;
			return;
		}
		
		self::$sharedStorageOptions['uploadTokenId'] = $uploadTokenId;
		self::$sharedUploadModeEnabled = true;
	}
	
	private function initUploadTokenMemcache()
	{
		$cache = kCacheManager::getSingleLayerCache(kCacheManager::CACHE_TYPE_UPLOAD_TOKEN);
		if (!$cache)
			throw new kUploadTokenException("Cache instance required for AutoFinalize functionality Could not initiated", kUploadTokenException::UPLOAD_TOKEN_AUTO_FINALIZE_CACHE_NOT_INITIALIZED);
		
		$this->_autoFinalizeCache = $cache;
		$this->_autoFinalizeCache->add($this->_uploadToken->getId() . ".retries", self::MAX_AUTO_FINALIZE_RETIRES, 86400);
	}
	
	/**
	 * Set default values and save the new upload token
	 */
	public function saveAsNewUploadToken()
	{
		$this->_uploadToken->setStatus(UploadToken::UPLOAD_TOKEN_PENDING);
		$this->_uploadToken->setUploadedFileSize(null);
		$this->_uploadToken->setUploadTempPath(null);
		$this->_uploadToken->setUserIp(requestUtils::getRemoteAddress());
		$this->_uploadToken->setDc(kDataCenterMgr::getCurrentDcId());
		$this->_uploadToken->save();
	}
	
	/**
	 * Get the current upload token used by the manager
	 */
	public function getUploadToken()
	{
		return $this->_uploadToken;
	}
	
	/**
	 * Upload a file to the current upload token
	 * @param file $fileData
	 * @param bool $resume
	 * @param bool $finalChunk
	 * @param int $resumeAt
	 * @throw kUploadTokenException
	 */
	public function uploadFileToToken($fileData, $resume = false, $resumeAt = -1)
	{
		$this->_autoFinalize = $this->_uploadToken->getAutoFinalize();
		if($this->_autoFinalize)
		{
			$this->initUploadTokenMemcache();
		}
		
		$allowedStatuses = array(UploadToken::UPLOAD_TOKEN_PENDING, UploadToken::UPLOAD_TOKEN_PARTIAL_UPLOAD);
		if (!in_array($this->_uploadToken->getStatus(), $allowedStatuses, true))
			throw new kUploadTokenException("Invalid upload token status", kUploadTokenException::UPLOAD_TOKEN_INVALID_STATUS);

		$this->updateFileName($fileData);
		
		try
		{
			$this->checkIfFileIsValid($fileData, $resumeAt, $this->_finalChunk);
		}
		catch(kUploadTokenException $ex)
		{
			if($ex->getCode() == kUploadTokenException::UPLOAD_TOKEN_FILE_IS_EMPTY)
			{
				return;
			}
			
			if(!$resume && $this->_finalChunk)
			{
				kFlowHelper::handleUploadFailed($this->_uploadToken);
			}
			
			$this->tryMoveToErrors($fileData);
			throw $ex;
		}
		
		if ($resume)
		{
			$fileSize = $this->handleResume($fileData, $resumeAt);
		}
		else
		{
			$this->handleMoveFile($fileData);
			$fileSize = kFile::fileSize($this->_uploadToken->getUploadTempPath());
		}
		
		if ($this->_finalChunk)
		{
			if(myUploadUtils::isFileTypeRestricted($this->_uploadToken->getUploadTempPath(), $fileData['name']) && $fileSize)
			{
				kFlowHelper::handleUploadFailed($this->_uploadToken);
				throw new kUploadTokenException("Restricted upload token file type", kUploadTokenException::UPLOAD_TOKEN_FILE_TYPE_RESTRICTED);
			}
			$this->_uploadToken->setStatus(UploadToken::UPLOAD_TOKEN_FULL_UPLOAD);
		}
		else
		{
			//We return null file size when we want to fail the upload since it reached max chunks waiting for concat
			$this->_uploadToken->setStatus(!is_null($fileSize) ? UploadToken::UPLOAD_TOKEN_PARTIAL_UPLOAD : UploadToken::UPLOAD_TOKEN_ERROR);
		}
		
		$this->_uploadToken->setUploadedFileSize($fileSize);
		$this->_uploadToken->setDc(kDataCenterMgr::getCurrentDcId());
		
		$this->_uploadToken->save();
		
		$entry = $this->getAttachedEntry();
		if ($entry && $entry->getType() == entryType::MEDIA_CLIP && !$entry->getMediaType())
		{
			$entry->setMediaType($this->getMediaType());
			$entry->save();
			
			if($entry->getMediaType() == KalturaMediaType::IMAGE)
			{
				$contentResource = new KalturaUploadedFileTokenResource();
				$contentResource->token = $this->_uploadToken->getId();
				$dbContentResource = $contentResource->toObject();
				$dbContentResource->attachCreatedObject($entry);
			}
		}
	}
	
{'fraction_non_alphanumeric': 0.1344762232942798, 'fraction_numerical': 0.004910406616126809, 'mean_word_length': 5.142328042328042, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 135, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1202919', 'n_tokens_mistral': 4111, 'n_tokens_neox': 3737, 'n_words': 679}