uawdijnntqw1x1x1
IP : 3.144.201.213
Hostname : axolotl
Kernel : Linux axolotl 4.9.0-13-amd64 #1 SMP Debian 4.9.228-1 (2020-07-05) x86_64
Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,
OS : Linux
PATH:
/
var
/
www
/
axolotl
/
data
/
www
/
yar.axolotls.ru
/
52131
/
..
/
bitrix
/
modules
/
disk
/
lib
/
bitrix24disk
/
tmpfile.php
/
/
<?php namespace Bitrix\Disk\Bitrix24Disk; use Bitrix\Disk\Driver; use Bitrix\Disk\Internals\Error\Error; use Bitrix\Disk\Internals\Error\ErrorCollection; use Bitrix\Disk\Internals\Model; use Bitrix\Disk\Internals\TmpFileTable; use Bitrix\Disk\User; use Bitrix\Main\DB\SqlExpression; use Bitrix\Main\IO; use Bitrix\Main\Loader; use Bitrix\Main\Type\DateTime; use CCloudStorageUpload; use CTempFile; class TmpFile extends Model { const ERROR_BUCKET_ID_EMPTY = 'DISK_TMP_FILE_22000'; const ERROR_INCLUDE_CLOUDS = 'DISK_TMP_FILE_22001'; const ERROR_INIT_BUCKET = 'DISK_TMP_FILE_22002'; const ERROR_DELETE_CLOUD_FILE = 'DISK_TMP_FILE_22003'; const ERROR_DELETE_FILE = 'DISK_TMP_FILE_22004'; const ERROR_UPLOAD_MAX_FILE_SIZE = 'DISK_TMP_FILE_22005'; const ERROR_UPLOAD_FILE = 'DISK_TMP_FILE_22015'; const ERROR_IS_NOT_UPLOADED_FILE = 'DISK_TMP_FILE_22016'; const ERROR_MOVE_UPLOADED_FILE = 'DISK_TMP_FILE_22017'; const ERROR_GET_FILE_CONTENTS = 'DISK_TMP_FILE_22020'; const ERROR_CLOUD_APPEND_INVALID_CHUNK_SIZE = 'DISK_TMP_FILE_22018'; const ERROR_CLOUD_START_UPLOAD = 'DISK_TMP_FILE_22019'; const ERROR_CLOUD_UPLOAD_PART = 'DISK_TMP_FILE_22021'; const ERROR_CLOUD_FINISH_UPLOAD = 'DISK_TMP_FILE_22022'; const ERROR_EXISTS_FILE = 'DISK_TMP_FILE_22023'; const ERROR_PUT_CONTENTS = 'DISK_TMP_FILE_22024'; const ERROR_MOVE_FILE = 'DISK_TMP_FILE_22025'; /** @var int */ protected $id; /** @var string */ protected $token; /** @var string */ protected $filename; /** @var string */ protected $contentType; /** @var string */ protected $path; /** @var int */ protected $bucketId; /** @var int */ protected $size; /** @var int */ protected $receivedSize; /** @var int */ protected $width; /** @var int */ protected $height; /** @var bool */ protected $isCloud; /** @var int */ protected $createdBy; /** @var User */ protected $createUser; /** @var DateTime */ protected $createTime; /** @var bool */ protected $isAlreadyDeleted = false; protected $deleteStatus = null; /** @var bool */ protected $isRegisteredShutdownFunction = false; /** * Gets the fully qualified name of table class which belongs to current model. * @throws \Bitrix\Main\NotImplementedException * @return string */ public static function getTableClassName() { return TmpFileTable::className(); } /** * Returns token. * @return string */ public function getToken() { return $this->token; } /** * Returns file name. * @return string */ public function getFilename() { return $this->filename; } /** * Returns content type. * @return string */ public function getContentType() { return $this->contentType; } /** * Returns path. * @return string */ public function getPath() { return $this->path; } /** * Returns id of bucket (only for cloud files). * @return int */ public function getBucketId() { return $this->bucketId; } /** * Returns size in bytes. * @return int */ public function getSize() { return $this->size; } /** * Returns received size of file in bytes. * @return int */ public function getReceivedSize() { return $this->receivedSize; } /** * Returns width. If tmp file is not image, then returns null. * @return int */ public function getWidth() { return $this->width; } /** * Returns height. If tmp file is not image, then returns null. * @return int */ public function getHeight() { return $this->height; } /** * Returns time of create object. * @return DateTime */ public function getCreateTime() { return $this->createTime; } /** * Returns id of user, who created object. * @return int */ public function getCreatedBy() { return $this->createdBy; } /** * Returns user model, who created object. * @return User */ public function getCreateUser() { if(isset($this->createUser) && $this->createdBy == $this->createUser->getId()) { return $this->createUser; } $this->createUser = User::getModelForReferenceField($this->createdBy, $this->createUser); return $this->createUser; } /** * Tells if tmp file locates in cloud. * @return bool */ public function isCloud() { return $this->isCloud && $this->bucketId; } /** * @return \CCloudStorageBucket|null * @throws \Bitrix\Main\LoaderException */ private function getBucket() { if(!$this->bucketId) { $this->errorCollection->addOne(new Error('Could not get bucket. BucketId is empty.', static::ERROR_BUCKET_ID_EMPTY)); return null; } if(!Loader::includeModule('clouds')) { $this->errorCollection->addOne(new Error('Could not include module "clouds".', static::ERROR_INCLUDE_CLOUDS)); return null; } $bucket = new \CCloudStorageBucket($this->bucketId); if (!$bucket->init()) { $this->errorCollection->addOne(new Error('Could not init bucket.', static::ERROR_INIT_BUCKET)); return null; } return $bucket; } /** * Deletes TmpFile. * The method attempts to destroy content (cloud or file from file system). * @return bool */ public function delete() { if($this->isCloud()) { if ($this->isAlreadyDeleted) { return $this->deleteStatus; } $bucket = $this->getBucket(); if(!$bucket) { return false; } $this->deleteStatus = $bucket->deleteFile($this->path); $this->isAlreadyDeleted = true; if(!$this->deleteStatus) { $this->errorCollection->addOne(new Error('Could not delete file from bucket.', static::ERROR_DELETE_CLOUD_FILE)); return false; } } else { $file = new IO\File($this->getAbsolutePath()); if($file->isExists()) { if(!$file->delete()) { $this->errorCollection->addOne(new Error('Could not delete file.', static::ERROR_DELETE_FILE)); return false; } } } return $this->deleteInternal(); } /** * Registers delayed delete which will do on the shutdown. * @return void */ public function registerDelayedDeleteOnShutdown() { if ($this->isRegisteredShutdownFunction) { return; } $self = $this; register_shutdown_function(function() use ($self){ $self->delete(); }); $this->isRegisteredShutdownFunction = true; } protected static function generateTokenByPath($path) { $name = bx_basename($path); if (preg_match('%^[0-9a-f]{32}$%', $name)) { return $name; } return md5($name . mt_rand() . mt_rand()); } protected static function prepareDataToInsertFromFileArray(array $fileData, array $data, ErrorCollection $errorCollection) { if (($fileData['error'] = intval($fileData['error'])) > 0) { if ($fileData['error'] < 3) { $errorCollection->addOne(new Error('upload_max_filesize: ' . intval(ini_get('upload_max_filesize')), static::ERROR_UPLOAD_MAX_FILE_SIZE)); return null; } $errorCollection->addOne(new Error('upload_error ' . $fileData['error'], static::ERROR_UPLOAD_FILE)); return null; } if(!is_uploaded_file($fileData['tmp_name'])) { $errorCollection->addOne(new Error('Current file is unsafe (is_uploaded_file check)', static::ERROR_IS_NOT_UPLOADED_FILE)); return null; } list($relativePath, $absolutePath) = static::generatePath(); if(!move_uploaded_file($fileData['tmp_name'], $absolutePath)) { $errorCollection->addOne(new Error('Could not move uploaded file (move_uploaded_file)', static::ERROR_MOVE_UPLOADED_FILE)); return null; } //now you can set CREATED_BY $data = array_intersect_key($data, array('CREATED_BY' => true, 'SIZE' => true,)); return array_merge(array( 'TOKEN' => static::generateTokenByPath($relativePath), 'FILENAME' => $fileData['name'], 'CONTENT_TYPE' => empty($fileData['type'])? \CFile::getContentType($absolutePath) : $fileData['type'], 'PATH' => $relativePath, 'BUCKET_ID' => '', 'SIZE' => empty($fileData['size'])? '' : $fileData['size'], 'RECEIVED_SIZE' => empty($fileData['size'])? '' : $fileData['size'], 'WIDTH' => empty($fileData['width'])? '' : $fileData['width'], 'HEIGHT' => empty($fileData['height'])? '' : $fileData['height'], ), $data); } /** * Creates TmpFile model from file array ($_FILE). * @param array $fileData Array like as $_FILE. * @param array $data Additional fields to TmpFile. * @param ErrorCollection $errorCollection Error collection. * @return Model|null|static */ public static function createFromFileArray(array $fileData, array $data, ErrorCollection $errorCollection) { $data = static::prepareDataToInsertFromFileArray($fileData, $data, $errorCollection); if(!$data) { return null; } return static::add($data, $errorCollection); } /** * Creates first part of file in bucket. * @param array $fileData Array like as $_FILE. * @param array $data Additional fields to TmpFile. * @param \CCloudStorageBucket $bucket Cloud bucket. * @param array $params Parameters (startRange, endRange, fileSize). * @param ErrorCollection $errorCollection Error collection. * @return Model|null|static */ public static function createInBucketFirstPartFromFileArray(array $fileData, array $data, \CCloudStorageBucket $bucket, array $params, ErrorCollection $errorCollection) { $data = static::prepareDataToInsertFromFileArray($fileData, $data, $errorCollection); $data['IS_CLOUD'] = 1; /** @noinspection PhpUndefinedFieldInspection */ $data['BUCKET_ID'] = $bucket->ID; $model = static::add($data, $errorCollection); if(!$model) { return null; } $uploadStatus = $model->appendContentCloud( IO\File::getFileContents($model->getAbsoluteNonCloudPath()), $params['startRange'], $params['endRange'], $params['fileSize'] ); if(!$uploadStatus) { $errorCollection->add($model->getErrors()); //todo Are we right? $model->delete(); unset($model); return null; } return $model; } /** * Appends contents to file. * @param string $fileContent File content. * @param array $params Parameters (startRange, endRange, fileSize). * @return bool * @throws \Bitrix\Main\ArgumentException */ public function append($fileContent, array $params) { $this->checkRequiredInputParams($params, array('endRange', 'fileSize')); if($this->errorCollection->hasErrors()) { return false; } if($this->isCloud()) { $status = $this->appendContentCloud($fileContent, $params['startRange'], $params['endRange'], $params['fileSize']); } else { $status = $this->appendContentNonCloud($fileContent, $params['startRange'], $params['endRange'], $params['fileSize']); } if ($status) { $this->increaseReceivedSize($params['endRange'] - $params['startRange'] + 1); } return $status; } private function appendContentCloud($fileContent, $startRange, $endRange, $fileSize) { $isLastChunk = ($endRange + 1) == $fileSize; $bucket = $this->getBucket(); if(!$bucket) { return false; } if ( ($endRange - $startRange + 1) < $bucket->getService()->getMinUploadPartSize() && !$isLastChunk ) { $this->errorCollection->addOne( new Error( "Could not append content. Size of chunk must be more than {$bucket->getService()->getMinUploadPartSize()} (if chunk is not last)", static::ERROR_CLOUD_APPEND_INVALID_CHUNK_SIZE ) ); return false; } $upload = new CCloudStorageUpload($this->path); if(!$upload->isStarted()) { if(!$upload->start($bucket->ID, $fileSize)) { $this->errorCollection->addOne( new Error( "Could not start cloud upload", static::ERROR_CLOUD_START_UPLOAD ) ); return false; } } $success = false; if($fileContent === false) { $this->errorCollection->addOne( new Error( 'Could not get file contents', static::ERROR_GET_FILE_CONTENTS ) ); return false; } if ($upload->getPos() == doubleval($endRange+1)) { //we already have this portion of content. Seems to be like that if ($isLastChunk && !$upload->finish()) { $this->errorCollection[] = new Error('Could not finish resumable upload',static::ERROR_CLOUD_FINISH_UPLOAD); return false; } return true; } $fails = 0; while ($upload->hasRetries()) { if ($upload->next($fileContent)) { $success = true; break; } $fails++; } if (!$success) { $this->errorCollection->addOne( new Error( "Could not upload part of file for {$fails} times", static::ERROR_CLOUD_UPLOAD_PART ) ); return false; } elseif($success && $isLastChunk) { if($upload->finish()) { //we don't inc and don't dec //$bucket->incFileCounter($fileSize); } else { $this->errorCollection->addOne( new Error( 'Could not finish resumable upload', static::ERROR_CLOUD_FINISH_UPLOAD ) ); return false; } return true; } return $success; } private function appendContentNonCloud($fileContent, $startRange, $endRange, $fileSize) { $file = new IO\File($this->getAbsolutePath()); if(!$file->isExists()) { $this->errorCollection->addOne( new Error( 'Could not find file', static::ERROR_EXISTS_FILE ) ); return false; } if ($file->getSize() == ($endRange+1)) { //we already have this portion of content. Seems to be like that return true; } if($file->putContents($fileContent, $file::APPEND) === false) { $this->errorCollection->addOne( new Error( 'Could not put contents to file', static::ERROR_PUT_CONTENTS ) ); return false; } return true; } protected function increaseReceivedSize($bytes) { $bytes = (int)$bytes; $success = $this->update([ 'RECEIVED_SIZE' => new SqlExpression("?# + {$bytes}", 'RECEIVED_SIZE'), ]); if($success) { $this->receivedSize += $bytes; } return $success; } protected static function generatePath() { $tmpName = md5(mt_rand() . mt_rand()); $dir = rtrim(CTempFile::getDirectoryName(2, Driver::INTERNAL_MODULE_ID), '/') . '/'; checkDirPath($dir); //make folder recursive $pathItems = explode(CTempFile::getAbsoluteRoot(), $dir . $tmpName); return array(array_pop($pathItems), $dir . $tmpName); } private function getAbsoluteCloudPath() { $bucket = $this->getBucket(); if(!$bucket) { return null; } return $bucket->getFileSRC($this->path); } private function getAbsoluteNonCloudPath() { return \CTempFile::getAbsoluteRoot() . '/' . $this->path; } /** * Returns absolute path to file. * @return null|string */ public function getAbsolutePath() { if($this->isCloud()) { return $this->getAbsoluteCloudPath(); } return $this->getAbsoluteNonCloudPath(); } /** * Returns the list of pair for mapping data and object properties. * Key is field in DataManager, value is object property. * @return array */ public static function getMapAttributes() { return array( 'ID' => 'id', 'TOKEN' => 'token', 'FILENAME' => 'filename', 'CONTENT_TYPE' => 'contentType', 'PATH' => 'path', 'BUCKET_ID' => 'bucketId', 'SIZE' => 'size', 'RECEIVED_SIZE' => 'receivedSize', 'WIDTH' => 'width', 'HEIGHT' => 'height', 'IS_CLOUD' => 'isCloud', 'CREATED_BY' => 'createdBy', 'CREATE_USER' => 'createUser', 'CREATE_TIME' => 'createTime', ); } /** * Returns the list attributes which is connected with another models. * @return array */ public static function getMapReferenceAttributes() { return array( 'CREATE_USER' => array( 'class' => User::className(), 'select' => User::getFieldsForSelect(), ), ); } }
/var/www/axolotl/data/www/yar.axolotls.ru/52131/../bitrix/modules/disk/lib/bitrix24disk/tmpfile.php