diff options
Diffstat (limited to 'phpBB')
-rw-r--r-- | phpBB/config/services.yml | 9 | ||||
-rw-r--r-- | phpBB/includes/functions_posting.php | 19 | ||||
-rw-r--r-- | phpBB/includes/functions_upload.php | 31 | ||||
-rw-r--r-- | phpBB/includes/message_parser.php | 49 | ||||
-rw-r--r-- | phpBB/includes/ucp/ucp_pm_compose.php | 10 | ||||
-rw-r--r-- | phpBB/install/install_install.php | 4 | ||||
-rw-r--r-- | phpBB/install/schemas/schema_data.sql | 2 | ||||
-rw-r--r-- | phpBB/language/en/plupload.php | 65 | ||||
-rw-r--r-- | phpBB/phpbb/db/migration/data/v310/alpha1.php | 1 | ||||
-rw-r--r-- | phpBB/phpbb/db/migration/data/v310/plupload.php | 32 | ||||
-rw-r--r-- | phpBB/phpbb/plupload/plupload.php | 374 | ||||
-rw-r--r-- | phpBB/posting.php | 7 | ||||
-rw-r--r-- | phpBB/styles/prosilver/template/overall_footer.html | 1 | ||||
-rw-r--r-- | phpBB/styles/prosilver/template/overall_header.html | 5 | ||||
-rw-r--r-- | phpBB/styles/prosilver/template/plupload.html | 48 | ||||
-rw-r--r-- | phpBB/styles/prosilver/theme/plupload.css | 11 |
16 files changed, 659 insertions, 9 deletions
diff --git a/phpBB/config/services.yml b/phpBB/config/services.yml index 51ae5c454d..c6490a21d7 100644 --- a/phpBB/config/services.yml +++ b/phpBB/config/services.yml @@ -258,6 +258,15 @@ services: php_ini: class: phpbb\php\ini + plupload: + class: phpbb\plupload\plupload + arguments: + - %core.root_path% + - @config + - @request + - @user + - @php_ini + request: class: phpbb\request\request diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php index ce1238d8e0..1bcef7f1f2 100644 --- a/phpBB/includes/functions_posting.php +++ b/phpBB/includes/functions_posting.php @@ -385,8 +385,18 @@ function posting_gen_topic_types($forum_id, $cur_topic_type = POST_NORMAL) /** * Upload Attachment - filedata is generated here * Uses upload class +* +* @param string $form_name The form name of the file upload input +* @param int $forum_id The id of the forum +* @param bool $local Whether the file is local or not +* @param string $local_storage The path to the local file +* @param bool $is_message Whether it is a PM or not +* @param \filespec $local_filedata A filespec object created for the local file +* @param \phpbb\plupload\plupload $plupload The plupload object if one is being used +* +* @return object filespec */ -function upload_attachment($form_name, $forum_id, $local = false, $local_storage = '', $is_message = false, $local_filedata = false) +function upload_attachment($form_name, $forum_id, $local = false, $local_storage = '', $is_message = false, $local_filedata = false, \phpbb\plupload\plupload $plupload = null) { global $auth, $user, $config, $db, $cache; global $phpbb_root_path, $phpEx; @@ -414,7 +424,7 @@ function upload_attachment($form_name, $forum_id, $local = false, $local_storage $extensions = $cache->obtain_attach_extensions((($is_message) ? false : (int) $forum_id)); $upload->set_allowed_extensions(array_keys($extensions['_allowed_'])); - $file = ($local) ? $upload->local_upload($local_storage, $local_filedata) : $upload->form_upload($form_name); + $file = ($local) ? $upload->local_upload($local_storage, $local_filedata) : $upload->form_upload($form_name, $plupload); if ($file->init_error) { @@ -469,6 +479,11 @@ function upload_attachment($form_name, $forum_id, $local = false, $local_storage { $file->remove(); + if ($plupload && $plupload->is_active()) + { + $plupload->emit_error(104, 'ATTACHED_IMAGE_NOT_IMAGE'); + } + // If this error occurs a user tried to exploit an IE Bug by renaming extensions // Since the image category is displaying content inline we need to catch this. trigger_error($user->lang['ATTACHED_IMAGE_NOT_IMAGE']); diff --git a/phpBB/includes/functions_upload.php b/phpBB/includes/functions_upload.php index 4181896eca..04d483e14c 100644 --- a/phpBB/includes/functions_upload.php +++ b/phpBB/includes/functions_upload.php @@ -44,10 +44,16 @@ class filespec var $upload = ''; /** + * The plupload object + * @var \phpbb\plupload\plupload + */ + protected $plupload; + + /** * File Class * @access private */ - function filespec($upload_ary, $upload_namespace) + function filespec($upload_ary, $upload_namespace, \phpbb\plupload\plupload $plupload = null) { if (!isset($upload_ary)) { @@ -80,6 +86,7 @@ class filespec $this->local = (isset($upload_ary['local_mode'])) ? true : false; $this->upload = $upload_namespace; + $this->plupload = $plupload; } /** @@ -161,12 +168,14 @@ class filespec */ function is_uploaded() { - if (!$this->local && !is_uploaded_file($this->filename)) + $is_plupload = $this->plupload && $this->plupload->is_active(); + + if (!$this->local && !$is_plupload && !is_uploaded_file($this->filename)) { return false; } - if ($this->local && !file_exists($this->filename)) + if (($this->local || $is_plupload) && !file_exists($this->filename)) { return false; } @@ -564,16 +573,28 @@ class fileupload * Upload file from users harddisk * * @param string $form_name Form name assigned to the file input field (if it is an array, the key has to be specified) + * @param \phpbb\plupload\plupload $plupload The plupload object + * * @return object $file Object "filespec" is returned, all further operations can be done with this object * @access public */ - function form_upload($form_name) + function form_upload($form_name, \phpbb\plupload\plupload $plupload = null) { global $user, $request; $upload = $request->file($form_name); unset($upload['local_mode']); - $file = new filespec($upload, $this); + + if ($plupload) + { + $result = $plupload->handle_upload($form_name); + if (is_array($result)) + { + $upload = array_merge($upload, $result); + } + } + + $file = new filespec($upload, $this, $plupload); if ($file->init_error) { diff --git a/phpBB/includes/message_parser.php b/phpBB/includes/message_parser.php index 3e348801c7..acd31fd519 100644 --- a/phpBB/includes/message_parser.php +++ b/phpBB/includes/message_parser.php @@ -1050,6 +1050,12 @@ class parse_message extends bbcode_firstpass var $mode; /** + * The plupload object used for dealing with attachments + * @var \phpbb\plupload\plupload + */ + protected $plupload; + + /** * Init - give message here or manually */ function parse_message($message = '') @@ -1440,6 +1446,11 @@ class parse_message extends bbcode_firstpass if ($preview || $refresh || sizeof($error)) { + if (isset($this->plupload) && $this->plupload->is_active()) + { + $json_response = new \phpbb\json_response(); + } + // Perform actions on temporary attachments if ($delete_file) { @@ -1484,13 +1495,17 @@ class parse_message extends bbcode_firstpass // Reindex Array $this->attachment_data = array_values($this->attachment_data); + if (isset($this->plupload) && $this->plupload->is_active()) + { + $json_response->send($this->attachment_data); + } } } else if (($add_file || $preview) && $upload_file) { if ($num_attachments < $cfg['max_attachments'] || $auth->acl_gets('m_', 'a_', $forum_id)) { - $filedata = upload_attachment($form_name, $forum_id, false, '', $is_message); + $filedata = upload_attachment($form_name, $forum_id, false, '', $is_message, false, $this->plupload); $error = array_merge($error, $filedata['error']); if (!sizeof($error)) @@ -1521,12 +1536,32 @@ class parse_message extends bbcode_firstpass $this->attachment_data = array_merge(array(0 => $new_entry), $this->attachment_data); $this->message = preg_replace('#\[attachment=([0-9]+)\](.*?)\[\/attachment\]#e', "'[attachment='.(\\1 + 1).']\\2[/attachment]'", $this->message); $this->filename_data['filecomment'] = ''; + + if (isset($this->plupload) && $this->plupload->is_active()) + { + // Send the client the attachment data to maintain state + $json_response->send($this->attachment_data); + } } } else { $error[] = $user->lang('TOO_MANY_ATTACHMENTS', (int) $cfg['max_attachments']); } + + if (!empty($error) && isset($this->plupload) && $this->plupload->is_active()) + { + // If this is a plupload (and thus ajax) request, give the + // client the first error we have + $json_response->send(array( + 'jsonrpc' => '2.0', + 'id' => 'id', + 'error' => array( + 'code' => 105, + 'message' => current($error), + ), + )); + } } } @@ -1687,4 +1722,16 @@ class parse_message extends bbcode_firstpass $poll['poll_max_options'] = ($poll['poll_max_options'] < 1) ? 1 : (($poll['poll_max_options'] > $config['max_poll_options']) ? $config['max_poll_options'] : $poll['poll_max_options']); } + + /** + * Setter function for passing the plupload object + * + * @param \phpbb\plupload\plupload $plupload The plupload object + * + * @return null + */ + public function set_plupload(\phpbb\plupload\plupload $plupload) + { + $this->plupload = $plupload; + } } diff --git a/phpBB/includes/ucp/ucp_pm_compose.php b/phpBB/includes/ucp/ucp_pm_compose.php index e0e7a46494..87dfdf902b 100644 --- a/phpBB/includes/ucp/ucp_pm_compose.php +++ b/phpBB/includes/ucp/ucp_pm_compose.php @@ -21,9 +21,10 @@ if (!defined('IN_PHPBB')) */ function compose_pm($id, $mode, $action, $user_folders = array()) { - global $template, $db, $auth, $user; + global $template, $db, $auth, $user, $cache; global $phpbb_root_path, $phpEx, $config; global $request; + global $phpbb_container; // Damn php and globals - i know, this is horrible // Needed for handle_message_list_actions() @@ -385,6 +386,8 @@ function compose_pm($id, $mode, $action, $user_folders = array()) } $message_parser = new parse_message(); + $plupload = $phpbb_container->get('plupload'); + $message_parser->set_plupload($plupload); $message_parser->message = ($action == 'reply') ? '' : $message_text; unset($message_text); @@ -1099,6 +1102,11 @@ function compose_pm($id, $mode, $action, $user_folders = array()) // Show attachment box for adding attachments if true $allowed = ($auth->acl_get('u_pm_attach') && $config['allow_pm_attach'] && $form_enctype); + if ($allowed) + { + $plupload->configure($cache, $template, $s_action, false); + } + // Attachment entry posting_gen_attachment_entry($attachment_data, $filename_data, $allowed); diff --git a/phpBB/install/install_install.php b/phpBB/install/install_install.php index c273660d08..1a7e1d1094 100644 --- a/phpBB/install/install_install.php +++ b/phpBB/install/install_install.php @@ -1322,6 +1322,10 @@ class install_install extends module SET config_value = '" . md5(mt_rand()) . "' WHERE config_name = 'avatar_salt'", + 'UPDATE ' . $data['table_prefix'] . "config + SET config_value = '" . md5(mt_rand()) . "' + WHERE config_name = 'plupload_salt'", + 'UPDATE ' . $data['table_prefix'] . "users SET username = '" . $db->sql_escape($data['admin_name']) . "', user_password='" . $db->sql_escape(md5($data['admin_pass1'])) . "', user_ip = '" . $db->sql_escape($user_ip) . "', user_lang = '" . $db->sql_escape($data['default_lang']) . "', user_email='" . $db->sql_escape($data['board_email']) . "', user_dateformat='" . $db->sql_escape($lang['default_dateformat']) . "', user_email_hash = " . $db->sql_escape(phpbb_email_hash($data['board_email'])) . ", username_clean = '" . $db->sql_escape(utf8_clean_string($data['admin_name'])) . "' WHERE username = 'Admin'", diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql index cd38f86312..094a43c8a0 100644 --- a/phpBB/install/schemas/schema_data.sql +++ b/phpBB/install/schemas/schema_data.sql @@ -222,6 +222,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('new_member_post_li INSERT INTO phpbb_config (config_name, config_value) VALUES ('new_member_group_default', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('override_user_style', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('pass_complex', 'PASS_TYPE_ANY'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('plupload_salt', 'phpbb_plupload'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('pm_edit_time', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('pm_max_boxes', '4'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('pm_max_msgs', '50'); @@ -284,6 +285,7 @@ INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('num_fi INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('num_posts', '1', 1); INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('num_topics', '1', 1); INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('num_users', '1', 1); +INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('plupload_last_gc', '0', 1); INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('rand_seed', '0', 1); INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('rand_seed_last_update', '0', 1); INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('record_online_date', '0', 1); diff --git a/phpBB/language/en/plupload.php b/phpBB/language/en/plupload.php new file mode 100644 index 0000000000..cfdce9810e --- /dev/null +++ b/phpBB/language/en/plupload.php @@ -0,0 +1,65 @@ +<?php +/** +* +* plupload [English] +* +* @package language +* @copyright (c) 2010-2013 Moxiecode Systems AB +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* DO NOT CHANGE +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +if (empty($lang) || !is_array($lang)) +{ + $lang = array(); +} + +// DEVELOPERS PLEASE NOTE +// +// All language files should use UTF-8 as their encoding and the files must not contain a BOM. +// +// Placeholders can now contain order information, e.g. instead of +// 'Page %s of %s' you can (and should) write 'Page %1$s of %2$s', this allows +// translators to re-order the output of data while ensuring it remains correct +// +// You do not need this where single placeholders are used, e.g. 'Message %d' is fine +// equally where a string contains only two placeholders which are used to wrap text +// in a url you again do not need to specify an order e.g., 'Click %sHERE%s' is fine + +$lang = array_merge($lang, array( + 'PLUPLOAD_ADD_FILES' => 'Add files', + 'PLUPLOAD_ADD_FILES_TO_QUEUE' => 'Add files to the upload queue and click the start button.', + 'PLUPLOAD_DRAG' => 'Drag files here.', + 'PLUPLOAD_ERR_INPUT' => 'Failed to open input stream.', + 'PLUPLOAD_ERR_MOVE_UPLOADED' => 'Failed to move uploaded file.', + 'PLUPLOAD_ERR_OUTPUT' => 'Failed to open output stream.', + 'PLUPLOAD_EXTENSION_ERROR' => 'File extension error.', + 'PLUPLOAD_FILENAME' => 'Filename', + 'PLUPLOAD_FILES_QUEUED' => '%d files queued', + 'PLUPLOAD_GENERIC_ERROR' => 'Generic error.', + 'PLUPLOAD_HTTP_ERROR' => 'HTTP error.', + 'PLUPLOAD_INIT_ERROR' => 'Init error.', + 'PLUPLOAD_IO_ERROR' => 'IO error.', + 'PLUPLOAD_NOT_APPLICABLE' => 'N/A', + 'PLUPLOAD_SECURITY_ERROR' => 'Security error.', + 'PLUPLOAD_SELECT_FILES' => 'Select files', + 'PLUPLOAD_SIZE' => 'Size', + 'PLUPLOAD_SIZE_ERROR' => 'File size error.', + 'PLUPLOAD_STATUS' => 'Status', + 'PLUPLOAD_START_UPLOAD' => 'Start upload', + 'PLUPLOAD_START_CURRENT_UPLOAD' => 'Start uploading queue', + 'PLUPLOAD_STOP_UPLOAD' => 'Stop upload', + 'PLUPLOAD_STOP_CURRENT_UPLOAD' => 'Stop current upload', + // Note: This string is formatted independently by plupload and so does not + // use the same formatting rules as normal phpBB translation strings + 'PLUPLOAD_UPLOADED' => 'Uploaded %d/%d files', +)); diff --git a/phpBB/phpbb/db/migration/data/v310/alpha1.php b/phpBB/phpbb/db/migration/data/v310/alpha1.php index 04f195daeb..368c53125e 100644 --- a/phpBB/phpbb/db/migration/data/v310/alpha1.php +++ b/phpBB/phpbb/db/migration/data/v310/alpha1.php @@ -27,6 +27,7 @@ class alpha1 extends \phpbb\db\migration\migration '\phpbb\db\migration\data\v310\namespaces', '\phpbb\db\migration\data\v310\notifications_cron', '\phpbb\db\migration\data\v310\notification_options_reconvert', + '\phpbb\db\migration\data\v310\plupload', '\phpbb\db\migration\data\v310\signature_module_auth', '\phpbb\db\migration\data\v310\softdelete_mcp_modules', '\phpbb\db\migration\data\v310\teampage', diff --git a/phpBB/phpbb/db/migration/data/v310/plupload.php b/phpBB/phpbb/db/migration/data/v310/plupload.php new file mode 100644 index 0000000000..1787c6dafc --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/plupload.php @@ -0,0 +1,32 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class plupload extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + return isset($this->config['plupload_last_gc']) && + isset($this->config['plupload_salt']); + } + + static public function depends_on() + { + return array('\phpbb\db\migration\data\310\dev'); + } + + public function update_data() + { + return array( + array('config.add', array('plupload_last_gc', 0)), + array('config.add', array('plupload_salt', unique_id())), + ); + } +} diff --git a/phpBB/phpbb/plupload/plupload.php b/phpBB/phpbb/plupload/plupload.php new file mode 100644 index 0000000000..6eb5adf864 --- /dev/null +++ b/phpBB/phpbb/plupload/plupload.php @@ -0,0 +1,374 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\plupload; + +/** + * @ignore + */ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** +* This class handles all server-side plupload functions +* +* @package \phpbb\plupload\plupload +*/ +class plupload +{ + /** + * @var string + */ + protected $phpbb_root_path; + + /** + * @var \phpbb\config\config + */ + protected $config; + + /** + * @var \phpbb\request\request_interface + */ + protected $request; + + /** + * @var \phpbb\user + */ + protected $user; + + /** + * @var \phpbb\php\ini + */ + protected $php_ini; + + /** + * 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 \phpbb\config\config $config + * @param \phpbb\request\request_interface $request + * @param \phpbb\user $user + * @param \phpbb\php\ini $php_ini + * + * @return null + */ + public function __construct($phpbb_root_path, \phpbb\config\config $config, \phpbb\request\request_interface $request, \phpbb\user $user, \phpbb\php\ini $php_ini) + { + $this->phpbb_root_path = $phpbb_root_path; + $this->config = $config; + $this->request = $request; + $this->user = $user; + $this->php_ini = $php_ini; + + $this->upload_directory = $this->phpbb_root_path . $this->config['upload_path']; + $this->temporary_directory = $this->upload_directory . '/plupload'; + } + + /** + * 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); + + $file_info = new \Symfony\Component\HttpFoundation\File\File($file_path); + + // 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' => $file_info->getMimeType($file_path), + ); + } + else + { + $json_response = new \phpbb\json_response(); + $json_response->send(array( + 'jsonrpc' => '2.0', + 'id' => 'id', + 'result' => null, + )); + } + } + + /** + * Fill in the plupload configuration options in the template + * + * @param \phpbb\cache\service $cache + * @param \phpbb\template\template $template + * @param string $s_action The URL to submit the POST data to + * @param int $forum_id The ID of the forum + * + * @return null + */ + public function configure(\phpbb\cache\service $cache, \phpbb\template\template $template, $s_action, $forum_id) + { + $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), + )); + + $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 \phpbb\json_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 \phpbb\cache\service $cache + * @param string $forum_id The ID of the forum + * + * @return string + */ + public function generate_filter_string(\phpbb\cache\service $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'] > 0 && $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 == 0 ? '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($in, 4096)) + { + 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' + ); + } + } +} diff --git a/phpBB/posting.php b/phpBB/posting.php index 1609382551..396b320eac 100644 --- a/phpBB/posting.php +++ b/phpBB/posting.php @@ -452,6 +452,8 @@ if ($mode == 'edit') $orig_poll_options_size = sizeof($post_data['poll_options']); $message_parser = new parse_message(); +$plupload = $phpbb_container->get('plupload'); +$message_parser->set_plupload($plupload); if (isset($post_data['post_text'])) { @@ -1551,6 +1553,11 @@ if (($mode == 'post' || ($mode == 'edit' && $post_id == $post_data['topic_first_ // Show attachment box for adding attachments if true $allowed = ($auth->acl_get('f_attach', $forum_id) && $auth->acl_get('u_attach') && $config['allow_attachments'] && $form_enctype); +if ($allowed) +{ + $plupload->configure($cache, $template, $s_action, $forum_id); +} + // Attachment entry posting_gen_attachment_entry($attachment_data, $filename_data, $allowed); diff --git a/phpBB/styles/prosilver/template/overall_footer.html b/phpBB/styles/prosilver/template/overall_footer.html index e26c94f367..b26a4c1610 100644 --- a/phpBB/styles/prosilver/template/overall_footer.html +++ b/phpBB/styles/prosilver/template/overall_footer.html @@ -65,6 +65,7 @@ <!-- EVENT overall_footer_after --> {$SCRIPTS} +<!-- IF S_PLUPLOAD --><!-- INCLUDE plupload.html --><!-- ENDIF --> </body> </html> diff --git a/phpBB/styles/prosilver/template/overall_header.html b/phpBB/styles/prosilver/template/overall_header.html index 6ca5c86fa4..92baf6ee51 100644 --- a/phpBB/styles/prosilver/template/overall_header.html +++ b/phpBB/styles/prosilver/template/overall_header.html @@ -33,6 +33,11 @@ <link href="{T_THEME_PATH}/bidi.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet" type="text/css" media="screen, projection" /> <!-- ENDIF --> +<!-- IF S_PLUPLOAD --> + <link href="{T_ASSETS_PATH}/plupload/jquery.plupload.queue/css/jquery.plupload.queue.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet" type="text/css" media="screen, projection" /> + <link href="{T_THEME_PATH}/plupload.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet" type="text/css" media="screen, projection" /> +<!-- ENDIF --> + <!--[if lte IE 8]> <link href="{T_THEME_PATH}/tweaks.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet" type="text/css" media="screen, projection" /> <![endif]--> diff --git a/phpBB/styles/prosilver/template/plupload.html b/phpBB/styles/prosilver/template/plupload.html new file mode 100644 index 0000000000..564c1b5c36 --- /dev/null +++ b/phpBB/styles/prosilver/template/plupload.html @@ -0,0 +1,48 @@ +<script type="text/javascript" src="{T_ASSETS_PATH}/plupload/plupload.js"></script> +<script type="text/javascript" src="{T_ASSETS_PATH}/plupload/plupload.html5.js"></script> +<script type="text/javascript" src="{T_ASSETS_PATH}/plupload/jquery.plupload.queue/jquery.plupload.queue.js"></script> +<script type="text/javascript"> +//<![CDATA[ +phpbb.plupload = { + i18n: { + 'Select files': '{LA_PLUPLOAD_SELECT_FILES}', + 'Add files to the upload queue and click the start button.': '{LA_PLUPLOAD_ADD_FILES_TO_QUEUE}', + 'Filename': '{LA_PLUPLOAD_FILENAME}', + 'Status': '{LA_PLUPLOAD_STATUS}', + 'Size': '{LA_PLUPLOAD_SIZE}', + 'Add files': '{LA_PLUPLOAD_ADD_FILES}', + 'Stop current upload': '{LA_PLUPLOAD_STOP_CURRENT_UPLOAD}', + 'Start uploading queue': '{LA_PLUPLOAD_START_CURRENT_UPLOAD}', + 'Uploaded %d/%d files': '{LA_PLUPLOAD_UPLOADED}', + 'N/A': '{LA_PLUPLOAD_NOT_APPLICABLE}', + 'Drag files here.': '{LA_PLUPLOAD_DRAG}', + 'File extension error.': '{LA_PLUPLOAD_EXTENSION_ERROR}', + 'File size error.': '{LA_PLUPLOAD_SIZE_ERROR}', + 'Init error.': '{LA_PLUPLOAD_INIT_ERROR}', + 'HTTP Error.': '{LA_PLUPLOAD_HTTP_ERROR}', + 'Security error.': '{LA_PLUPLOAD_SECURITY_ERROR}', + 'Generic error.': '{LA_PLUPLOAD_GENERIC_ERROR}', + 'IO error.': '{LA_PLUPLOAD_IO_ERROR}', + 'Stop Upload': '{LA_PLUPLOAD_STOP_UPLOAD}', + 'Start upload': '{LA_PLUPLOAD_START_UPLOAD}', + '%d files queued': '{LA_PLUPLOAD_FILES_QUEUED}' + }, + config: { + runtimes: 'html5', + url: '{S_PLUPLOAD_URL}', + max_file_size: '{FILESIZE}b', + chunk_size: '{CHUNK_SIZE}b', + unique_names: true, + filters: [{FILTERS}], + {S_RESIZE} + headers: {'X-PHPBB-USING-PLUPLOAD': '1'}, + file_data_name: 'fileupload', + multipart_params: {'add_file': '{LA_ADD_FILE}'}, + img_path: '{T_ASSETS_PATH}/plupload/jquery.plupload.queue/img', + element_hook: '#attach-panel .inner', + form_hook: '#postform' + } +}; +//]]> +</script> +<script type="text/javascript" src="{T_ASSETS_PATH}/javascript/plupload.js"></script> diff --git a/phpBB/styles/prosilver/theme/plupload.css b/phpBB/styles/prosilver/theme/plupload.css new file mode 100644 index 0000000000..16c26822b5 --- /dev/null +++ b/phpBB/styles/prosilver/theme/plupload.css @@ -0,0 +1,11 @@ +.plupload_filelist li.can_delete:hover { + cursor: pointer; +} + +.plupload_filelist li.can_delete:hover a { + background: url('../../../assets/plupload/jquery.plupload.queue/img/delete.gif'); +} + +.plupload_filelist li a.working { + background: url('../../../assets/plupload/jquery.plupload.queue/img/throbber.gif'); +} |