Файловый менеджер - Редактировать - /var/www/html/components/com_jchat/Model/AttachmentsModel.php
Ðазад
<?php namespace JExtstore\Component\JChat\Site\Model; /** * @package JCHAT::ATTACHMENTS::components::com_jchat * @subpackage models * @author Joomla! Extensions Store * @Copyright (C) 2015 - Joomla! Extensions Store * @license GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html */ defined( '_JEXEC' ) or die( 'Restricted access' ); use Joomla\CMS\Language\Text; use Joomla\CMS\Factory; use Joomla\CMS\MVC\Factory\MVCFactoryInterface; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Filter\InputFilter; use Joomla\CMS\Filesystem\Folder; use Joomla\CMS\Filesystem\File; use JExtstore\Component\JChat\Administrator\Framework\Model as JChatModel; use JExtstore\Component\JChat\Administrator\Framework\Helpers\Users as JChatHelpersUsers; use JExtstore\Component\JChat\Administrator\Framework\Thumb\Factory as JChatThumbFactory; /** * Here the entity is the file attachment message on stream * * @package JCHAT::ATTACHMENTS::components::com_jchat * @subpackage models * @since 1.0 */ class AttachmentsModel extends JChatModel { /** * @access private * @var int */ private $cacheFolder; /** * User object * * @access private * @var int */ private $myUser; /** * User object * * @access private * @var int */ private $lastInsertId; /** * @access private * @param string $originalFilename * @param string $thumbFilename * @param string $fileExtension * @return boolean */ private function resizeImage($originalFilename, $thumbFilename, $fileExtension) { $thumb = JChatThumbFactory::create($originalFilename); $resizeWidth = $this->componentParams->get('resize_attachments_images_maxwidth', 800); $defaultOptions = array ( 'resizeUp' => false, 'jpegQuality' => $this->componentParams->get('resize_attachments_images_quality', 80), 'correctPermissions' => false, 'preserveAlpha' => true, 'alphaMaskColor' => array (255, 255, 255), 'preserveTransparency' => false, 'transparencyMaskColor' => array (0, 0, 0) ); $thumb->setOptions($defaultOptions); $thumb->resize($resizeWidth); $thumb->save($thumbFilename, $fileExtension); } /** * Generate file name hash * * @access private * @param string $filename * @param string $userid * @return string */ private function generaHash($filename, $messageId) { $filenameStripped = File::stripExt($filename); $fileExtension = File::getExt($filename); $hash = md5($filenameStripped . $messageId); return $hash . '.' . $fileExtension; } /** * Store file attachment message on database as a special record * * @access private * @param string $filename * @return boolean */ private function storeDBMessage($filename) { if ($this->getState('to', null) && !empty($filename)) { // Get user reference $to = $this->getState('to', null); $tologged = $this->getState('tologged', null); // Valid target user session id? if($to == -1 && $tologged) { $sessionSql = "SELECT" . "\n " . $this->dbInstance->quoteName('session_id') . "\n FROM #__session" . "\n WHERE" . "\n " . $this->dbInstance->quoteName('userid') . " = " . (int)$tologged . "\n ORDER BY " . $this->dbInstance->quoteName('time') . " DESC" . "\n LIMIT 1"; $this->dbInstance->setQuery($sessionSql); $sessionIDReceiver = $this->dbInstance->loadResult(); $to = $sessionIDReceiver ? $sessionIDReceiver : -1; } // Get users actual names $actualNames = JChatHelpersUsers::getActualNames ( $this->getState('from'), $this->getState('to'), $this->componentParams ); $unixTimeStamp = time(); $sql = "INSERT INTO #__jchat (" . $this->dbInstance->quoteName('from') . ',' . $this->dbInstance->quoteName('to') . ',' . $this->dbInstance->quoteName('fromuser') . ',' . $this->dbInstance->quoteName('touser') . ',' . $this->dbInstance->quoteName('message') . ',' . $this->dbInstance->quoteName('sent') . ',' . $this->dbInstance->quoteName('read') . ',' . $this->dbInstance->quoteName('type') . ',' . $this->dbInstance->quoteName('status') . ',' . $this->dbInstance->quoteName('actualfrom') . ',' . $this->dbInstance->quoteName('actualto') . ',' . $this->dbInstance->quoteName('ipaddress') . ') VALUES( ' . $this->dbInstance->quote($this->getState('from')). ", ". $this->dbInstance->quote($to). ",". $this->dbInstance->quote($this->myUser->id). ", ". $this->dbInstance->quote($tologged). ",". $this->dbInstance->quote($filename) . ",". $this->dbInstance->quote($unixTimeStamp) . ",". "0" . "," . $this->dbInstance->quote('file') . "," . "0" . "," . $this->dbInstance->quote($actualNames['fromActualName']) . ", ". $this->dbInstance->quote($actualNames['toActualName']) . ", ". $this->dbInstance->quote($_SERVER['REMOTE_ADDR']) . ")"; $this->dbInstance->setQuery($sql); if(!$this->dbInstance->execute()){ return false; } if (empty($this->sessionName['jchat_user_'.$this->getState('to')])) { $this->sessionName['jchat_user_'.$this->getState('to')] = array(); } $lastInsertId = $this->dbInstance->insertid(); $this->lastInsertId = $lastInsertId; $insertTime = HTMLHelper::_('date', $unixTimeStamp, Text::_('DATE_FORMAT_LC2')); $this->sessionName['jchat_user_'.$this->getState('to')][$lastInsertId] = array( "id" => $this->dbInstance->insertid(), "from" => $this->getState('to'), "message" => $filename, "type" => 'file', "status" => 0, "time" => $insertTime, "self" => 1, "old" => 1) ; } return true; } /** * Store file attachment message on database as a special record * to all participants to the conference after retrieving the list of other peers involved * * @access private * @param string $filename * @return boolean */ private function storeDBConferenceMessage($filename) { if (!empty($filename)) { // Get this peer session ID identifier $thisPeer = $this->getState('from'); if($this->getState('isLiveStreaming')) { // Valid target user session id? $otherConfPeersSql = "SELECT" . "\n status.sessionid AS peer2, sess.userid" . "\n FROM #__jchat_sessionstatus AS status" . "\n LEFT JOIN #__session AS sess" . "\n ON status.sessionid = sess.session_id" . "\n WHERE" . "\n status.livestreaming_hash = " . $this->dbInstance->quote($thisPeer) . "\n AND status.sessionid != " . $this->dbInstance->quote($thisPeer); } else { // Valid target user session id? $otherConfPeersSql = "SELECT" . "\n conf.peer2, sess.userid" . "\n FROM #__jchat_webrtc_conference AS conf" . "\n LEFT JOIN #__session AS sess" . "\n ON conf.peer2 = sess.session_id" . "\n WHERE" . "\n conf.peer1 = " . $this->dbInstance->quote($thisPeer); } $this->dbInstance->setQuery($otherConfPeersSql); $otherConfPeers = $this->dbInstance->loadObjectList(); if(is_array($otherConfPeers) && count($otherConfPeers)) { foreach ($otherConfPeers as $otherConfPeer) { // Get users actual names $actualNames = JChatHelpersUsers::getActualNames ( $thisPeer, $otherConfPeer->peer2, $this->componentParams ); $unixTimeStamp = time(); $sql = "INSERT INTO #__jchat (" . $this->dbInstance->quoteName('from') . ',' . $this->dbInstance->quoteName('to') . ',' . $this->dbInstance->quoteName('fromuser') . ',' . $this->dbInstance->quoteName('touser') . ',' . $this->dbInstance->quoteName('message') . ',' . $this->dbInstance->quoteName('sent') . ',' . $this->dbInstance->quoteName('read') . ',' . $this->dbInstance->quoteName('type') . ',' . $this->dbInstance->quoteName('status') . ',' . $this->dbInstance->quoteName('actualfrom') . ',' . $this->dbInstance->quoteName('actualto') . ',' . $this->dbInstance->quoteName('ipaddress') . ') VALUES( ' . $this->dbInstance->quote($thisPeer). ", ". $this->dbInstance->quote($otherConfPeer->peer2). ",". $this->dbInstance->quote($this->myUser->id). ", ". $this->dbInstance->quote($otherConfPeer->userid). ",". $this->dbInstance->quote($filename) . ",". $this->dbInstance->quote($unixTimeStamp) . ",". "0" . "," . $this->dbInstance->quote('file') . "," . "0" . "," . $this->dbInstance->quote($actualNames['fromActualName']) . ", ". $this->dbInstance->quote($actualNames['toActualName']) . ", ". $this->dbInstance->quote($_SERVER['REMOTE_ADDR']) . ")"; $this->dbInstance->setQuery($sql); if(!$this->dbInstance->execute()){ return false; } if (empty($this->sessionName['jchat_user_'.$otherConfPeer->peer2])) { $this->sessionName['jchat_user_'.$otherConfPeer->peer2] = array(); } $lastInsertId = $this->dbInstance->insertid(); $this->lastInsertId = $lastInsertId; $insertTime = HTMLHelper::_('date', $unixTimeStamp, Text::_('DATE_FORMAT_LC2')); $this->sessionName['jchat_user_'.$otherConfPeer->peer2][$lastInsertId] = array( "id" => $this->dbInstance->insertid(), "from" => $otherConfPeer->peer2, "message" => $filename, "type" => 'file', "status" => 0, "time" => $insertTime, "self" => 1, "old" => 1) ; } } } return true; } /** * Read file by chunks to send to output buffer * * @access private * @param string $nomefile * @return boolean */ private function readFileChunked($filePath) { $chunksize = 1 * (1024 * 1024); // how many bytes per chunk $buffer = ''; $cnt = 0; $handle = fopen ( $filePath, 'rb' ); if ($handle === false) { return false; } while ( ! feof ( $handle ) ) { $buffer = fread ( $handle, $chunksize ); echo $buffer; @ob_flush (); flush (); } $status = fclose ( $handle ); return $status; } /** * Detect mime type for streamed file * * @access private * @param $filename * @return string Il mime type trovato a fronte del lookup nella tabella */ private function detectMimeType($filename) { global $mosConfig_absolute_path; include_once JPATH_COMPONENT_ADMINISTRATOR . '/Framework/Helpers/mime.mapping.php'; $filename = strtolower ( $filename ); $exts = preg_split ( "#[/\\.]#i", $filename ); $n = count ( $exts ) - 1; $fileExtension = $exts [$n]; foreach ( $mime_extension_map as $extension => $mime ) { if ($extension === $fileExtension) return $mime; } return 'application/octet-stream'; } /** * Store uploaded file to cache folder, * fully manage error messages and ask for database insert * * @access public * @param bool $updateNulls * @return mixed */ public function storeEntity($updateNulls = false) { $tmpFile = $this->requestFilesName['newfile']['tmp_name']; $tmpFileName = $this->requestFilesName['newfile']['name']; if(!$tmpFile || !$tmpFileName) { $msg = Text::_('COM_JCHAT_NOFILE_SELECTED'); $this->setError($msg); return; } $tmpFileSize = $this->requestFilesName['newfile']['size']; $allowedFileSize = $this->componentParams->get('maxfilesize', 2) * 1024 * 1024; // MB->Bytes if($tmpFileSize > $allowedFileSize) { $msg = Text::_('COM_JCHAT_SIZE_ERROR') .' Max ' . $this->componentParams->get('maxfilesize', 2) . 'MB.'; $this->setError($msg); return; } $disallowedExtensions = explode(',', $this->componentParams->get('disallowed_extensions', 'exe,bat,pif')); $tmpFileExtension = @array_pop(explode('.', $tmpFileName)); if(in_array(strtolower($tmpFileExtension), $disallowedExtensions)) { $msg = Text::_('COM_JCHAT_EXT_ERROR') . $this->componentParams->get('disallowed_extensions', 'exe,bat,pif'); $this->setError($msg); return; } if(!is_dir($this->cacheFolder)) { Folder::create($this->cacheFolder); } if(!is_writable($this->cacheFolder)) { try { if(!chmod($this->cacheFolder, 0775)) { throw new \Exception( Text::_('COM_JCHAT_DIR_WRITABLE')); } } catch(\Exception $e) { $msg = $e->getMessage(); $this->setError($msg); return; } } if(!move_uploaded_file($tmpFile, $this->cacheFolder . $tmpFileName)) { $msg = Text::_('COM_JCHAT_UPLOAD_ERROR'); $this->setError($msg); return; } // Store the DB message file $filter = InputFilter::getInstance(); if($this->getState('receiver', null) === 'conference') { // Set the message to be received by conference joined users if(!$this->storeDBConferenceMessage($filter->clean($tmpFileName))) { $msg = Text::_('COM_JCHAT_SENDMSGFILE_ERROR'); $this->setError($msg); return; } $this->lastInsertId = 'conference'; } else { if(!$this->storeDBMessage($filter->clean($tmpFileName))) { $msg = Text::_('COM_JCHAT_SENDMSGFILE_ERROR'); $this->setError($msg); return; } } // Hash and store the file on file system $hashedFileName = $this->generaHash($tmpFileName, $this->lastInsertId); if(file_exists($this->cacheFolder . $hashedFileName)) { unlink($this->cacheFolder . $hashedFileName); } // Check if there is an image file uploaded and if the option to resize images is active if($this->componentParams->get('resize_attachments_images', 0) && in_array(strtolower($tmpFileExtension), array('jpg', 'jpeg', 'gif'))) { $this->resizeImage($this->cacheFolder . $tmpFileName, $this->cacheFolder . $hashedFileName, $tmpFileExtension); unlink($this->cacheFolder . $tmpFileName); } else { if(!rename($this->cacheFolder . $tmpFileName, $this->cacheFolder . $hashedFileName)) { $msg = Text::_('COM_JCHAT_RENAME_ERROR'); $this->setError($msg); return; } } $msg = Text::_('COM_JCHAT_SUCCESS_FILEUPLOAD'); $this->setState('result', $msg); } /** * Download uploaded file message * * @access public * @return void */ public function loadEntity($ids = null) { $idMessage = $this->getState('idMessage'); $idUserConversation = $this->getState('from'); try { $query = "SELECT #__jchat.from, #__jchat.message FROM #__jchat WHERE id = " . (int)$idMessage; $this->dbInstance->setQuery($query); $resultInfo = $this->dbInstance->loadObject(); if(!$resultInfo) { $conversationArray = $this->sessionName['jchat_user_' . $idUserConversation]; foreach ($conversationArray as $message) { if($message['id'] == $idMessage) { $resultInfo = new \stdClass(); $resultInfo->from = $message['from']; $resultInfo->message = $message['message']; break; } } if(!$resultInfo) { throw new \Exception('COM_JCHAT_ERROR_NOTFOUND_FILE'); } } $fileName = $this->generaHash($resultInfo->message, $idMessage); $filePath = $this->cacheFolder . $fileName; if(!file_exists($filePath)) { // Check if there is a conference shared file, fallback here before throwing an error $fileName = $this->generaHash($resultInfo->message, 'conference'); $filePath = $this->cacheFolder . $fileName; if(!file_exists($filePath)) { throw new \Exception('COM_JCHAT_ERROR_DELETED_FILE'); } } } catch (\Exception $e) { // JS inject $appNonce = $this->app->get('csp_nonce', null); $nonce = $appNonce ? ' nonce="' . $appNonce . '"' : ''; echo '<script' . $nonce . '>alert("' . Text::_($e->getMessage()) . '");window.history.go(-1);</script>'; exit(); } $fsize = @filesize ( $filePath ); $mod_date = date ( 'r', filemtime ( $filePath ) ); $cont_dis = 'attachment'; $mimeType = $this->detectMimeType ( $fileName ); // required for IE, otherwise Content-disposition is ignored if (ini_get ( 'zlib.output_compression' )) { ini_set ( 'zlib.output_compression', 'Off' ); } header ( "Pragma: public" ); header ( "Cache-Control: must-revalidate, post-check=0, pre-check=0" ); header ( "Expires: 0" ); header ( "Content-Transfer-Encoding: binary" ); header ( 'Content-Disposition:' . $cont_dis . ';' . ' filename="' . $resultInfo->message . '";' . ' modification-date="' . $mod_date . '";' . ' size=' . $fsize . ';' ); //RFC2183 header ( "Content-Type: " . $mimeType ); // MIME type header ( "Content-Length: " . $fsize ); if (! ini_get ( 'safe_mode' )) { // set_time_limit doesn't work in safe mode @set_time_limit ( 0 ); } // No encoding - we aren't using compression... (RFC1945) //header("Content-Encoding: none"); //header("Vary: none"); $downloadStatus = $this->readFileChunked ( $filePath ); // Al raggiungimento dell'effettivo download si aggiorna lo status update if($downloadStatus) { $query = "UPDATE #__jchat SET status=1 WHERE id = " . (int)$idMessage; $this->dbInstance->setQuery($query); $this->dbInstance->execute(); } exit(); } /** * Class constructor * * @access public * @return Object & */ public function __construct($config = array(), MVCFactoryInterface $factory = null) { $this->getComponentParams(); $this->cacheFolder = JPATH_SITE . '/components/com_jchat/cache/'; $this->myUser = Factory::getApplication()->getIdentity(); parent::__construct( $config, $factory ); } } ?>
| ver. 1.1 | |
.
| PHP 8.4.18 | Ð“ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ñ Ñтраницы: 0 |
proxy
|
phpinfo
|
ÐаÑтройка