/** * @see \wcf\page\IPage::show() */ public function show() { parent::show(); if (!$this->tiny && !$this->thumbnail) { // update download count $editor = new AttachmentEditor($this->attachment); $editor->update(array('downloads' => $this->attachment->downloads + 1, 'lastDownloadTime' => TIME_NOW)); } // send file to client $this->fileReader->send(); exit; }
/** * Handles uploaded attachments. */ public function upload() { // get object type $objectType = ObjectTypeCache::getInstance()->getObjectTypeByName('com.woltlab.wcf.attachment.objectType', $this->parameters['objectType']); // save files $thumbnails = $attachments = $failedUploads = array(); $files = $this->parameters['__files']->getFiles(); foreach ($files as $file) { if ($file->getValidationErrorType()) { $failedUploads[] = $file; continue; } $data = array('objectTypeID' => $objectType->objectTypeID, 'objectID' => intval($this->parameters['objectID']), 'userID' => WCF::getUser()->userID ?: null, 'tmpHash' => !$this->parameters['objectID'] ? $this->parameters['tmpHash'] : '', 'filename' => $file->getFilename(), 'filesize' => $file->getFilesize(), 'fileType' => $file->getMimeType(), 'fileHash' => sha1_file($file->getLocation()), 'uploadTime' => TIME_NOW); // get image data if (($imageData = $file->getImageData()) !== null) { $data['width'] = $imageData['width']; $data['height'] = $imageData['height']; $data['fileType'] = $imageData['mimeType']; if (preg_match('~^image/(gif|jpe?g|png)$~i', $data['fileType'])) { $data['isImage'] = 1; } } // create attachment $attachment = AttachmentEditor::create($data); // check attachment directory // and create subdirectory if necessary $dir = dirname($attachment->getLocation()); if (!@file_exists($dir)) { FileUtil::makePath($dir, 0777); } // move uploaded file if (@move_uploaded_file($file->getLocation(), $attachment->getLocation())) { if ($attachment->isImage) { $thumbnails[] = $attachment; // rotate image based on the exif data $neededMemory = $attachment->width * $attachment->height * ($attachment->fileType == 'image/png' ? 4 : 3) * 2.1; if (FileUtil::getMemoryLimit() == -1 || FileUtil::getMemoryLimit() > memory_get_usage() + $neededMemory) { $exifData = ExifUtil::getExifData($attachment->getLocation()); if (!empty($exifData)) { $orientation = ExifUtil::getOrientation($exifData); if ($orientation != ExifUtil::ORIENTATION_ORIGINAL) { $adapter = ImageHandler::getInstance()->getAdapter(); $adapter->loadFile($attachment->getLocation()); $newImage = null; switch ($orientation) { case ExifUtil::ORIENTATION_180_ROTATE: $newImage = $adapter->rotate(180); break; case ExifUtil::ORIENTATION_90_ROTATE: $newImage = $adapter->rotate(90); break; case ExifUtil::ORIENTATION_270_ROTATE: $newImage = $adapter->rotate(270); break; case ExifUtil::ORIENTATION_HORIZONTAL_FLIP: case ExifUtil::ORIENTATION_VERTICAL_FLIP: case ExifUtil::ORIENTATION_VERTICAL_FLIP_270_ROTATE: case ExifUtil::ORIENTATION_HORIZONTAL_FLIP_270_ROTATE: // unsupported break; } if ($newImage !== null) { $adapter->load($newImage, $adapter->getType()); } $adapter->writeImage($attachment->getLocation()); if ($newImage !== null) { // update width, height and filesize of the attachment if ($orientation == ExifUtil::ORIENTATION_90_ROTATE || $orientation == ExifUtil::ORIENTATION_270_ROTATE) { $attachmentEditor = new AttachmentEditor($attachment); $attachmentEditor->update(array('height' => $attachment->width, 'width' => $attachment->height, 'filesize' => filesize($attachment->getLocation()))); } } } } } } else { // check whether we can create thumbnails for this file $this->eventAttachment = $attachment; $this->eventData = array('hasThumbnail' => false); EventHandler::getInstance()->fireAction($this, 'checkThumbnail'); if ($this->eventData['hasThumbnail']) { $thumbnails[] = $attachment; } } $attachments[$file->getInternalFileID()] = $attachment; } else { // moving failed; delete attachment $editor = new AttachmentEditor($attachment); $editor->delete(); } } // generate thumbnails if (ATTACHMENT_ENABLE_THUMBNAILS) { if (!empty($thumbnails)) { $action = new AttachmentAction($thumbnails, 'generateThumbnails'); $action->executeAction(); } } // return result $result = array('attachments' => array(), 'errors' => array()); if (!empty($attachments)) { // get attachment ids $attachmentIDs = $attachmentToFileID = array(); foreach ($attachments as $internalFileID => $attachment) { $attachmentIDs[] = $attachment->attachmentID; $attachmentToFileID[$attachment->attachmentID] = $internalFileID; } // get attachments from database (check thumbnail status) $attachmentList = new AttachmentList(); $attachmentList->getConditionBuilder()->add('attachment.attachmentID IN (?)', array($attachmentIDs)); $attachmentList->readObjects(); foreach ($attachmentList as $attachment) { $result['attachments'][$attachmentToFileID[$attachment->attachmentID]] = array('filename' => $attachment->filename, 'filesize' => $attachment->filesize, 'formattedFilesize' => FileUtil::formatFilesize($attachment->filesize), 'isImage' => $attachment->isImage, 'attachmentID' => $attachment->attachmentID, 'tinyURL' => $attachment->tinyThumbnailType ? LinkHandler::getInstance()->getLink('Attachment', array('object' => $attachment), 'tiny=1') : '', 'thumbnailURL' => $attachment->thumbnailType ? LinkHandler::getInstance()->getLink('Attachment', array('object' => $attachment), 'thumbnail=1') : '', 'url' => LinkHandler::getInstance()->getLink('Attachment', array('object' => $attachment)), 'height' => $attachment->height, 'width' => $attachment->width); } } foreach ($failedUploads as $failedUpload) { $result['errors'][$failedUpload->getInternalFileID()] = array('filename' => $failedUpload->getFilename(), 'filesize' => $failedUpload->getFilesize(), 'errorType' => $failedUpload->getValidationErrorType()); } return $result; }