public function check()
 {
     $user = KunenaUserHelper::get($this->userid);
     $message = KunenaForumMessageHelper::get($this->mesid);
     if ($this->userid != 0 && !$user->exists()) {
         $this->setError(JText::sprintf('COM_KUNENA_LIB_TABLE_ATTACHMENTS_ERROR_USER_INVALID', (int) $user->userid));
     }
     if ($message->id && !$message->exists()) {
         $this->setError(JText::sprintf('COM_KUNENA_LIB_TABLE_ATTACHMENTS_ERROR_MESSAGE_INVALID', (int) $message->id));
     }
     $this->folder = trim($this->folder, '/');
     if (!$this->folder) {
         $this->setError(JText::_('COM_KUNENA_LIB_TABLE_ATTACHMENTS_ERROR_NO_FOLDER'));
     }
     if (!$this->filename) {
         $this->setError(JText::_('COM_KUNENA_LIB_TABLE_ATTACHMENTS_ERROR_NO_FILENAME'));
     }
     if (!$this->filename_real) {
         $this->filename_real = $this->filename;
     }
     $file = JPATH_ROOT . "/{$this->folder}/{$this->filename}";
     if (!is_file($file)) {
         $this->setError(JText::sprintf('COM_KUNENA_LIB_TABLE_ATTACHMENTS_ERROR_FILE_MISSING', "{$this->folder}/{$this->filename}"));
     } else {
         if (!$this->hash) {
             $this->hash = md5_file($file);
         }
         if (!$this->size) {
             $this->size = filesize($file);
         }
         if (!$this->filetype) {
             $this->filetype = KunenaFile::getMime($file);
         }
     }
     return $this->getError() == '';
 }
Beispiel #2
0
 /**
  * Upload a file via AJAX, supports chunks and fallback to regular file upload.
  *
  * @param  array   $options   Upload options.
  *
  * @return array  Updated options.
  * @throws Exception|RuntimeException
  */
 public function ajaxUpload(array $options)
 {
     static $defaults = array('completed' => false, 'filename' => null, 'size' => 0, 'mime' => null, 'hash' => null, 'chunkStart' => 0, 'chunkEnd' => 0);
     $options += $defaults;
     $config = KunenaConfig::getInstance();
     $exception = null;
     $in = null;
     $out = null;
     $size = $bytes = 0;
     $outFile = null;
     // Look for the content type header
     if (isset($_SERVER['HTTP_CONTENT_TYPE'])) {
         $contentType = $_SERVER['HTTP_CONTENT_TYPE'];
     } elseif (isset($_SERVER['CONTENT_TYPE'])) {
         $contentType = $_SERVER['CONTENT_TYPE'];
     } else {
         $contentType = '';
     }
     try {
         // Set filename for future queries.
         $this->filename = $options['filename'];
         $folder = $this->getFolder();
         // Create target directory if it does not exist.
         if (!KunenaFolder::exists($folder) && !KunenaFolder::create($folder)) {
             throw new RuntimeException(JText::_('Failed to create upload directory.'), 500);
         }
         // Calculate temporary filename.
         $outFile = $this->getProtectedFile();
         if ($options['chunkEnd'] > $options['size'] || $options['chunkStart'] > $options['chunkEnd']) {
             throw new RuntimeException(JText::_('COM_KUNENA_UPLOAD_ERROR_EXTRA_CHUNK'), 400);
         }
         if ($options['size'] > max($config->filesize, $config->imagesize) * 1024) {
             throw new RuntimeException(JText::sprintf('COM_KUNENA_UPLOAD_ERROR_SIZE_X', $this->bytes($options['size'])), 400);
         }
         if (strpos($contentType, 'multipart') !== false) {
             // Older WebKit browsers didn't support multi-part in HTML5.
             $exception = $this->checkUpload($_FILES['file']);
             if ($exception) {
                 throw $exception;
             }
             $in = fopen($_FILES['file']['tmp_name'], 'rb');
         } else {
             // Multi-part upload.
             $in = fopen('php://input', 'rb');
         }
         if (!$in) {
             throw new RuntimeException(JText::_('Failed to open upload input stream.'), 500);
         }
         // Open temporary file.
         $out = fopen($outFile, !$options['chunkStart'] ? 'wb' : 'r+b');
         if (!$out) {
             throw new RuntimeException(JText::_('Failed to open upload output stream.'), 500);
         }
         // Get current size for the file.
         $stat = fstat($out);
         if (!$stat) {
             throw new RuntimeException(JText::_('COM_KUNENA_UPLOAD_ERROR_STAT', $options['filename']), 500);
         }
         $size = $stat['size'];
         if ($options['chunkStart'] > $size) {
             throw new RuntimeException(JText::sprintf('Missing data chunk at location %d.', $size), 500);
         }
         fseek($out, $options['chunkStart']);
         while (!feof($in)) {
             // Set script execution time to 8 seconds in order to interrupt stalled file transfers (< 1kb/sec).
             // Not sure if it works, though, needs some testing. :)
             @set_time_limit(8);
             $buff = fread($in, 8192);
             if ($buff === false) {
                 throw new RuntimeException(JText::_('Failed to read from upload input stream.'), 500);
             }
             $bytes = fwrite($out, $buff);
             if ($bytes === false) {
                 throw new RuntimeException(JText::_('Failed to write into upload output stream.'), 500);
             }
             $size += $bytes;
             if ($size > max($config->filesize, $config->imagesize) * 1024) {
                 throw new RuntimeException(JText::sprintf('COM_KUNENA_UPLOAD_ERROR_SIZE_X', $this->bytes($size)), 400);
             }
         }
     } catch (Exception $exception) {
     }
     // Reset script execution time.
     @set_time_limit(25);
     if ($in) {
         fclose($in);
     }
     if ($out) {
         fclose($out);
     }
     if ($exception instanceof Exception) {
         $this->cleanup();
         throw $exception;
     }
     // Generate response.
     if (is_null($options['size']) && $size || $size === $options['size']) {
         $options['size'] = (int) $size;
         $options['completed'] = true;
     }
     $options['chunkStart'] = (int) $size;
     $options['chunkEnd'] = min($size + 1024 * 1024, $size + $this->getMaxSize(), max($size, $options['size'], is_null($options['size']) ? $this->getMaxSize() : 0)) - 1;
     if ($options['completed']) {
         $options['mime'] = KunenaFile::getMime($outFile);
         $options['hash'] = md5_file($outFile);
     } else {
         if ($size) {
             $options['mime'] = KunenaFile::getMime($outFile);
         }
     }
     return $options;
 }