Verzeichnisstruktur phpBB-3.1.0


Veröffentlicht
27.10.2014

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

plupload.php

Zuletzt modifiziert: 09.10.2024, 12:52 - Dateigröße: 9.72 KiB


001  <?php
002  /**
003  *
004  * This file is part of the phpBB Forum Software package.
005  *
006  * @copyright (c) phpBB Limited <https://www.phpbb.com>
007  * @license GNU General Public License, version 2 (GPL-2.0)
008  *
009  * For full copyright and license information, please see
010  * the docs/CREDITS.txt file.
011  *
012  */
013   
014  namespace phpbb\plupload;
015   
016  /**
017  * This class handles all server-side plupload functions
018  */
019  class plupload
020  {
021      /**
022      * @var string
023      */
024      protected $phpbb_root_path;
025   
026      /**
027      * @var \phpbb\config\config
028      */
029      protected $config;
030   
031      /**
032      * @var \phpbb\request\request_interface
033      */
034      protected $request;
035   
036      /**
037      * @var \phpbb\user
038      */
039      protected $user;
040   
041      /**
042      * @var \phpbb\php\ini
043      */
044      protected $php_ini;
045   
046      /**
047      * @var \phpbb\mimetype\guesser
048      */
049      protected $mimetype_guesser;
050   
051      /**
052      * Final destination for uploaded files, i.e. the "files" directory.
053      * @var string
054      */
055      protected $upload_directory;
056   
057      /**
058      * Temporary upload directory for plupload uploads.
059      * @var string
060      */
061      protected $temporary_directory;
062   
063      /**
064      * Constructor.
065      *
066      * @param string $phpbb_root_path
067      * @param \phpbb\config\config $config
068      * @param \phpbb\request\request_interface $request
069      * @param \phpbb\user $user
070      * @param \phpbb\php\ini $php_ini
071      * @param \phpbb\mimetype\guesser $mimetype_guesser
072      */
073      public function __construct($phpbb_root_path, \phpbb\config\config $config, \phpbb\request\request_interface $request, \phpbb\user $user, \phpbb\php\ini $php_ini, \phpbb\mimetype\guesser $mimetype_guesser)
074      {
075          $this->phpbb_root_path = $phpbb_root_path;
076          $this->config = $config;
077          $this->request = $request;
078          $this->user = $user;
079          $this->php_ini = $php_ini;
080          $this->mimetype_guesser = $mimetype_guesser;
081   
082          $this->set_default_directories();
083      }
084   
085      /**
086      * Plupload allows for chunking so we must check for that and assemble
087      * the whole file first before performing any checks on it.
088      *
089      * @param string $form_name The name of the file element in the upload form
090      *
091      * @return array|null    null if there are no chunks to piece together
092      *                        otherwise array containing the path to the
093      *                        pieced-together file and its size
094      */
095      public function handle_upload($form_name)
096      {
097          $chunks_expected = $this->request->variable('chunks', 0);
098   
099          // If chunking is disabled or we are not using plupload, just return
100          // and handle the file as usual
101          if ($chunks_expected < 2)
102          {
103              return;
104          }
105   
106          $file_name = $this->request->variable('name', '');
107          $chunk = $this->request->variable('chunk', 0);
108   
109          $this->user->add_lang('plupload');
110          $this->prepare_temporary_directory();
111   
112          $file_path = $this->temporary_filepath($file_name);
113          $this->integrate_uploaded_file($form_name, $chunk, $file_path);
114   
115          // If we are done with all the chunks, strip the .part suffix and then
116          // handle the resulting file as normal, otherwise die and await the
117          // next chunk.
118          if ($chunk == $chunks_expected - 1)
119          {
120              rename("{$file_path}.part", $file_path);
121   
122              // Reset upload directories to defaults once completed
123              $this->set_default_directories();
124   
125              // Need to modify some of the $_FILES values to reflect the new file
126              return array(
127                  'tmp_name' => $file_path,
128                  'name' => $this->request->variable('real_filename', ''),
129                  'size' => filesize($file_path),
130                  'type' => $this->mimetype_guesser->guess($file_path, $file_name),
131              );
132          }
133          else
134          {
135              $json_response = new \phpbb\json_response();
136              $json_response->send(array(
137                  'jsonrpc' => '2.0',
138                  'id' => 'id',
139                  'result' => null,
140              ));
141          }
142      }
143   
144      /**
145      * Fill in the plupload configuration options in the template
146      *
147      * @param \phpbb\cache\service        $cache
148      * @param \phpbb\template\template    $template
149      * @param string                        $s_action The URL to submit the POST data to
150      * @param int                        $forum_id The ID of the forum
151      * @param int                        $max_files Maximum number of files allowed. 0 for unlimited.
152      *
153      * @return null
154      */
155      public function configure(\phpbb\cache\service $cache, \phpbb\template\template $template, $s_action, $forum_id, $max_files)
156      {
157          $filters = $this->generate_filter_string($cache, $forum_id);
158          $chunk_size = $this->get_chunk_size();
159          $resize = $this->generate_resize_string();
160   
161          $template->assign_vars(array(
162              'S_RESIZE'            => $resize,
163              'S_PLUPLOAD'        => true,
164              'FILTERS'            => $filters,
165              'CHUNK_SIZE'        => $chunk_size,
166              'S_PLUPLOAD_URL'    => htmlspecialchars_decode($s_action),
167              'MAX_ATTACHMENTS'    => $max_files,
168              'ATTACH_ORDER'        => ($this->config['display_order']) ? 'asc' : 'desc',
169              'L_TOO_MANY_ATTACHMENTS'    => $this->user->lang('TOO_MANY_ATTACHMENTS', $max_files),
170          ));
171   
172          $this->user->add_lang('plupload');
173      }
174   
175      /**
176      * Checks whether the page request was sent by plupload or not
177      *
178      * @return bool
179      */
180      public function is_active()
181      {
182          return $this->request->header('X-PHPBB-USING-PLUPLOAD', false);
183      }
184   
185      /**
186      * Returns whether the current HTTP request is a multipart request.
187      *
188      * @return bool
189      */
190      public function is_multipart()
191      {
192          $content_type = $this->request->server('CONTENT_TYPE');
193   
194          return strpos($content_type, 'multipart') === 0;
195      }
196   
197      /**
198      * Sends an error message back to the client via JSON response
199      *
200      * @param int $code        The error code
201      * @param string $msg    The translation string of the message to be sent
202      *
203      * @return null
204      */
205      public function emit_error($code, $msg)
206      {
207          $json_response = new \phpbb\json_response();
208          $json_response->send(array(
209              'jsonrpc' => '2.0',
210              'id' => 'id',
211              'error' => array(
212                  'code' => $code,
213                  'message' => $this->user->lang($msg),
214              ),
215          ));
216      }
217   
218      /**
219      * Looks at the list of allowed extensions and generates a string
220      * appropriate for use in configuring plupload with
221      *
222      * @param \phpbb\cache\service $cache
223      * @param string $forum_id The ID of the forum
224      *
225      * @return string
226      */
227      public function generate_filter_string(\phpbb\cache\service $cache, $forum_id)
228      {
229          $attach_extensions = $cache->obtain_attach_extensions($forum_id);
230          unset($attach_extensions['_allowed_']);
231          $groups = array();
232   
233          // Re-arrange the extension array to $groups[$group_name][]
234          foreach ($attach_extensions as $extension => $extension_info)
235          {
236              if (!isset($groups[$extension_info['group_name']]))
237              {
238                  $groups[$extension_info['group_name']] = array();
239              }
240   
241              $groups[$extension_info['group_name']][] = $extension;
242          }
243   
244          $filters = array();
245          foreach ($groups as $group => $extensions)
246          {
247              $filters[] = sprintf(
248                  "{title: '%s', extensions: '%s'}",
249                  addslashes(ucfirst(strtolower($group))),
250                  addslashes(implode(',', $extensions))
251              );
252          }
253   
254          return implode(',', $filters);
255      }
256   
257      /**
258      * Generates a string that is used to tell plupload to automatically resize
259      * files before uploading them.
260      *
261      * @return string
262      */
263      public function generate_resize_string()
264      {
265          $resize = '';
266          if ($this->config['img_max_height'] > 0 && $this->config['img_max_width'] > 0)
267          {
268              $resize = sprintf(
269                  'resize: {width: %d, height: %d, quality: 100},',
270                  (int) $this->config['img_max_height'],
271                  (int) $this->config['img_max_width']
272              );
273          }
274   
275          return $resize;
276      }
277   
278      /**
279      * Checks various php.ini values and the maximum file size to determine
280      * the maximum size chunks a file can be split up into for upload
281      *
282      * @return int
283      */
284      public function get_chunk_size()
285      {
286          $max = min(
287              $this->php_ini->get_bytes('upload_max_filesize'),
288              $this->php_ini->get_bytes('post_max_size'),
289              max(1, $this->php_ini->get_bytes('memory_limit')),
290              $this->config['max_filesize']
291          );
292   
293          // Use half of the maximum possible to leave plenty of room for other
294          // POST data.
295          return floor($max / 2);
296      }
297   
298      protected function temporary_filepath($file_name)
299      {
300          // Must preserve the extension for plupload to work.
301          return sprintf(
302              '%s/%s_%s%s',
303              $this->temporary_directory,
304              $this->config['plupload_salt'],
305              md5($file_name),
306              \filespec::get_extension($file_name)
307          );
308      }
309   
310      /**
311      * Checks whether the chunk we are about to deal with was actually uploaded
312      * by PHP and actually exists, if not, it generates an error
313      *
314      * @param string $form_name The name of the file in the form data
315      *
316      * @return null
317      */
318      protected function integrate_uploaded_file($form_name, $chunk, $file_path)
319      {
320          $is_multipart = $this->is_multipart();
321          $upload = $this->request->file($form_name);
322          if ($is_multipart && (!isset($upload['tmp_name']) || !is_uploaded_file($upload['tmp_name'])))
323          {
324              $this->emit_error(103, 'PLUPLOAD_ERR_MOVE_UPLOADED');
325          }
326   
327          $tmp_file = $this->temporary_filepath($upload['tmp_name']);
328   
329          if (!move_uploaded_file($upload['tmp_name'], $tmp_file))
330          {
331              $this->emit_error(103, 'PLUPLOAD_ERR_MOVE_UPLOADED');
332          }
333   
334          $out = fopen("{$file_path}.part", $chunk == 0 ? 'wb' : 'ab');
335          if (!$out)
336          {
337              $this->emit_error(102, 'PLUPLOAD_ERR_OUTPUT');
338          }
339   
340          $in = fopen(($is_multipart) ? $tmp_file : 'php://input', 'rb');
341          if (!$in)
342          {
343              $this->emit_error(101, 'PLUPLOAD_ERR_INPUT');
344          }
345   
346          while ($buf = fread($in, 4096))
347          {
348              fwrite($out, $buf);
349          }
350   
351          fclose($in);
352          fclose($out);
353   
354          if ($is_multipart)
355          {
356              unlink($tmp_file);
357          }
358      }
359   
360      /**
361      * Creates the temporary directory if it does not already exist.
362      *
363      * @return null
364      */
365      protected function prepare_temporary_directory()
366      {
367          if (!file_exists($this->temporary_directory))
368          {
369              mkdir($this->temporary_directory);
370   
371              copy(
372                  $this->upload_directory . '/index.htm',
373                  $this->temporary_directory . '/index.htm'
374              );
375          }
376      }
377   
378      /**
379      * Sets the default directories for uploads
380      *
381      * @return null
382      */
383      protected function set_default_directories()
384      {
385          $this->upload_directory = $this->phpbb_root_path . $this->config['upload_path'];
386          $this->temporary_directory = $this->upload_directory . '/plupload';
387      }
388   
389      /**
390      * Sets the upload directories to the specified paths
391      *
392      * @param string $upload_directory Upload directory
393      * @param string $temporary_directory Temporary directory
394      *
395      * @return null
396      */
397      public function set_upload_directories($upload_directory, $temporary_directory)
398      {
399          $this->upload_directory = $upload_directory;
400          $this->temporary_directory = $temporary_directory;
401      }
402  }
403