/** * @see \wcf\form\IForm::save() */ public function save() { parent::save(); $returnValues = $this->objectAction->getReturnValues(); // create folder for pictures of this category FileUtil::makePath(NEWS_DIR . 'images/news/' . $returnValues['returnValues']->categoryID . '/'); }
/** * @see \wcf\system\importer\IImporter::import() */ public function import($oldID, array $data, array $additionalData = array()) { // check file location if (!@file_exists($additionalData['fileLocation'])) { return 0; } // get image size $imageData = @getimagesize($additionalData['fileLocation']); if ($imageData === false) { return 0; } $data['width'] = $imageData[0]; $data['height'] = $imageData[1]; // check min size if ($data['width'] < 48 || $data['height'] < 48) { return 0; } // check image type if ($imageData[2] != IMAGETYPE_GIF && $imageData[2] != IMAGETYPE_JPEG && $imageData[2] != IMAGETYPE_PNG) { return 0; } // get file hash if (empty($data['fileHash'])) { $data['fileHash'] = sha1_file($additionalData['fileLocation']); } // get user id $data['userID'] = ImportHandler::getInstance()->getNewID('com.woltlab.wcf.user', $data['userID']); if (!$data['userID']) { return 0; } // save avatar $avatar = UserAvatarEditor::create($data); // check avatar directory // and create subdirectory if necessary $dir = dirname($avatar->getLocation()); if (!@file_exists($dir)) { FileUtil::makePath($dir, 0777); } // copy file try { if (!copy($additionalData['fileLocation'], $avatar->getLocation())) { throw new SystemException(); } // create thumbnails $action = new UserAvatarAction(array($avatar), 'generateThumbnails'); $action->executeAction(); // update owner $sql = "UPDATE\twcf" . WCF_N . "_user\n\t\t\t\tSET\tavatarID = ?\n\t\t\t\tWHERE\tuserID = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($avatar->avatarID, $data['userID'])); return $avatar->avatarID; } catch (SystemException $e) { // copy failed; delete avatar $editor = new UserAvatarEditor($avatar); $editor->delete(); } return 0; }
/** * Creates the target directory if necessary. */ protected function createTargetDir() { if (!@is_dir($this->targetDir)) { if (!FileUtil::makePath($this->targetDir, FileUtil::isApacheModule() ? 0777 : 0755)) { throw new SystemException("Could not create dir '" . $this->targetDir . "'"); } } if (FileUtil::isApacheModule() || !is_writeable($this->targetDir)) { $this->makeWriteable($this->targetDir); } }
/** * Copies a style. * * @return array<string> */ public function copy() { // get unique style name $sql = "SELECT\tstyleName\n\t\t\tFROM\twcf" . WCF_N . "_style\n\t\t\tWHERE\tstyleName LIKE ?\n\t\t\t\tAND styleID <> ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($this->styleEditor->styleName . '%', $this->styleEditor->styleID)); $numbers = array(); $regEx = new Regex('\\((\\d+)\\)$'); while ($row = $statement->fetchArray()) { $styleName = $row['styleName']; if ($regEx->match($styleName)) { $matches = $regEx->getMatches(); // check if name matches the pattern 'styleName (x)' if ($styleName == $this->styleEditor->styleName . ' (' . $matches[1] . ')') { $numbers[] = $matches[1]; } } } $number = count($numbers) ? max($numbers) + 1 : 2; $styleName = $this->styleEditor->styleName . ' (' . $number . ')'; // create the new style $newStyle = StyleEditor::create(array('styleName' => $styleName, 'templateGroupID' => $this->styleEditor->templateGroupID, 'isDisabled' => 1, 'styleDescription' => $this->styleEditor->styleDescription, 'styleVersion' => $this->styleEditor->styleVersion, 'styleDate' => $this->styleEditor->styleDate, 'copyright' => $this->styleEditor->copyright, 'license' => $this->styleEditor->license, 'authorName' => $this->styleEditor->authorName, 'authorURL' => $this->styleEditor->authorURL, 'imagePath' => $this->styleEditor->imagePath)); // check if style description uses i18n if (preg_match('~^wcf.style.styleDescription\\d+$~', $newStyle->styleDescription)) { $styleDescription = 'wcf.style.styleDescription' . $newStyle->styleID; // copy language items $sql = "INSERT INTO\twcf" . WCF_N . "_language_item\n\t\t\t\t\t\t(languageID, languageItem, languageItemValue, languageItemOriginIsSystem, languageCategoryID, packageID)\n\t\t\t\tSELECT\t\tlanguageID, '" . $styleDescription . "', languageItemValue, 0, languageCategoryID, packageID\n\t\t\t\tFROM\t\twcf" . WCF_N . "_language_item\n\t\t\t\tWHERE\t\tlanguageItem = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($newStyle->styleDescription)); // update style description $styleEditor = new StyleEditor($newStyle); $styleEditor->update(array('styleDescription' => $styleDescription)); } // copy style variables $sql = "INSERT INTO\twcf" . WCF_N . "_style_variable_value\n\t\t\t\t\t(styleID, variableID, variableValue)\n\t\t\tSELECT\t\t" . $newStyle->styleID . " AS styleID, value.variableID, value.variableValue\n\t\t\tFROM\t\twcf" . WCF_N . "_style_variable_value value\n\t\t\tWHERE\t\tvalue.styleID = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($this->styleEditor->styleID)); // copy preview image if ($this->styleEditor->image) { // get extension $fileExtension = mb_substr($this->styleEditor->image, mb_strrpos($this->styleEditor->image, '.')); // copy existing preview image if (@copy(WCF_DIR . 'images/' . $this->styleEditor->image, WCF_DIR . 'images/stylePreview-' . $newStyle->styleID . $fileExtension)) { // bypass StyleEditor::update() to avoid scaling of already fitting image $sql = "UPDATE\twcf" . WCF_N . "_style\n\t\t\t\t\tSET\timage = ?\n\t\t\t\t\tWHERE\tstyleID = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array('stylePreview-' . $newStyle->styleID . $fileExtension, $newStyle->styleID)); } } // copy images if ($this->styleEditor->imagePath && is_dir(WCF_DIR . $this->styleEditor->imagePath)) { $path = FileUtil::removeTrailingSlash($this->styleEditor->imagePath); $newPath = ''; $i = 2; while (true) { $newPath = "{$path}-{$i}/"; if (!file_exists(WCF_DIR . $newPath)) { break; } $i++; } if (!FileUtil::makePath(WCF_DIR . $newPath)) { $newPath = ''; } if ($newPath) { $src = FileUtil::addTrailingSlash(WCF_DIR . $this->styleEditor->imagePath); $dst = WCF_DIR . $newPath; $dir = opendir($src); while (($file = readdir($dir)) !== false) { if ($file != '.' && $file != '..' && !is_dir($file)) { @copy($src . $file, $dst . $file); } } closedir($dir); } $sql = "UPDATE\twcf" . WCF_N . "_style\n\t\t\t\tSET\timagePath = ?\n\t\t\t\tWHERE\tstyleID = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($newPath, $newStyle->styleID)); } StyleCacheBuilder::getInstance()->reset(); return array('redirectURL' => LinkHandler::getInstance()->getLink('StyleEdit', array('id' => $newStyle->styleID))); }
/** * @see wcf\system\io\IArchive::extract() */ public function extract($index, $destination) { if (!$this->read) { $this->open(); $this->readContent(); } $header = $this->getFileInfo($index); FileUtil::makePath(dirname($destination)); if ($header['type'] === 'folder') { FileUtil::makePath($destination); return; } // seek to offset $this->file->seek($header['offset']); $targetFile = new File($destination); // read data $n = floor($header['size'] / 512); for ($i = 0; $i < $n; $i++) { $content = $this->file->read(512); $targetFile->write($content, 512); } if ($header['size'] % 512 != 0) { $content = $this->file->read(512); $targetFile->write($content, $header['size'] % 512); } $targetFile->close(); if (FileUtil::isApacheModule() || !@$targetFile->is_writable()) { @$targetFile->chmod(0777); } else { @$targetFile->chmod(0755); } if ($header['mtime']) { @$targetFile->touch($header['mtime']); } // check filesize if (filesize($destination) != $header['size']) { throw new SystemException("Could not untar file '" . $header['filename'] . "' to '" . $destination . "'. Maybe disk quota exceeded in folder '" . dirname($destination) . "'."); } return true; }
/** * @see wcf\system\io\IArchive::extract() */ public function extract($offset, $destination) { if (!is_int($offset)) { $offset = $this->getIndexByFilename($offset); } try { $file = $this->readFile($offset); } catch (SystemException $e) { return false; } FileUtil::makePath(dirname($destination)); if ($file['header']['type'] === 'folder') { FileUtil::makePath($destination); return; } $targetFile = new File($destination); $targetFile->write($file['content'], strlen($file['content'])); $targetFile->close(); if (FileUtil::isApacheModule() || !@$targetFile->is_writable()) { @$targetFile->chmod(0777); } else { @$targetFile->chmod(0755); } if ($file['header']['mtime']) { @$targetFile->touch($file['header']['mtime']); } // check filesize if (filesize($destination) != $file['header']['size']) { throw new SystemException("Could not unzip file '" . $file['header']['filename'] . "' to '" . $destination . "'. Maybe disk quota exceeded in folder '" . dirname($destination) . "'."); } return true; }
/** * Fetches an avatar from a remote server and sets it for given user. */ public function fetchRemoteAvatar() { $avatarID = 0; $filename = ''; // fetch avatar from URL try { $request = new HTTPRequest($this->parameters['url']); $request->execute(); $reply = $request->getReply(); $filename = FileUtil::getTemporaryFilename('avatar_'); file_put_contents($filename, $reply['body']); $imageData = getimagesize($filename); if ($imageData === false) { throw new SystemException('Downloaded file is not an image'); } } catch (\Exception $e) { if (!empty($filename)) { @unlink($filename); } return; } // rescale avatar if required try { $newFilename = $this->enforceDimensions($filename); if ($newFilename !== $filename) { @unlink($filename); } $filename = $newFilename; $imageData = getimagesize($filename); if ($imageData === false) { throw new SystemException('Rescaled file is not an image'); } } catch (\Exception $e) { @unlink($filename); return; } $tmp = parse_url($this->parameters['url']); if (!isset($tmp['path'])) { @unlink($filename); return; } $tmp = pathinfo($tmp['path']); if (!isset($tmp['basename']) || !isset($tmp['extension'])) { @unlink($filename); return; } $data = array('avatarName' => $tmp['basename'], 'avatarExtension' => $tmp['extension'], 'width' => $imageData[0], 'height' => $imageData[1], 'userID' => $this->parameters['userEditor']->userID, 'fileHash' => sha1_file($filename)); // create avatar $avatar = UserAvatarEditor::create($data); // check avatar directory // and create subdirectory if necessary $dir = dirname($avatar->getLocation()); if (!@file_exists($dir)) { FileUtil::makePath($dir, 0777); } // move uploaded file if (@copy($filename, $avatar->getLocation())) { @unlink($filename); // create thumbnails $action = new UserAvatarAction(array($avatar), 'generateThumbnails'); $action->executeAction(); $avatarID = $avatar->avatarID; } else { @unlink($filename); // moving failed; delete avatar $editor = new UserAvatarEditor($avatar); $editor->delete(); } // update user if ($avatarID) { $this->parameters['userEditor']->update(array('avatarID' => $avatarID, 'enableGravatar' => 0)); // delete old avatar if ($this->parameters['userEditor']->avatarID) { $action = new UserAvatarAction(array($this->parameters['userEditor']->avatarID), 'delete'); $action->executeAction(); } } // reset user storage UserStorageHandler::getInstance()->reset(array($this->parameters['userEditor']->userID), 'avatar'); }
/** * 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; }
/** * Handles upload of a file. */ public function upload() { $files = $this->parameters['__files']->getFiles(); $failedUploads = array(); $result = array('files' => array(), 'errors' => array()); foreach ($files as $file) { try { if ($file->getValidationErrorType()) { $failedUploads[] = $file; continue; } $data = array('title' => $file->getFilename(), 'filesize' => $file->getFilesize(), 'fileType' => $file->getMimeType(), 'fileHash' => sha1_file($file->getLocation()), 'uploadTime' => TIME_NOW); $uploadedFile = FileEditor::create($data); //clear cache FileCacheBuilder::getInstance()->reset(); // create subdirectory if necessary $dir = dirname($uploadedFile->getLocation()); if (!@file_exists($dir)) { FileUtil::makePath($dir, 0777); } // move uploaded file if (@move_uploaded_file($file->getLocation(), $uploadedFile->getLocation())) { @unlink($file->getLocation()); $result['files'][$file->getInternalFileID()] = array('fileID' => $uploadedFile->fileID, 'title' => $uploadedFile->getTitle(), 'filesize' => $uploadedFile->filesize, 'formattedFilesize' => FileUtil::formatFilesize($uploadedFile->filesize)); } else { // failure $editor = new FileEditor($uploadedFile); $editor->delete(); throw new UserInputException('file', 'uploadFailed'); } } catch (UserInputException $e) { $file->setValidationErrorType($e->getType()); $failedUploads[] = $file; } } // return results foreach ($failedUploads as $failedUpload) { $result['errors'][$failedUpload->getInternalFileID()] = array('title' => $failedUpload->getFilename(), 'filesize' => $failedUpload->getFilesize(), 'errorType' => $failedUpload->getValidationErrorType()); } return $result; }
foreach ($list->getObjects() as $image) { //get file hash $fileHash = sha1_file(CMS_DIR . 'images/news/' . $image->filename); $folder = substr($fileHash, 0, 2); //get size $size = filesize(CMS_DIR . 'images/news/' . $image->filename); //mime type $mime = FileUtil::getMimeType(CMS_DIR . 'images/news/' . $image->filename); //create db entry $action = new FileAction(array(), 'create', array('data' => array('title' => $image->getTitle(), 'filesize' => $size, 'fileType' => $mime, 'fileHash' => $fileHash, 'uploadTime' => TIME_NOW))); $action->executeAction(); $returnValues = $action->getReturnValues(); //set old IDs $oldIDs[$image->imageID] = $returnValues['returnValues']->fileID; if (!is_dir(CMS_DIR . 'files/' . $folder)) { FileUtil::makePath(CMS_DIR . 'files/' . $folder); } copy(CMS_DIR . 'images/news/' . $image->filename, CMS_DIR . 'files/' . $folder . '/' . $returnValues['returnValues']->fileID . '-' . $fileHash); @unlink(CMS_DIR . 'images/news/' . $image->filename); //insert into news image category $sql = "INSERT INTO cms" . WCF_N . "_file_to_category VALUES (?, ?)"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($returnValues['returnValues']->fileID, $categoryID)); } //loop through news $list = new NewsList(); $list->readObjects(); foreach ($list->getObjects() as $news) { //check if image is set ( no foreign key is given :( ) if ($news->imageID !== 0 && isset($oldIDs[$news->imageID])) { $editor = new NewsEditor($news);