Вход Регистрация
Файл: phpbb/plupload/plupload.php
Строк: 341
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/

namespace phpbbplupload;

/**
* This class handles all server-side plupload functions
*/
class plupload
{
    
/**
    * @var string
    */
    
protected $phpbb_root_path;

    
/**
    * @var phpbbconfigconfig
    */
    
protected $config;

    
/**
    * @var phpbbrequestrequest_interface
    */
    
protected $request;

    
/**
    * @var phpbbuser
    */
    
protected $user;

    
/**
    * @var phpbbphpini
    */
    
protected $php_ini;

    
/**
    * @var phpbbmimetypeguesser
    */
    
protected $mimetype_guesser;

    
/**
    * Final destination for uploaded files, i.e. the "files" directory.
    * @var string
    */
    
protected $upload_directory;

    
/**
    * Temporary upload directory for plupload uploads.
    * @var string
    */
    
protected $temporary_directory;

    
/**
    * Constructor.
    *
    * @param string $phpbb_root_path
    * @param phpbbconfigconfig $config
    * @param phpbbrequestrequest_interface $request
    * @param phpbbuser $user
    * @param phpbbphpini $php_ini
    * @param phpbbmimetypeguesser $mimetype_guesser
    */
    
public function __construct($phpbb_root_pathphpbbconfigconfig $configphpbbrequestrequest_interface $requestphpbbuser $userphpbbphpini $php_iniphpbbmimetypeguesser $mimetype_guesser)
    {
        
$this->phpbb_root_path $phpbb_root_path;
        
$this->config $config;
        
$this->request $request;
        
$this->user $user;
        
$this->php_ini $php_ini;
        
$this->mimetype_guesser $mimetype_guesser;

        
$this->set_default_directories();
    }

    
/**
    * Plupload allows for chunking so we must check for that and assemble
    * the whole file first before performing any checks on it.
    *
    * @param string $form_name The name of the file element in the upload form
    *
    * @return array|null    null if there are no chunks to piece together
    *                        otherwise array containing the path to the
    *                        pieced-together file and its size
    */
    
public function handle_upload($form_name)
    {
        
$chunks_expected $this->request->variable('chunks'0);

        
// If chunking is disabled or we are not using plupload, just return
        // and handle the file as usual
        
if ($chunks_expected 2)
        {
            return;
        }

        
$file_name $this->request->variable('name''');
        
$chunk $this->request->variable('chunk'0);

        
$this->user->add_lang('plupload');
        
$this->prepare_temporary_directory();

        
$file_path $this->temporary_filepath($file_name);
        
$this->integrate_uploaded_file($form_name$chunk$file_path);

        
// If we are done with all the chunks, strip the .part suffix and then
        // handle the resulting file as normal, otherwise die and await the
        // next chunk.
        
if ($chunk == $chunks_expected 1)
        {
            
rename("{$file_path}.part"$file_path);

            
// Reset upload directories to defaults once completed
            
$this->set_default_directories();

            
// Need to modify some of the $_FILES values to reflect the new file
            
return array(
                
'tmp_name' => $file_path,
                
'name' => $this->request->variable('real_filename'''),
                
'size' => filesize($file_path),
                
'type' => $this->mimetype_guesser->guess($file_path$file_name),
            );
        }
        else
        {
            
$json_response = new phpbbjson_response();
            
$json_response->send(array(
                
'jsonrpc' => '2.0',
                
'id' => 'id',
                
'result' => null,
            ));
        }
    }

    
/**
    * Fill in the plupload configuration options in the template
    *
    * @param phpbbcacheservice        $cache
    * @param phpbbtemplatetemplate    $template
    * @param string                        $s_action The URL to submit the POST data to
    * @param int                        $forum_id The ID of the forum
    * @param int                        $max_files Maximum number of files allowed. 0 for unlimited.
    *
    * @return null
    */
    
public function configure(phpbbcacheservice $cachephpbbtemplatetemplate $template$s_action$forum_id$max_files)
    {
        
$filters $this->generate_filter_string($cache$forum_id);
        
$chunk_size $this->get_chunk_size();
        
$resize $this->generate_resize_string();

        
$template->assign_vars(array(
            
'S_RESIZE'            => $resize,
            
'S_PLUPLOAD'        => true,
            
'FILTERS'            => $filters,
            
'CHUNK_SIZE'        => $chunk_size,
            
'S_PLUPLOAD_URL'    => htmlspecialchars_decode($s_action),
            
'MAX_ATTACHMENTS'    => $max_files,
            
'ATTACH_ORDER'        => ($this->config['display_order']) ? 'asc' 'desc',
            
'L_TOO_MANY_ATTACHMENTS'    => $this->user->lang('TOO_MANY_ATTACHMENTS'$max_files),
        ));

        
$this->user->add_lang('plupload');
    }

    
/**
    * Checks whether the page request was sent by plupload or not
    *
    * @return bool
    */
    
public function is_active()
    {
        return 
$this->request->header('X-PHPBB-USING-PLUPLOAD'false);
    }

    
/**
    * Returns whether the current HTTP request is a multipart request.
    *
    * @return bool
    */
    
public function is_multipart()
    {
        
$content_type $this->request->server('CONTENT_TYPE');

        return 
strpos($content_type'multipart') === 0;
    }

    
/**
    * Sends an error message back to the client via JSON response
    *
    * @param int $code        The error code
    * @param string $msg    The translation string of the message to be sent
    *
    * @return null
    */
    
public function emit_error($code$msg)
    {
        
$json_response = new phpbbjson_response();
        
$json_response->send(array(
            
'jsonrpc' => '2.0',
            
'id' => 'id',
            
'error' => array(
                
'code' => $code,
                
'message' => $this->user->lang($msg),
            ),
        ));
    }

    
/**
    * Looks at the list of allowed extensions and generates a string
    * appropriate for use in configuring plupload with
    *
    * @param phpbbcacheservice $cache
    * @param string $forum_id The ID of the forum
    *
    * @return string
    */
    
public function generate_filter_string(phpbbcacheservice $cache$forum_id)
    {
        
$attach_extensions $cache->obtain_attach_extensions($forum_id);
        unset(
$attach_extensions['_allowed_']);
        
$groups = array();

        
// Re-arrange the extension array to $groups[$group_name][]
        
foreach ($attach_extensions as $extension => $extension_info)
        {
            if (!isset(
$groups[$extension_info['group_name']]))
            {
                
$groups[$extension_info['group_name']] = array();
            }

            
$groups[$extension_info['group_name']][] = $extension;
        }

        
$filters = array();
        foreach (
$groups as $group => $extensions)
        {
            
$filters[] = sprintf(
                
"{title: '%s', extensions: '%s'}",
                
addslashes(ucfirst(strtolower($group))),
                
addslashes(implode(','$extensions))
            );
        }

        return 
implode(','$filters);
    }

    
/**
    * Generates a string that is used to tell plupload to automatically resize
    * files before uploading them.
    *
    * @return string
    */
    
public function generate_resize_string()
    {
        
$resize '';
        if (
$this->config['img_max_height'] > && $this->config['img_max_width'] > 0)
        {
            
$resize sprintf(
                
'resize: {width: %d, height: %d, quality: 100},',
                (int) 
$this->config['img_max_height'],
                (int) 
$this->config['img_max_width']
            );
        }

        return 
$resize;
    }

    
/**
    * Checks various php.ini values and the maximum file size to determine
    * the maximum size chunks a file can be split up into for upload
    *
    * @return int
    */
    
public function get_chunk_size()
    {
        
$max min(
            
$this->php_ini->get_bytes('upload_max_filesize'),
            
$this->php_ini->get_bytes('post_max_size'),
            
max(1$this->php_ini->get_bytes('memory_limit')),
            
$this->config['max_filesize']
        );

        
// Use half of the maximum possible to leave plenty of room for other
        // POST data.
        
return floor($max 2);
    }

    protected function 
temporary_filepath($file_name)
    {
        
// Must preserve the extension for plupload to work.
        
return sprintf(
            
'%s/%s_%s%s',
            
$this->temporary_directory,
            
$this->config['plupload_salt'],
            
md5($file_name),
            
filespec::get_extension($file_name)
        );
    }

    
/**
    * Checks whether the chunk we are about to deal with was actually uploaded
    * by PHP and actually exists, if not, it generates an error
    *
    * @param string $form_name The name of the file in the form data
    *
    * @return null
    */
    
protected function integrate_uploaded_file($form_name$chunk$file_path)
    {
        
$is_multipart $this->is_multipart();
        
$upload $this->request->file($form_name);
        if (
$is_multipart && (!isset($upload['tmp_name']) || !is_uploaded_file($upload['tmp_name'])))
        {
            
$this->emit_error(103'PLUPLOAD_ERR_MOVE_UPLOADED');
        }

        
$tmp_file $this->temporary_filepath($upload['tmp_name']);

        if (!
move_uploaded_file($upload['tmp_name'], $tmp_file))
        {
            
$this->emit_error(103'PLUPLOAD_ERR_MOVE_UPLOADED');
        }

        
$out fopen("{$file_path}.part"$chunk == 'wb' 'ab');
        if (!
$out)
        {
            
$this->emit_error(102'PLUPLOAD_ERR_OUTPUT');
        }

        
$in fopen(($is_multipart) ? $tmp_file 'php://input''rb');
        if (!
$in)
        {
            
$this->emit_error(101'PLUPLOAD_ERR_INPUT');
        }

        while (
$buf fread($in4096))
        {
            
fwrite($out$buf);
        }

        
fclose($in);
        
fclose($out);

        if (
$is_multipart)
        {
            
unlink($tmp_file);
        }
    }

    
/**
    * Creates the temporary directory if it does not already exist.
    *
    * @return null
    */
    
protected function prepare_temporary_directory()
    {
        if (!
file_exists($this->temporary_directory))
        {
            
mkdir($this->temporary_directory);

            
copy(
                
$this->upload_directory '/index.htm',
                
$this->temporary_directory '/index.htm'
            
);
        }
    }

    
/**
    * Sets the default directories for uploads
    *
    * @return null
    */
    
protected function set_default_directories()
    {
        
$this->upload_directory $this->phpbb_root_path $this->config['upload_path'];
        
$this->temporary_directory $this->upload_directory '/plupload';
    }

    
/**
    * Sets the upload directories to the specified paths
    *
    * @param string $upload_directory Upload directory
    * @param string $temporary_directory Temporary directory
    *
    * @return null
    */
    
public function set_upload_directories($upload_directory$temporary_directory)
    {
        
$this->upload_directory $upload_directory;
        
$this->temporary_directory $temporary_directory;
    }
}
Онлайн: 2
Реклама