/** * upload an attachment * * @param Integer $forumId * @param String $groupId * @return Object $oMbqEtAtt */ public function uploadAttachment($oMbqEtForum, $groupId = null) { //ref wcf\action\AJAXUploadAction,wcf\action\AJAXProxyAction,wcf\data\attachment\AttachmentAction $parameters['objectType'] = 'com.woltlab.wbb.post'; $parameters['objectID'] = 0; $parameters['tmpHash'] = $groupId ? $groupId : StringUtil::getRandomID(); $parameters['parentObjectID'] = $oMbqEtForum->forumId->oriValue; $parameters['__files'] = UploadHandler::getUploadHandler('attachment'); //ref AJAXUploadAction::readParameters() $oAttachmentAction = new AttachmentAction(array(), 'upload', $parameters); //ref AJAXProxyAction::invoke() $oAttachmentAction->validateAction(); //todo:catch exception $ret = $oAttachmentAction->executeAction(); //todo:catch exception if ($ret['returnValues']['attachments']) { $r = array_shift($ret['returnValues']['attachments']); $oMbqEtAtt = MbqMain::$oClk->newObj('MbqEtAtt'); $oMbqEtAtt->attId->setOriValue($r['attachmentID']); $oMbqEtAtt->groupId->setOriValue($parameters['tmpHash']); $oMbqEtAtt->filtersSize->setOriValue($r['filesize']); $oMbqEtAtt->uploadFileName->setOriValue($r['filename']); return $oMbqEtAtt; } else { MbqError::alert('', "Upload attachment failed!", '', MBQ_ERR_APP); } }
/** * @see \wcf\system\importer\IImporter::import() */ public function import($oldID, array $data, array $additionalData = array()) { $data['packageID'] = 1; // set temporary option name $data['optionName'] = StringUtil::getRandomID(); if ($data['optionType'] == 'boolean' || $data['optionType'] == 'integer') { if (isset($data['defaultValue'])) { $data['defaultValue'] = intval($data['defaultValue']); } } // create category $this->createCategory($data['categoryName']); // save option $action = new UserOptionAction(array(), 'create', array('data' => $data)); $returnValues = $action->executeAction(); $userOption = $returnValues['returnValues']; // update generic option name $editor = new UserOptionEditor($userOption); $editor->update(array('optionName' => 'option' . $userOption->optionID)); // save name $sql = "INSERT IGNORE INTO\twcf" . WCF_N . "_language_item\n\t\t\t\t\t\t(languageID, languageItem, languageItemValue, languageItemOriginIsSystem, languageCategoryID, packageID)\n\t\t\tVALUES\t\t\t(?, ?, ?, ?, ?, ?)"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array(LanguageFactory::getInstance()->getDefaultLanguageID(), 'wcf.user.option.option' . $userOption->optionID, $additionalData['name'], 0, $this->languageCategoryID, 1)); ImportHandler::getInstance()->saveNewID('com.woltlab.wcf.user.option', $oldID, $userOption->optionID); return $userOption->optionID; }
/** * action implement */ public function actionImplement() { if (!MbqMain::$oMbqConfig->moduleIsEnable('forum')) { MbqError::alert('', "Not support module forum!", '', MBQ_ERR_NOT_SUPPORT); } $forumId = MbqMain::$input['forum_id']; $groupId = MbqMain::$input['group_id'] ? MbqMain::$input['group_id'] : StringUtil::getRandomID(); $oMbqRdEtForum = MbqMain::$oClk->newObj('MbqRdEtForum'); $objsMbqEtForum = $oMbqRdEtForum->getObjsMbqEtForum(array($forumId), array('case' => 'byForumIds')); if ($objsMbqEtForum && ($oMbqEtForum = $objsMbqEtForum[0])) { $oMbqAclEtAtt = MbqMain::$oClk->newObj('MbqAclEtAtt'); if ($oMbqAclEtAtt->canAclUploadAttach($oMbqEtForum)) { //acl judge $oMbqWrEtAtt = MbqMain::$oClk->newObj('MbqWrEtAtt'); $oMbqEtAtt = $oMbqWrEtAtt->uploadAttachment($forumId, $groupId); $oMbqRdEtAtt = MbqMain::$oClk->newObj('MbqRdEtAtt'); $this->data['result'] = true; $data1 = $oMbqRdEtAtt->returnApiDataAttachment($oMbqEtAtt); MbqMain::$oMbqCm->mergeApiData($this->data, $data1); } else { MbqError::alert('', '', '', MBQ_ERR_APP); } } else { MbqError::alert('', "Need valid forum id!", '', MBQ_ERR_APP); } }
/** * @see \wcf\data\DatabaseObjectEditor::update() */ public function update(array $parameters = array()) { // update salt and create new password hash if (isset($parameters['password']) && $parameters['password'] !== '') { $parameters['password'] = PasswordUtil::getDoubleSaltedHash($parameters['password']); $parameters['accessToken'] = StringUtil::getRandomID(); // update accessToken $this->accessToken = $parameters['accessToken']; } else { unset($parameters['password'], $parameters['accessToken']); } parent::update($parameters); }
/** * Reorders content to provide a logical order. In fact the content of * '{content}' is moved outside the if-condition in order to capture * the content during runtime, safely determining wether content is empty * or not. * * @param array $matches * @return string */ protected static function replaceContentCallback(array $matches) { $beforeContent = $matches[1]; $content = $matches[2]; $afterContent = $matches[3]; $elseContent = isset($matches[5]) ? $matches[5] : ''; $variable = 'hascontent_' . StringUtil::getRandomID(); $newContent = '{capture assign=' . $variable . '}' . $content . '{/capture}' . "\n"; $newContent .= '{assign var=' . $variable . ' value=$' . $variable . '|trim}' . "\n"; $newContent .= '{if $' . $variable . '}' . $beforeContent . '{@$' . $variable . '}' . "\n" . $afterContent; if (!empty($elseContent)) { $newContent .= '{else}' . $elseContent . "\n"; } $newContent .= '{/if}' . "\n"; return $newContent; }
/** * @see \wcf\system\template\ICompilerTemplatePlugin::executeStart() */ public function executeStart($tagArgs, TemplateScriptingCompiler $compiler) { $compiler->pushTag('implode'); if (!isset($tagArgs['from'])) { throw new SystemException($compiler->formatSyntaxError("missing 'from' argument in implode tag", $compiler->getCurrentIdentifier(), $compiler->getCurrentLineNo())); } if (!isset($tagArgs['item'])) { throw new SystemException($compiler->formatSyntaxError("missing 'item' argument in implode tag", $compiler->getCurrentIdentifier(), $compiler->getCurrentLineNo())); } $hash = StringUtil::getRandomID(); $glue = isset($tagArgs['glue']) ? $tagArgs['glue'] : "', '"; $this->tagStack[] = array('hash' => $hash, 'glue' => $glue); $phpCode = "<?php\n"; $phpCode .= "\$_length" . $hash . " = count(" . $tagArgs['from'] . ");\n"; $phpCode .= "\$_i" . $hash . " = 0;\n"; $phpCode .= "foreach (" . $tagArgs['from'] . " as " . (isset($tagArgs['key']) ? (mb_substr($tagArgs['key'], 0, 1) != '$' ? "\$this->v[" . $tagArgs['key'] . "]" : $tagArgs['key']) . " => " : '') . (mb_substr($tagArgs['item'], 0, 1) != '$' ? "\$this->v[" . $tagArgs['item'] . "]" : $tagArgs['item']) . ") { ?>"; return $phpCode; }
/** * Reorders content to provide a logical order. In fact the content of * '{content}' is moved outside the if-condition in order to capture * the content during runtime, safely determining wether content is empty * or not. * * @param array $matches * @return string */ protected static function replaceContentCallback(array $matches) { $beforeContent = $matches['before']; $content = $matches['content']; $afterContent = $matches['after']; $elseContent = (isset($matches['else'])) ? $matches['else'] : ''; $assignContent = (isset($matches['assign']) && !empty($matches['assign'])) ? $matches['assign'] : ''; $variable = 'hascontent_' . StringUtil::getRandomID(); $newContent = '{capture assign='.$variable.'}'.$content.'{/capture}'."\n"; $newContent .= '{assign var='.$variable.' value=$'.$variable.'|trim}'."\n"; if ($assignContent) $newContent .= '{capture assign='.$assignContent.'}'."\n"; $newContent .= '{if $'.$variable.'}'.$beforeContent.'{@$'.$variable.'}'."\n".$afterContent; if (!empty($elseContent)) { $newContent .= '{else}'.$elseContent."\n"; } $newContent .= '{/if}'."\n"; if ($assignContent) $newContent .= "{/capture}\n{@$".$assignContent."}\n"; return $newContent; }
/** * @see \wcf\page\IPage::readParameters() */ public function readParameters() { parent::readParameters(); I18nHandler::getInstance()->register('styleDescription'); $this->setVariables(); if (empty($_POST)) { $this->readStyleVariables(); } $templateGroupList = new TemplateGroupList(); $templateGroupList->sqlOrderBy = "templateGroupName"; $templateGroupList->readObjects(); $this->availableTemplateGroups = $templateGroupList->getObjects(); if (isset($_REQUEST['tmpHash'])) { $this->tmpHash = StringUtil::trim($_REQUEST['tmpHash']); } if (empty($this->tmpHash)) { $this->tmpHash = StringUtil::getRandomID(); } }
/** * init one forum by condition * * @param Mixed $var * @param Array $mbqOpt * $mbqOpt['case'] = 'byForumId' means init forum by forum id * $mbqOpt['case'] = 'oDetailedBoardNode' means init forum by oDetailedBoardNode * @return Mixed */ public function initOMbqEtForum($var = null, $mbqOpt = array()) { if ($mbqOpt['case'] == 'byForumId') { if (isset(MbqMain::$oMbqAppEnv->exttAllForums[$var])) { return MbqMain::$oMbqAppEnv->exttAllForums[$var]; } return false; } elseif ($mbqOpt['case'] == 'oDetailedBoardNode') { $oBoard = $var->getBoard(); $oMbqEtForum = MbqMain::$oClk->newObj('MbqEtForum'); $oMbqEtForum->forumId->setOriValue($oBoard->boardID); $oMbqEtForum->forumName->setOriValue($oBoard->getTitle()); $oMbqEtForum->description->setOriValue($oBoard->description); $oMbqEtForum->totalTopicNum->setOriValue($var->getThreads()); $oMbqEtForum->totalPostNum->setOriValue($var->getPosts()); $oMbqEtForum->parentId->setOriValue($oBoard->parentID); if ($var->getUnreadThreads()) { $oMbqEtForum->newPost->setOriValue(MbqBaseFdt::getFdt('MbqFdtForum.MbqEtForum.newPost.range.yes')); } if ($oBoard->isExternalLink()) { $oMbqEtForum->url->setOriValue($oBoard->getLink()); } if ($oBoard->isCategory()) { $oMbqEtForum->subOnly->setOriValue(MbqBaseFdt::getFdt('MbqFdtForum.MbqEtForum.subOnly.range.yes')); } elseif ($oBoard->isBoard()) { $oMbqEtForum->subOnly->setOriValue(MbqBaseFdt::getFdt('MbqFdtForum.MbqEtForum.subOnly.range.no')); } $oMbqAclEtForumTopic = MbqMain::$oClk->newObj('MbqAclEtForumTopic'); $oMbqEtForum->mbqBind['oDetailedBoardNode'] = $var; if ($oMbqAclEtForumTopic->canAclNewTopic($oMbqEtForum)) { $oMbqEtForum->canPost->setOriValue(MbqBaseFdt::getFdt('MbqFdtForum.MbqEtForum.canPost.range.yes')); } else { $oMbqEtForum->canPost->setOriValue(MbqBaseFdt::getFdt('MbqFdtForum.MbqEtForum.canPost.range.no')); } $attachmentObjectType = 'com.woltlab.wbb.post'; $attachmentObjectID = 0; $attachmentParentObjectID = $oBoard->boardID; $oAttachmentHandler = new AttachmentHandler($attachmentObjectType, $attachmentObjectID, \wcf\util\StringUtil::getRandomID(), $attachmentParentObjectID); if ($oAttachmentHandler->canUpload()) { $oMbqEtForum->canUpload->setOriValue(MbqBaseFdt::getFdt('MbqFdtForum.MbqEtForum.canUpload.range.yes')); } else { $oMbqEtForum->canUpload->setOriValue(MbqBaseFdt::getFdt('MbqFdtForum.MbqEtForum.canUpload.range.no')); } return $oMbqEtForum; } MbqError::alert('', __METHOD__ . ',line:' . __LINE__ . '.' . MBQ_ERR_INFO_UNKNOWN_CASE); }
/** * @see wcf\form\IForm::save() */ public function save() { // generate salt $salt = StringUtil::getRandomID(); // write master password file $file = new File(WCF_DIR . 'acp/masterPassword.inc.php'); $file->write("<?php\n/** MASTER PASSWORD STORAGE\nDO NOT EDIT THIS FILE */\ndefine('MASTER_PASSWORD', '" . StringUtil::getSaltedHash($this->masterPassword, $salt) . "');\ndefine('MASTER_PASSWORD_SALT', '" . $salt . "');\n?>"); $file->close(); @chmod(WCF_DIR . 'acp/masterPassword.inc.php', 0777); parent::save(); }
/** * Creates a boundary for mutlipart/mixed Mail */ protected function setBoundary() { $this->boundary = "==Multipart_Boundary_x" . StringUtil::getRandomID() . "x"; }
/** * Returns a short SHA1-hash. * * @return string */ protected function getToken() { return mb_substr(StringUtil::getRandomID(), 0, 8); }
/** * @see \wcf\form\IForm::save() */ public function save() { parent::save(); $this->objectAction = new UserOptionAction(array(), 'create', array('data' => array_merge($this->additionalFields, array('optionName' => StringUtil::getRandomID(), 'categoryName' => $this->categoryName, 'optionType' => $this->optionType, 'defaultValue' => $this->defaultValue, 'showOrder' => $this->showOrder, 'outputClass' => $this->outputClass, 'validationPattern' => $this->validationPattern, 'selectOptions' => $this->selectOptions, 'required' => $this->required, 'askDuringRegistration' => $this->askDuringRegistration, 'searchable' => $this->searchable, 'editable' => $this->editable, 'visible' => $this->visible, 'packageID' => 1, 'additionalData' => $this->optionType == 'select' ? serialize(array('allowEmptyValue' => true)) : '')))); $this->objectAction->executeAction(); $returnValues = $this->objectAction->getReturnValues(); $userOption = $returnValues['returnValues']; // save language vars I18nHandler::getInstance()->save('optionName', 'wcf.user.option.option' . $userOption->optionID, 'wcf.user.option'); I18nHandler::getInstance()->save('optionDescription', 'wcf.user.option.option' . $userOption->optionID . '.description', 'wcf.user.option'); $editor = new UserOptionEditor($userOption); $editor->update(array('optionName' => 'option' . $userOption->optionID)); $this->saved(); // reset values $this->optionName = $this->optionDescription = $this->categoryName = $this->optionType = $this->defaultValue = $this->validationPattern = $this->selectOptions = $this->outputClass = ''; $this->optionType = 'text'; $this->required = $this->searchable = $this->showOrder = $this->askDuringRegistration = 0; $this->editable = 3; $this->visible = 15; I18nHandler::getInstance()->reset(); // show success WCF::getTPL()->assign('success', true); }
/** * Constructs a new instance of HTTPRequest. * * @param string $url URL to connect to * @param array<string> $options * @param mixed $postParameters Parameters to send via POST * @param array $files Files to attach to the request */ public function __construct($url, array $options = array(), $postParameters = array(), array $files = array()) { $this->setURL($url); $this->postParameters = $postParameters; $this->files = $files; $this->setOptions($options); // set default headers $this->addHeader('user-agent', "HTTP.PHP (HTTPRequest.class.php; WoltLab Community Framework/" . WCF_VERSION . "; " . WCF::getLanguage()->languageCode . ")"); $this->addHeader('accept', '*/*'); $this->addHeader('accept-language', WCF::getLanguage()->getFixedLanguageCode()); if (isset($this->options['maxLength'])) { $this->addHeader('Range', 'bytes=0-' . ($this->options['maxLength'] - 1)); } if ($this->options['method'] !== 'GET') { if (empty($this->files)) { if (is_array($postParameters)) { $this->body = http_build_query($this->postParameters, '', '&'); } else { if (is_string($postParameters) && !empty($postParameters)) { $this->body = $postParameters; } } $this->addHeader('content-type', 'application/x-www-form-urlencoded'); } else { $boundary = StringUtil::getRandomID(); $this->addHeader('content-type', 'multipart/form-data; boundary=' . $boundary); // source of the iterators: http://stackoverflow.com/a/7623716/782822 if (!empty($this->postParameters)) { $iterator = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($this->postParameters), \RecursiveIteratorIterator::SELF_FIRST); foreach ($iterator as $k => $v) { if (!$iterator->hasChildren()) { $key = ''; for ($i = 0, $max = $iterator->getDepth(); $i <= $max; $i++) { if ($i === 0) { $key .= $iterator->getSubIterator($i)->key(); } else { $key .= '[' . $iterator->getSubIterator($i)->key() . ']'; } } $this->body .= "--" . $boundary . "\r\n"; $this->body .= 'Content-Disposition: form-data; name="' . $key . '"' . "\r\n\r\n"; $this->body .= $v . "\r\n"; } } } $iterator = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($this->files), \RecursiveIteratorIterator::SELF_FIRST); foreach ($iterator as $k => $v) { if (!$iterator->hasChildren()) { $key = ''; for ($i = 0, $max = $iterator->getDepth(); $i <= $max; $i++) { if ($i === 0) { $key .= $iterator->getSubIterator($i)->key(); } else { $key .= '[' . $iterator->getSubIterator($i)->key() . ']'; } } $this->body .= "--" . $boundary . "\r\n"; $this->body .= 'Content-Disposition: form-data; name="' . $k . '"; filename="' . basename($v) . '"' . "\r\n"; $this->body .= 'Content-Type: ' . (FileUtil::getMimeType($v) ?: 'application/octet-stream.') . "\r\n\r\n"; $this->body .= file_get_contents($v) . "\r\n"; } } $this->body .= "--" . $boundary . "--"; } $this->addHeader('content-length', strlen($this->body)); } if (isset($this->options['auth'])) { $this->addHeader('authorization', "Basic " . base64_encode($options['auth']['username'] . ":" . $options['auth']['password'])); } $this->addHeader('connection', 'Close'); }
/** * Imports a style. * * @param string $filename * @param integer $packageID * @param StyleEditor $style * @return StyleEditor */ public static function import($filename, $packageID = 1, StyleEditor $style = null) { // open file $tar = new Tar($filename); // get style data $data = self::readStyleData($tar); $styleData = array('styleName' => $data['name'], 'variables' => $data['variables'], 'styleVersion' => $data['version'], 'styleDate' => $data['date'], 'copyright' => $data['copyright'], 'license' => $data['license'], 'authorName' => $data['authorName'], 'authorURL' => $data['authorURL']); // create template group if (!empty($data['templates'])) { $templateGroupName = $originalTemplateGroupName = $data['name']; $templateGroupFolderName = preg_replace('/[^a-z0-9_-]/i', '', $templateGroupName); if (empty($templateGroupFolderName)) { $templateGroupFolderName = 'generic' . mb_substr(StringUtil::getRandomID(), 0, 8); } $originalTemplateGroupFolderName = $templateGroupFolderName; // get unique template group name $i = 1; while (true) { $sql = "SELECT\tCOUNT(*) AS count\n\t\t\t\t\tFROM\twcf" . WCF_N . "_template_group\n\t\t\t\t\tWHERE\ttemplateGroupName = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($templateGroupName)); $row = $statement->fetchArray(); if (!$row['count']) { break; } $templateGroupName = $originalTemplateGroupName . '_' . $i; $i++; } // get unique folder name $i = 1; while (true) { $sql = "SELECT\tCOUNT(*) AS count\n\t\t\t\t\tFROM\twcf" . WCF_N . "_template_group\n\t\t\t\t\tWHERE\ttemplateGroupFolderName = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array(FileUtil::addTrailingSlash($templateGroupFolderName))); $row = $statement->fetchArray(); if (!$row['count']) { break; } $templateGroupFolderName = $originalTemplateGroupFolderName . '_' . $i; $i++; } $templateGroupAction = new TemplateGroupAction(array(), 'create', array('data' => array('templateGroupName' => $templateGroupName, 'templateGroupFolderName' => FileUtil::addTrailingSlash($templateGroupFolderName)))); $returnValues = $templateGroupAction->executeAction(); $styleData['templateGroupID'] = $returnValues['returnValues']->templateGroupID; } // import images if (!empty($data['images']) && $data['imagesPath'] != 'images/') { // create images folder if necessary $imagesLocation = self::getFileLocation($data['imagesPath']); $styleData['imagePath'] = FileUtil::getRelativePath(WCF_DIR, $imagesLocation); $index = $tar->getIndexByFilename($data['images']); if ($index !== false) { // extract images tar $destination = FileUtil::getTemporaryFilename('images_'); $tar->extract($index, $destination); // open images tar $imagesTar = new Tar($destination); $contentList = $imagesTar->getContentList(); foreach ($contentList as $key => $val) { if ($val['type'] == 'file') { $imagesTar->extract($key, $imagesLocation . basename($val['filename'])); FileUtil::makeWritable($imagesLocation . basename($val['filename'])); } } // delete tmp file $imagesTar->close(); @unlink($destination); } } // import templates if (!empty($data['templates'])) { $index = $tar->getIndexByFilename($data['templates']); if ($index !== false) { // extract templates tar $destination = FileUtil::getTemporaryFilename('templates_'); $tar->extract($index, $destination); // open templates tar and group templates by package $templatesTar = new Tar($destination); $contentList = $templatesTar->getContentList(); $packageToTemplates = array(); foreach ($contentList as $val) { if ($val['type'] == 'file') { $folders = explode('/', $val['filename']); $packageName = array_shift($folders); if (!isset($packageToTemplates[$packageName])) { $packageToTemplates[$packageName] = array(); } $packageToTemplates[$packageName][] = array('index' => $val['index'], 'filename' => implode('/', $folders)); } } // copy templates foreach ($packageToTemplates as $package => $templates) { // try to find package $sql = "SELECT\t*\n\t\t\t\t\t\tFROM\twcf" . WCF_N . "_package\n\t\t\t\t\t\tWHERE\tpackage = ?\n\t\t\t\t\t\t\tAND isApplication = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($package, 1)); while ($row = $statement->fetchArray()) { // get template path $templatesDir = FileUtil::addTrailingSlash(FileUtil::getRealPath(WCF_DIR . $row['packageDir']) . 'templates/' . $templateGroupFolderName); // create template path if (!file_exists($templatesDir)) { @mkdir($templatesDir, 0777); FileUtil::makeWritable($templatesDir); } // copy templates foreach ($templates as $template) { $templatesTar->extract($template['index'], $templatesDir . $template['filename']); TemplateEditor::create(array('application' => Package::getAbbreviation($package), 'packageID' => $row['packageID'], 'templateName' => str_replace('.tpl', '', $template['filename']), 'templateGroupID' => $styleData['templateGroupID'])); } } } // delete tmp file $templatesTar->close(); @unlink($destination); } } // save style if ($style !== null) { $style->update($styleData); } else { $styleData['packageID'] = $packageID; $style = new StyleEditor(self::create($styleData)); } // import preview image if (!empty($data['image'])) { $fileExtension = mb_substr($data['image'], mb_strrpos($data['image'], '.')); $index = $tar->getIndexByFilename($data['image']); if ($index !== false) { $filename = WCF_DIR . 'images/stylePreview-' . $style->styleID . $fileExtension; $tar->extract($index, $filename); FileUtil::makeWritable($filename); if (file_exists($filename)) { $style->update(array('image' => 'stylePreview-' . $style->styleID . $fileExtension)); } } } $tar->close(); // handle descriptions if (!empty($data['description'])) { self::saveLocalizedDescriptions($style, $data['description']); LanguageFactory::getInstance()->deleteLanguageCache(); } if ($data['default']) { $style->setAsDefault(); } return $style; }
/** * add forum topic * * @param $oMbqEtForumTopic */ public function addMbqEtForumTopic($oMbqEtForumTopic) { $oMbqRdEtForum = MbqMain::$oClk->newObj('MbqRdEtForum'); $objsMbqEtForum = $oMbqRdEtForum->getObjsMbqEtForum(array($oMbqEtForumTopic->forumId->oriValue), array('case' => 'byForumIds')); if ($oMbqEtForum = $objsMbqEtForum[0]) { $oBoard = $oMbqEtForum->mbqBind['oDetailedBoardNode']->getBoard(); } else { MbqError::alert('', "Need valid forum.", '', MBQ_ERR_APP); } //ref wcf\form\MessageForm,wbb\form\ThreadAddForm $oMbqEtForumTopic->topicTitle->setOriValue(StringUtil::trim($oMbqEtForumTopic->topicTitle->oriValue)); $oMbqEtForumTopic->topicContent->setOriValue(MessageUtil::stripCrap(StringUtil::trim($oMbqEtForumTopic->topicContent->oriValue))); $attachmentObjectType = 'com.woltlab.wbb.post'; $attachmentObjectID = 0; $tmpHash = $oMbqEtForumTopic->groupId->oriValue ? $oMbqEtForumTopic->groupId->oriValue : StringUtil::getRandomID(); $attachmentParentObjectID = $oBoard->boardID; //settings $preParse = $enableSmilies = $enableBBCodes = $showSignature = $subscribeThread = $enableHtml = 0; $preParse = 1; if (WCF::getSession()->getPermission('user.message.canUseSmilies')) { $enableSmilies = 1; } //if (WCF::getSession()->getPermission('user.message.canUseHtml')) $enableHtml = 1; if (WCF::getSession()->getPermission('user.message.canUseBBCodes')) { $enableBBCodes = 1; } $showSignature = 1; $subscribeThread = 1; $type = Thread::TYPE_DEFAULT; // get max text length $maxTextLength = WCF::getSession()->getPermission('user.board.maxPostLength'); $minCharLength = WBB_THREAD_MIN_CHAR_LENGTH; $minWordCount = WBB_THREAD_MIN_WORD_COUNT; //begin validate $allowedBBCodesPermission = 'user.message.allowedBBCodes'; //validateSubject if (empty($oMbqEtForumTopic->topicTitle->oriValue)) { MbqError::alert('', "Need topic title.", '', MBQ_ERR_APP); } if (StringUtil::length($oMbqEtForumTopic->topicTitle->oriValue) > 255) { MbqError::alert('', "Topic title is too long.", '', MBQ_ERR_APP); } // search for censored words if (ENABLE_CENSORSHIP) { $result = Censorship::getInstance()->test($oMbqEtForumTopic->topicTitle->oriValue); if ($result) { MbqError::alert('', "Found censored words in topic title.", '', MBQ_ERR_APP); } } //validateText if (empty($oMbqEtForumTopic->topicContent->oriValue)) { MbqError::alert('', "Need topic content.", '', MBQ_ERR_APP); } // check text length if ($maxTextLength != 0 && StringUtil::length($oMbqEtForumTopic->topicContent->oriValue) > $maxTextLength) { MbqError::alert('', "Topic content is too long.", '', MBQ_ERR_APP); } if ($enableBBCodes && $allowedBBCodesPermission) { $disallowedBBCodes = BBCodeParser::getInstance()->validateBBCodes($oMbqEtForumTopic->topicContent->oriValue, ArrayUtil::trim(explode(',', WCF::getSession()->getPermission($allowedBBCodesPermission)))); if (!empty($disallowedBBCodes)) { MbqError::alert('', "Topic content included disallowed bbcodes.", '', MBQ_ERR_APP); } } // search for censored words if (ENABLE_CENSORSHIP) { $result = Censorship::getInstance()->test($oMbqEtForumTopic->topicContent->oriValue); if ($result) { MbqError::alert('', "Found censored words in topic content.", '', MBQ_ERR_APP); } } if ($minCharLength && StringUtil::length($oMbqEtForumTopic->topicContent->oriValue) < $minCharLength) { MbqError::alert('', "Topic content is too short.", '', MBQ_ERR_APP); } if ($minWordCount && count(explode(' ', $oMbqEtForumTopic->topicContent->oriValue)) < $minWordCount) { MbqError::alert('', "Need more words in topic content", '', MBQ_ERR_APP); } //language //$languageID = LanguageFactory::getInstance()->getUserLanguage()->languageID; $languageID = NULL; //attachment if (MODULE_ATTACHMENT && $attachmentObjectType) { $attachmentHandler = new AttachmentHandler($attachmentObjectType, $attachmentObjectID, $tmpHash, $attachmentParentObjectID); } //save if ($preParse) { // BBCodes are enabled if ($enableBBCodes) { if ($allowedBBCodesPermission) { $oMbqEtForumTopic->topicContent->setOriValue(PreParser::getInstance()->parse($oMbqEtForumTopic->topicContent->oriValue, ArrayUtil::trim(explode(',', WCF::getSession()->getPermission($allowedBBCodesPermission))))); } else { $oMbqEtForumTopic->topicContent->setOriValue(PreParser::getInstance()->parse($oMbqEtForumTopic->topicContent->oriValue)); } } else { $oMbqEtForumTopic->topicContent->setOriValue(PreParser::getInstance()->parse($oMbqEtForumTopic->topicContent->oriValue, array())); } } // save thread $data = array('boardID' => $oMbqEtForumTopic->forumId->oriValue, 'languageID' => $languageID, 'topic' => $oMbqEtForumTopic->topicTitle->oriValue, 'time' => TIME_NOW, 'userID' => MbqMain::$oCurMbqEtUser->userId->oriValue, 'username' => MbqMain::$oCurMbqEtUser->loginName->oriValue, 'hasLabels' => 0); $data['isClosed'] = 0; if (!$oBoard->getPermission('canStartThreadWithoutModeration')) { $data['isDisabled'] = 1; } $threadData = array('data' => $data, 'board' => $oBoard, 'attachmentHandler' => $attachmentHandler, 'postData' => array('message' => $oMbqEtForumTopic->topicContent->oriValue, 'enableBBCodes' => $enableBBCodes, 'enableHtml' => $enableHtml, 'enableSmilies' => $enableSmilies, 'showSignature' => $showSignature), 'tags' => array(), 'subscribeThread' => $subscribeThread); $oThreadAction = new ThreadAction(array(), 'create', $threadData); $resultValues = $oThreadAction->executeAction(); if ($resultValues['returnValues']->threadID) { $oMbqEtForumTopic->topicId->setOriValue($resultValues['returnValues']->threadID); $oMbqRdEtForumTopic = MbqMain::$oClk->newObj('MbqRdEtForumTopic'); $oMbqEtForumTopic = $oMbqRdEtForumTopic->initOMbqEtForumTopic($oMbqEtForumTopic->topicId->oriValue, array('case' => 'byTopicId')); //for get state /* mark forum topic read */ $this->markForumTopicRead($oMbqEtForumTopic); } else { MbqError::alert('', "Can not create topic.", '', MBQ_ERR_APP); } }
/** * Changes the user stored in the session, this method is different from changeUser() because it * attempts to re-use sessions unless there are other virtual sessions for the same user (userID != 0). * In reverse, logging out attempts to re-use the current session or spawns a new session depending * on other virtual sessions. * * @param \wcf\data\user\User $user */ protected function changeUserVirtual(User $user) { $sessionTable = call_user_func(array($this->sessionClassName, 'getDatabaseTableName')); switch ($user->userID) { // // user -> guest (logout) // case 0: // delete virtual session if ($this->virtualSession) { $virtualSessionEditor = new SessionVirtualEditor($this->virtualSession); $virtualSessionEditor->delete(); } // there are still other virtual sessions, create a new session if (SessionVirtual::countVirtualSessions($this->session->sessionID)) { // save session $sessionData = array('sessionID' => StringUtil::getRandomID(), 'userID' => $user->userID, 'ipAddress' => UserUtil::getIpAddress(), 'userAgent' => UserUtil::getUserAgent(), 'lastActivityTime' => TIME_NOW, 'requestURI' => UserUtil::getRequestURI(), 'requestMethod' => !empty($_SERVER['REQUEST_METHOD']) ? substr($_SERVER['REQUEST_METHOD'], 0, 7) : ''); $this->session = call_user_func(array($this->sessionEditorClassName, 'create'), $sessionData); HeaderUtil::setCookie('cookieHash', $this->session->sessionID); } else { // this was the last virtual session, re-use current session // update session $sessionEditor = new $this->sessionEditorClassName($this->session); $sessionEditor->update(array('userID' => $user->userID)); } break; // // guest -> user (login) // // // guest -> user (login) // default: // find existing session for this user $session = call_user_func(array($this->sessionClassName, 'getSessionByUserID'), $user->userID); // no session exists, re-use current session if ($session === null) { // update session $sessionEditor = new $this->sessionEditorClassName($this->session); try { $this->register('__changeSessionID', true); $sessionEditor->update(array('userID' => $user->userID)); } catch (DatabaseException $e) { // MySQL error 23000 = unique key // do not check against the message itself, some weird systems localize them if ($e->getCode() == 23000) { // delete guest session $sessionEditor = new $this->sessionEditorClassName($this->session); $sessionEditor->delete(); // inherit existing session $this->session = $session; } else { // not our business throw $e; } } } else { // delete guest session $sessionEditor = new $this->sessionEditorClassName($this->session); $sessionEditor->delete(); // inherit existing session $this->session = $session; // inherit security token $variables = @unserialize($this->session->sessionVariables); if (is_array($variables) && !empty($variables['__SECURITY_TOKEN'])) { $this->register('__SECURITY_TOKEN', $variables['__SECURITY_TOKEN']); } HeaderUtil::setCookie('cookieHash', $this->session->sessionID); } break; } $this->user = $user; $this->loadVirtualSession(true); }
/** * @see \wcf\action\IAction::execute() */ public function execute() { parent::execute(); $callbackURL = LinkHandler::getInstance()->getLink('FacebookAuth'); // Work around Facebook performing an illegal substitution of the Slash // by '%2F' when entering redirect URI (RFC 3986 sect. 2.2, sect. 3.4) $callbackURL = preg_replace_callback('/(?<=\\?).*/', function ($matches) { return rawurlencode($matches[0]); }, $callbackURL); // user accepted the connection if (isset($_GET['code'])) { try { // fetch access_token $request = new HTTPRequest('https://graph.facebook.com/oauth/access_token?client_id=' . StringUtil::trim(FACEBOOK_PUBLIC_KEY) . '&redirect_uri=' . rawurlencode($callbackURL) . '&client_secret=' . StringUtil::trim(FACEBOOK_PRIVATE_KEY) . '&code=' . rawurlencode($_GET['code'])); $request->execute(); $reply = $request->getReply(); $content = $reply['body']; } catch (SystemException $e) { // force logging $e->getExceptionID(); throw new IllegalLinkException(); } // validate state, validation of state is executed after fetching the access_token to invalidate 'code' if (!isset($_GET['state']) || $_GET['state'] != WCF::getSession()->getVar('__facebookInit')) { throw new IllegalLinkException(); } WCF::getSession()->unregister('__facebookInit'); parse_str($content, $data); try { // fetch userdata $request = new HTTPRequest('https://graph.facebook.com/me?access_token=' . rawurlencode($data['access_token']) . '&fields=birthday,bio,email,gender,id,location,name,picture.type(large),website'); $request->execute(); $reply = $request->getReply(); $content = $reply['body']; } catch (SystemException $e) { // force logging $e->getExceptionID(); throw new IllegalLinkException(); } $userData = JSON::decode($content); // check whether a user is connected to this facebook account $user = $this->getUser($userData['id']); if ($user->userID) { // a user is already connected, but we are logged in, break if (WCF::getUser()->userID) { throw new NamedUserException(WCF::getLanguage()->get('wcf.user.3rdparty.facebook.connect.error.inuse')); } else { if (UserAuthenticationFactory::getInstance()->getUserAuthentication()->supportsPersistentLogins()) { $password = StringUtil::getRandomID(); $userEditor = new UserEditor($user); $userEditor->update(array('password' => $password)); // reload user to retrieve salt $user = new User($user->userID); UserAuthenticationFactory::getInstance()->getUserAuthentication()->storeAccessData($user, $user->username, $password); } WCF::getSession()->changeUser($user); WCF::getSession()->update(); HeaderUtil::redirect(LinkHandler::getInstance()->getLink()); } } else { WCF::getSession()->register('__3rdPartyProvider', 'facebook'); // save data for connection if (WCF::getUser()->userID) { WCF::getSession()->register('__facebookUsername', $userData['name']); WCF::getSession()->register('__facebookData', $userData); HeaderUtil::redirect(LinkHandler::getInstance()->getLink('AccountManagement') . '#3rdParty'); } else { WCF::getSession()->register('__username', $userData['name']); if (isset($userData['email'])) { WCF::getSession()->register('__email', $userData['email']); } WCF::getSession()->register('__facebookData', $userData); // we assume that bots won't register on facebook first // thus no need for a captcha if (REGISTER_USE_CAPTCHA) { WCF::getSession()->register('noRegistrationCaptcha', true); } WCF::getSession()->update(); HeaderUtil::redirect(LinkHandler::getInstance()->getLink('Register')); } } $this->executed(); exit; } // user declined or any other error that may occur if (isset($_GET['error'])) { throw new NamedUserException(WCF::getLanguage()->get('wcf.user.3rdparty.facebook.login.error.' . $_GET['error'])); } // start auth by redirecting to facebook $token = StringUtil::getRandomID(); WCF::getSession()->register('__facebookInit', $token); HeaderUtil::redirect("https://www.facebook.com/dialog/oauth?client_id=" . StringUtil::trim(FACEBOOK_PUBLIC_KEY) . "&redirect_uri=" . rawurlencode($callbackURL) . "&state=" . $token . "&scope=email,user_about_me,user_birthday,user_location,user_website"); $this->executed(); exit; }
/** * @see \wcf\action\IAction::execute() */ public function execute() { parent::execute(); // user accepted if (isset($_GET['oauth_token']) && isset($_GET['oauth_verifier'])) { // fetch data created in the first step $initData = WCF::getSession()->getVar('__twitterInit'); WCF::getSession()->unregister('__twitterInit'); if (!$initData) { throw new IllegalLinkException(); } // validate oauth_token if ($_GET['oauth_token'] !== $initData['oauth_token']) { throw new IllegalLinkException(); } try { // fetch access_token $oauthHeader = array('oauth_consumer_key' => StringUtil::trim(TWITTER_PUBLIC_KEY), 'oauth_nonce' => StringUtil::getRandomID(), 'oauth_signature_method' => 'HMAC-SHA1', 'oauth_timestamp' => TIME_NOW, 'oauth_version' => '1.0', 'oauth_token' => $initData['oauth_token']); $postData = array('oauth_verifier' => $_GET['oauth_verifier']); $signature = $this->createSignature('https://api.twitter.com/oauth/access_token', array_merge($oauthHeader, $postData)); $oauthHeader['oauth_signature'] = $signature; $request = new HTTPRequest('https://api.twitter.com/oauth/access_token', array(), $postData); $request->addHeader('Authorization', 'OAuth ' . $this->buildOAuthHeader($oauthHeader)); $request->execute(); $reply = $request->getReply(); $content = $reply['body']; } catch (SystemException $e) { // force logging $e->getExceptionID(); throw new IllegalLinkException(); } parse_str($content, $data); // check whether a user is connected to this twitter account $user = $this->getUser($data['user_id']); if ($user->userID) { // a user is already connected, but we are logged in, break if (WCF::getUser()->userID) { throw new NamedUserException(WCF::getLanguage()->get('wcf.user.3rdparty.twitter.connect.error.inuse')); } else { if (UserAuthenticationFactory::getInstance()->getUserAuthentication()->supportsPersistentLogins()) { $password = StringUtil::getRandomID(); $userEditor = new UserEditor($user); $userEditor->update(array('password' => $password)); // reload user to retrieve salt $user = new User($user->userID); UserAuthenticationFactory::getInstance()->getUserAuthentication()->storeAccessData($user, $user->username, $password); } WCF::getSession()->changeUser($user); WCF::getSession()->update(); HeaderUtil::redirect(LinkHandler::getInstance()->getLink()); } } else { WCF::getSession()->register('__3rdPartyProvider', 'twitter'); // save data for connection if (WCF::getUser()->userID) { WCF::getSession()->register('__twitterUsername', $data['screen_name']); WCF::getSession()->register('__twitterData', $data); HeaderUtil::redirect(LinkHandler::getInstance()->getLink('AccountManagement') . '#3rdParty'); } else { // fetch user data $twitterData = null; try { $request = new HTTPRequest('https://api.twitter.com/1.1/users/show.json?screen_name=' . $data['screen_name']); $request->execute(); $reply = $request->getReply(); $twitterData = json_decode($reply['body'], true); } catch (SystemException $e) { /* ignore errors */ } WCF::getSession()->register('__username', $data['screen_name']); if ($twitterData !== null) { $data = $twitterData; } WCF::getSession()->register('__twitterData', $data); // we assume that bots won't register on twitter first // thus no need for a captcha if (REGISTER_USE_CAPTCHA) { WCF::getSession()->register('noRegistrationCaptcha', true); } WCF::getSession()->update(); HeaderUtil::redirect(LinkHandler::getInstance()->getLink('Register')); } } $this->executed(); exit; } // user declined if (isset($_GET['denied'])) { throw new NamedUserException(WCF::getLanguage()->get('wcf.user.3rdparty.twitter.login.error.denied')); } // start auth by fetching request_token try { $callbackURL = LinkHandler::getInstance()->getLink('TwitterAuth', array('appendSession' => false)); $oauthHeader = array('oauth_callback' => $callbackURL, 'oauth_consumer_key' => StringUtil::trim(TWITTER_PUBLIC_KEY), 'oauth_nonce' => StringUtil::getRandomID(), 'oauth_signature_method' => 'HMAC-SHA1', 'oauth_timestamp' => TIME_NOW, 'oauth_version' => '1.0'); $signature = $this->createSignature('https://api.twitter.com/oauth/request_token', $oauthHeader); $oauthHeader['oauth_signature'] = $signature; // call api $request = new HTTPRequest('https://api.twitter.com/oauth/request_token', array('method' => 'POST')); $request->addHeader('Authorization', 'OAuth ' . $this->buildOAuthHeader($oauthHeader)); $request->execute(); $reply = $request->getReply(); $content = $reply['body']; } catch (SystemException $e) { // force logging $e->getExceptionID(); throw new IllegalLinkException(); } parse_str($content, $data); if ($data['oauth_callback_confirmed'] != 'true') { throw new IllegalLinkException(); } WCF::getSession()->register('__twitterInit', $data); // redirect to twitter HeaderUtil::redirect('https://api.twitter.com/oauth/authenticate?oauth_token=' . rawurlencode($data['oauth_token'])); $this->executed(); exit; }
/** * @see \wcf\data\IMessageInlineEditorAction::beginEdit() */ public function beginEdit() { BBCodeHandler::getInstance()->setAllowedBBCodes(explode(',', WCF::getSession()->getPermission('user.message.allowedBBCodes'))); WCF::getTPL()->assign(array('defaultSmilies' => SmileyCache::getInstance()->getCategorySmilies(), 'message' => $this->message, 'permissionCanUseSmilies' => 'user.message.canUseSmilies', 'wysiwygSelector' => 'messageEditor' . $this->message->messageID)); if (MODULE_ATTACHMENT) { $tmpHash = StringUtil::getRandomID(); $attachmentHandler = new AttachmentHandler('com.woltlab.wcf.conversation.message', $this->message->messageID, $tmpHash); $attachmentList = $attachmentHandler->getAttachmentList(); WCF::getTPL()->assign(array('attachmentHandler' => $attachmentHandler, 'attachmentList' => $attachmentList->getObjects(), 'attachmentObjectID' => $this->message->messageID, 'attachmentObjectType' => 'com.woltlab.wcf.conversation.message', 'attachmentParentObjectID' => 0, 'tmpHash' => $tmpHash)); } return array('actionName' => 'beginEdit', 'template' => WCF::getTPL()->fetch('conversationMessageInlineEditor')); }
/** * @see \wcf\form\IForm::save() */ public function save() { AbstractForm::save(); // get options $saveOptions = $this->optionHandler->save(); $registerVia3rdParty = false; $avatarURL = ''; if ($this->isExternalAuthentication) { switch (WCF::getSession()->getVar('__3rdPartyProvider')) { case 'github': // GitHub if (WCF::getSession()->getVar('__githubData')) { $githubData = WCF::getSession()->getVar('__githubData'); $this->additionalFields['authData'] = 'github:' . WCF::getSession()->getVar('__githubToken'); WCF::getSession()->unregister('__githubData'); WCF::getSession()->unregister('__githubToken'); if (WCF::getSession()->getVar('__email') && WCF::getSession()->getVar('__email') == $this->email) { $registerVia3rdParty = true; } if (isset($githubData['bio']) && User::getUserOptionID('aboutMe') !== null) { $saveOptions[User::getUserOptionID('aboutMe')] = $githubData['bio']; } if (isset($githubData['location']) && User::getUserOptionID('location') !== null) { $saveOptions[User::getUserOptionID('location')] = $githubData['location']; } } break; case 'twitter': // Twitter if (WCF::getSession()->getVar('__twitterData')) { $twitterData = WCF::getSession()->getVar('__twitterData'); $this->additionalFields['authData'] = 'twitter:' . $twitterData['user_id']; WCF::getSession()->unregister('__twitterData'); if (isset($twitterData['description']) && User::getUserOptionID('aboutMe') !== null) { $saveOptions[User::getUserOptionID('aboutMe')] = $twitterData['description']; } if (isset($twitterData['location']) && User::getUserOptionID('location') !== null) { $saveOptions[User::getUserOptionID('location')] = $twitterData['location']; } } break; case 'facebook': // Facebook if (WCF::getSession()->getVar('__facebookData')) { $facebookData = WCF::getSession()->getVar('__facebookData'); $this->additionalFields['authData'] = 'facebook:' . $facebookData['id']; WCF::getSession()->unregister('__facebookData'); if (isset($facebookData['email']) && $facebookData['email'] == $this->email) { $registerVia3rdParty = true; } if (isset($facebookData['gender']) && User::getUserOptionID('gender') !== null) { $saveOptions[User::getUserOptionID('gender')] = $facebookData['gender'] == 'male' ? UserProfile::GENDER_MALE : UserProfile::GENDER_FEMALE; } if (isset($facebookData['birthday']) && User::getUserOptionID('birthday') !== null) { list($month, $day, $year) = explode('/', $facebookData['birthday']); $saveOptions[User::getUserOptionID('birthday')] = $year . '-' . $month . '-' . $day; } if (isset($facebookData['bio']) && User::getUserOptionID('bio') !== null) { $saveOptions[User::getUserOptionID('aboutMe')] = $facebookData['bio']; } if (isset($facebookData['location']) && User::getUserOptionID('location') !== null) { $saveOptions[User::getUserOptionID('location')] = $facebookData['location']['name']; } if (isset($facebookData['website']) && User::getUserOptionID('website') !== null) { $urls = preg_split('/[\\s,;]/', $facebookData['website'], -1, PREG_SPLIT_NO_EMPTY); if (!empty($urls)) { if (!Regex::compile('^https?://')->match($urls[0])) { $urls[0] = 'http://' . $urls[0]; } $saveOptions[User::getUserOptionID('homepage')] = $urls[0]; } } // avatar if (isset($facebookData['picture']) && !$facebookData['picture']['data']['is_silhouette']) { $avatarURL = $facebookData['picture']['data']['url']; } } break; case 'google': // Google Plus if (WCF::getSession()->getVar('__googleData')) { $googleData = WCF::getSession()->getVar('__googleData'); $this->additionalFields['authData'] = 'google:' . $googleData['id']; WCF::getSession()->unregister('__googleData'); if (isset($googleData['emails'][0]['value']) && $googleData['emails'][0]['value'] == $this->email) { $registerVia3rdParty = true; } if (isset($googleData['gender']) && User::getUserOptionID('gender') !== null) { switch ($googleData['gender']) { case 'male': $saveOptions[User::getUserOptionID('gender')] = UserProfile::GENDER_MALE; break; case 'female': $saveOptions[User::getUserOptionID('gender')] = UserProfile::GENDER_FEMALE; break; } } if (isset($googleData['birthday']) && User::getUserOptionID('birthday') !== null) { $saveOptions[User::getUserOptionID('birthday')] = $googleData['birthday']; } if (isset($googleData['placesLived']) && User::getUserOptionID('location') !== null) { // save primary location $saveOptions[User::getUserOptionID('location')] = current(array_map(function ($element) { return $element['value']; }, array_filter($googleData['placesLived'], function ($element) { return isset($element['primary']) && $element['primary']; }))); } // avatar if (isset($googleData['image']['url'])) { $avatarURL = $googleData['image']['url']; } } break; } // create fake password $this->password = StringUtil::getRandomID(); } $this->additionalFields['languageID'] = $this->languageID; if (LOG_IP_ADDRESS) { $this->additionalFields['registrationIpAddress'] = WCF::getSession()->ipAddress; } // generate activation code $addDefaultGroups = true; if (REGISTER_ACTIVATION_METHOD == 1 && !$registerVia3rdParty || REGISTER_ACTIVATION_METHOD == 2) { $activationCode = UserRegistrationUtil::getActivationCode(); $this->additionalFields['activationCode'] = $activationCode; $addDefaultGroups = false; $this->groupIDs = UserGroup::getGroupIDsByType(array(UserGroup::EVERYONE, UserGroup::GUESTS)); } // check gravatar support if (MODULE_GRAVATAR && Gravatar::test($this->email)) { $this->additionalFields['enableGravatar'] = 1; } // create user $data = array('data' => array_merge($this->additionalFields, array('username' => $this->username, 'email' => $this->email, 'password' => $this->password)), 'groups' => $this->groupIDs, 'languageIDs' => $this->visibleLanguages, 'options' => $saveOptions, 'addDefaultGroups' => $addDefaultGroups); $this->objectAction = new UserAction(array(), 'create', $data); $result = $this->objectAction->executeAction(); $user = $result['returnValues']; $userEditor = new UserEditor($user); // update session WCF::getSession()->changeUser($user); // set avatar if provided if (!empty($avatarURL)) { $userAvatarAction = new UserAvatarAction(array(), 'fetchRemoteAvatar', array('url' => $avatarURL, 'userEditor' => $userEditor)); $userAvatarAction->executeAction(); } // activation management if (REGISTER_ACTIVATION_METHOD == 0) { $this->message = 'wcf.user.register.success'; } else { if (REGISTER_ACTIVATION_METHOD == 1) { // registering via 3rdParty leads to instant activation if ($registerVia3rdParty) { $this->message = 'wcf.user.register.success'; } else { $mail = new Mail(array($this->username => $this->email), WCF::getLanguage()->getDynamicVariable('wcf.user.register.needActivation.mail.subject'), WCF::getLanguage()->getDynamicVariable('wcf.user.register.needActivation.mail', array('user' => $user))); $mail->send(); $this->message = 'wcf.user.register.needActivation'; } } else { if (REGISTER_ACTIVATION_METHOD == 2) { $this->message = 'wcf.user.register.awaitActivation'; } } } // notify admin if (REGISTER_ADMIN_NOTIFICATION) { // get default language $language = LanguageFactory::getInstance()->getLanguage(LanguageFactory::getInstance()->getDefaultLanguageID()); // send mail $mail = new Mail(MAIL_ADMIN_ADDRESS, $language->getDynamicVariable('wcf.user.register.notification.mail.subject'), $language->getDynamicVariable('wcf.user.register.notification.mail', array('user' => $user))); $mail->setLanguage($language); $mail->send(); } if ($this->captchaObjectType) { $this->captchaObjectType->getProcessor()->reset(); } if (WCF::getSession()->getVar('noRegistrationCaptcha')) { WCF::getSession()->unregister('noRegistrationCaptcha'); } // login user UserAuthenticationFactory::getInstance()->getUserAuthentication()->storeAccessData($user, $this->username, $this->password); WCF::getSession()->unregister('registrationRandomFieldNames'); WCF::getSession()->unregister('registrationStartTime'); $this->saved(); // forward to index page HeaderUtil::delayedRedirect(LinkHandler::getInstance()->getLink(), WCF::getLanguage()->getDynamicVariable($this->message, array('user' => $user)), 15); exit; }
/** * Exports users. */ public function exportUsers($offset, $limit) { // prepare password update $sql = "UPDATE\twcf" . WCF_N . "_user\n\t\t\tSET\tpassword = ?\n\t\t\tWHERE\tuserID = ?"; $passwordUpdateStatement = WCF::getDB()->prepareStatement($sql); // get users $sql = "SELECT\t\tkunena_users.*, users.*,\n\t\t\t\t\t(\n\t\t\t\t\t\tSELECT\tGROUP_CONCAT(user_usergroup_map.group_id)\n\t\t\t\t\t\tFROM\t" . $this->databasePrefix . "user_usergroup_map user_usergroup_map\n\t\t\t\t\t\tWHERE\tuser_usergroup_map.user_id = kunena_users.userid\n\t\t\t\t\t) AS groupIDs\n\t\t\tFROM\t\t" . $this->databasePrefix . "kunena_users kunena_users,\n\t\t\t\t\t" . $this->databasePrefix . "users users\n\t\t\tWHERE\t\tusers.id = kunena_users.userid\n\t\t\tORDER BY\tkunena_users.userid"; $statement = $this->database->prepareStatement($sql, $limit, $offset); $statement->execute(); while ($row = $statement->fetchArray()) { $data = array('username' => $row['username'], 'password' => StringUtil::getRandomID(), 'email' => $row['email'], 'banned' => $row['banned'] ? 1 : 0, 'registrationDate' => @strtotime($row['registerDate']), 'lastActivityTime' => @strtotime($row['lastvisitDate']), 'signature' => self::fixBBCodes($row['signature'])); // get user options $options = array('location' => $row['location'], 'birthday' => $row['birthdate'], 'icq' => $row['icq'], 'skype' => $row['skype'], 'homepage' => $row['websiteurl'], 'gender' => $row['gender']); $additionalData = array('groupIDs' => explode(',', $row['groupIDs']), 'options' => $options); // import user $newUserID = ImportHandler::getInstance()->getImporter('com.woltlab.wcf.user')->import($row['userid'], $data, $additionalData); // update password hash if ($newUserID) { $password = '******' . $row['password']; if (substr($row['password'], 0, 3) == '$1$') { $password = '******' . $row['password']; } else { if (substr($row['password'], 0, 4) == '$2y$' || substr($row['password'], 0, 4) == '$2a$') { $password = PasswordUtil::getSaltedHash($row['password'], $row['password']); } else { if (substr($row['password'], 0, 3) == '$P$') { $password = '******' . $row['password']; } } } $passwordUpdateStatement->execute(array($password, $newUserID)); } } }
/** * forget_password this function should send the email password change to this user * * @return Array */ public function forgetPassword($oMbqEtUser) { $oUser = $oMbqEtUser->mbqBind['oUser']; // generate a new lost password key $lostPasswordKey = StringUtil::getRandomID(); // save key and request time in database $objectAction = new UserAction(array($oUser), 'update', array('data' => array_merge($this->additionalFields, array('lostPasswordKey' => $lostPasswordKey, 'lastLostPasswordRequestTime' => TIME_NOW)))); $objectAction->executeAction(); // send mail $mail = new Mail(array($oUser->username => $oUser->email), WCF::getLanguage()->getDynamicVariable('wcf.user.lostPassword.mail.subject'), WCF::getLanguage()->getDynamicVariable('wcf.user.lostPassword.mail', array('username' => $oUser->username, 'userID' => $oUser->userID, 'key' => $lostPasswordKey))); $mail->send(); return true; }
protected function tar() { $this->filename = FileUtil::getTempFolder() . 'CMS-Export.' . StringUtil::getRandomID() . '.tgz'; $this->buildXML(); $this->tarFiles(); $files = array('cmsData.xml', 'files.tar'); $tar = new TarWriter($this->filename, true); foreach ($files as $file) { $tar->add(FileUtil::getTempFolder() . $file, '', FileUtil::getTempFolder()); @unlink(FileUtil::getTempFolder() . $file); } $tar->create(); }
/** * @see \wcf\action\IAction::execute() */ public function execute() { parent::execute(); // user accepted the connection if (isset($_GET['code'])) { try { // fetch access_token $request = new HTTPRequest('https://github.com/login/oauth/access_token', array(), array('client_id' => StringUtil::trim(GITHUB_PUBLIC_KEY), 'client_secret' => StringUtil::trim(GITHUB_PRIVATE_KEY), 'code' => $_GET['code'])); $request->execute(); $reply = $request->getReply(); $content = $reply['body']; } catch (SystemException $e) { // force logging $e->getExceptionID(); throw new IllegalLinkException(); } // validate state, validation of state is executed after fetching the access_token to invalidate 'code' if (!isset($_GET['state']) || $_GET['state'] != WCF::getSession()->getVar('__githubInit')) { throw new IllegalLinkException(); } WCF::getSession()->unregister('__githubInit'); parse_str($content, $data); // check whether the token is okay if (isset($data['error'])) { throw new IllegalLinkException(); } // check whether a user is connected to this github account $user = $this->getUser($data['access_token']); if ($user->userID) { // a user is already connected, but we are logged in, break if (WCF::getUser()->userID) { throw new NamedUserException(WCF::getLanguage()->get('wcf.user.3rdparty.github.connect.error.inuse')); } else { if (UserAuthenticationFactory::getInstance()->getUserAuthentication()->supportsPersistentLogins()) { $password = StringUtil::getRandomID(); $userEditor = new UserEditor($user); $userEditor->update(array('password' => $password)); // reload user to retrieve salt $user = new User($user->userID); UserAuthenticationFactory::getInstance()->getUserAuthentication()->storeAccessData($user, $user->username, $password); } WCF::getSession()->changeUser($user); WCF::getSession()->update(); HeaderUtil::redirect(LinkHandler::getInstance()->getLink()); } } else { try { // fetch userdata $request = new HTTPRequest('https://api.github.com/user?access_token=' . $data['access_token']); $request->execute(); $reply = $request->getReply(); $userData = JSON::decode(StringUtil::trim($reply['body'])); } catch (SystemException $e) { // force logging $e->getExceptionID(); throw new IllegalLinkException(); } WCF::getSession()->register('__3rdPartyProvider', 'github'); // save data for connection if (WCF::getUser()->userID) { WCF::getSession()->register('__githubUsername', $userData['login']); WCF::getSession()->register('__githubToken', $data['access_token']); HeaderUtil::redirect(LinkHandler::getInstance()->getLink('AccountManagement') . '#3rdParty'); } else { WCF::getSession()->register('__githubData', $userData); WCF::getSession()->register('__username', $userData['login']); // check whether user has entered a public email if (isset($userData) && isset($userData['email']) && $userData['email'] !== null) { WCF::getSession()->register('__email', $userData['email']); } else { try { $request = new HTTPRequest('https://api.github.com/user/emails?access_token=' . $data['access_token']); $request->execute(); $reply = $request->getReply(); $emails = JSON::decode(StringUtil::trim($reply['body'])); // handle future response as well a current response (see. http://developer.github.com/v3/users/emails/) if (is_string($emails[0])) { $email = $emails[0]; } else { $email = $emails[0]['email']; foreach ($emails as $tmp) { if ($tmp['primary']) { $email = $tmp['email']; } break; } } WCF::getSession()->register('__email', $email); } catch (SystemException $e) { } } WCF::getSession()->register('__githubToken', $data['access_token']); // we assume that bots won't register on github first // thus no need for a captcha if (REGISTER_USE_CAPTCHA) { WCF::getSession()->register('noRegistrationCaptcha', true); } WCF::getSession()->update(); HeaderUtil::redirect(LinkHandler::getInstance()->getLink('Register')); } } $this->executed(); exit; } // user declined or any other error that may occur if (isset($_GET['error'])) { throw new NamedUserException(WCF::getLanguage()->get('wcf.user.3rdparty.github.login.error.' . $_GET['error'])); } // start auth by redirecting to github $token = StringUtil::getRandomID(); WCF::getSession()->register('__githubInit', $token); HeaderUtil::redirect("https://github.com/login/oauth/authorize?client_id=" . rawurlencode(StringUtil::trim(GITHUB_PUBLIC_KEY)) . "&scope=" . rawurlencode('user:email') . "&state=" . $token); $this->executed(); exit; }
/** * Reads a random captcha question. */ protected function readCaptchaQuestion() { $questionID = array_rand($this->questions); $this->question = $this->questions[$questionID]; do { $this->captchaQuestion = StringUtil::getRandomID(); } while (WCF::getSession()->getVar('captchaQuestion_' . $this->captchaQuestion) !== null); WCF::getSession()->register('captchaQuestion_' . $this->captchaQuestion, $questionID); }
/** * add private conversation message * * @param Object $oMbqEtPcMsg * @param Object $oMbqEtPc */ public function addMbqEtPcMsg($oMbqEtPcMsg, $oMbqEtPc) { $oConversation = $oMbqEtPc->mbqBind['oViewableConversation']->getDecoratedObject(); //ref wcf\form\MessageForm,wcf\form\ConversationMessageAddForm $oMbqEtPcMsg->msgContent->setOriValue(MessageUtil::stripCrap(StringUtil::trim($oMbqEtPcMsg->msgContent->oriValue))); $attachmentObjectType = 'com.woltlab.wcf.conversation.message'; $attachmentObjectID = 0; $tmpHash = StringUtil::getRandomID(); $attachmentParentObjectID = 0; //settings $preParse = $enableSmilies = $enableBBCodes = $showSignature = $enableHtml = 0; $preParse = 1; if (WCF::getSession()->getPermission('user.message.canUseSmilies')) { $enableSmilies = 1; } //if (WCF::getSession()->getPermission('user.message.canUseHtml')) $enableHtml = 1; if (WCF::getSession()->getPermission('user.message.canUseBBCodes')) { $enableBBCodes = 1; } $showSignature = 1; // get max text length $maxTextLength = WCF::getSession()->getPermission('user.conversation.maxLength'); //!!! use this,is better than 0 //begin validate $allowedBBCodesPermission = 'user.message.allowedBBCodes'; //validateText if (empty($oMbqEtPcMsg->msgContent->oriValue)) { MbqError::alert('', "Need message content.", '', MBQ_ERR_APP); } // check text length if ($maxTextLength != 0 && StringUtil::length($oMbqEtPcMsg->msgContent->oriValue) > $maxTextLength) { MbqError::alert('', "Message content is too long.", '', MBQ_ERR_APP); } if ($enableBBCodes && $allowedBBCodesPermission) { $disallowedBBCodes = BBCodeParser::getInstance()->validateBBCodes($oMbqEtPcMsg->msgContent->oriValue, ArrayUtil::trim(explode(',', WCF::getSession()->getPermission($allowedBBCodesPermission)))); if (!empty($disallowedBBCodes)) { MbqError::alert('', "Message content included disallowed bbcodes.", '', MBQ_ERR_APP); } } // search for censored words if (ENABLE_CENSORSHIP) { $result = Censorship::getInstance()->test($oMbqEtPcMsg->msgContent->oriValue); if ($result) { MbqError::alert('', "Found censored words in message content.", '', MBQ_ERR_APP); } } //language $languageID = NULL; //attachment if (MODULE_ATTACHMENT && $attachmentObjectType) { $attachmentHandler = new AttachmentHandler($attachmentObjectType, $attachmentObjectID, $tmpHash, $attachmentParentObjectID); } //save if ($preParse) { // BBCodes are enabled if ($enableBBCodes) { if ($allowedBBCodesPermission) { $oMbqEtPcMsg->msgContent->setOriValue(PreParser::getInstance()->parse($oMbqEtPcMsg->msgContent->oriValue, ArrayUtil::trim(explode(',', WCF::getSession()->getPermission($allowedBBCodesPermission))))); } else { $oMbqEtPcMsg->msgContent->setOriValue(PreParser::getInstance()->parse($oMbqEtPcMsg->msgContent->oriValue)); } } else { $oMbqEtPcMsg->msgContent->setOriValue(PreParser::getInstance()->parse($oMbqEtPcMsg->msgContent->oriValue, array())); } } // save message $data = array('conversationID' => $oConversation->conversationID, 'message' => $oMbqEtPcMsg->msgContent->oriValue, 'time' => TIME_NOW, 'userID' => WCF::getUser()->userID, 'username' => WCF::getUser()->username, 'enableBBCodes' => $enableBBCodes, 'enableHtml' => $enableHtml, 'enableSmilies' => $enableSmilies, 'showSignature' => $showSignature); $messageData = array('data' => $data, 'attachmentHandler' => $attachmentHandler); $objectAction = new ConversationMessageAction(array(), 'create', $messageData); $resultValues = $objectAction->executeAction(); if ($resultValues['returnValues']->messageID) { $oMbqEtPcMsg->msgId->setOriValue($resultValues['returnValues']->messageID); } else { MbqError::alert('', "Can not create topic.", '', MBQ_ERR_APP); } return $oMbqEtPcMsg; }
/** * modify forum post * * @param $oMbqEtForumPost */ public function mdfMbqEtForumPost($oMbqEtForumPost, $mbqOpt) { $oBoard = $oMbqEtForumPost->oMbqEtForumTopic->oMbqEtForum->mbqBind['oDetailedBoardNode']->getBoard(); $oThread = $oMbqEtForumPost->oMbqEtForumTopic->mbqBind['oViewableThread']->getDecoratedObject(); $oPost = $oMbqEtForumPost->mbqBind['oViewablePost']->getDecoratedObject(); //ref wbb\form\PostEditForm,wcf\form\MessageForm,wbb\form\ThreadAddForm $oMbqEtForumPost->postTitle->setOriValue(StringUtil::trim($oMbqEtForumPost->postTitle->oriValue)); $oMbqEtForumPost->postContent->setOriValue(MessageUtil::stripCrap(StringUtil::trim($oMbqEtForumPost->postContent->oriValue))); $editReason = ''; $attachmentObjectType = 'com.woltlab.wbb.post'; $attachmentObjectID = $oMbqEtForumPost->postId->oriValue; if ($oThread->firstPostID == $oMbqEtForumPost->postId->oriValue) { $enableMultilingualism = true; $isFirstPost = true; } $tmpHash = StringUtil::getRandomID(); $attachmentParentObjectID = $oBoard->boardID; //$attachmentParentObjectID = 0; //settings $preParse = $enableSmilies = $enableBBCodes = $showSignature = $subscribeThread = $enableHtml = 0; $preParse = 1; if (WCF::getSession()->getPermission('user.message.canUseSmilies')) { $enableSmilies = 1; } //if (WCF::getSession()->getPermission('user.message.canUseHtml')) $enableHtml = 1; if (WCF::getSession()->getPermission('user.message.canUseBBCodes')) { $enableBBCodes = 1; } $showSignature = 1; $subscribeThread = 1; $type = Thread::TYPE_DEFAULT; if ($oThread->isSticky) { $type = Thread::TYPE_STICKY; } elseif ($oThread->isAnnouncement) { MbqError::alert('', __METHOD__ . ',line:' . __LINE__ . '.' . 'Sorry,do not support announcement type.'); } if ($oBoard->getPermission('canHideEditNote')) { $hideEditNote = true; } else { $hideEditNote = false; } // get max text length $maxTextLength = WCF::getSession()->getPermission('user.board.maxPostLength'); $minCharLength = WBB_POST_MIN_CHAR_LENGTH; $minWordCount = WBB_POST_MIN_WORD_COUNT; //begin validate $allowedBBCodesPermission = 'user.message.allowedBBCodes'; //validateSubject if (StringUtil::length($oMbqEtForumPost->postTitle->oriValue) > 255) { MbqError::alert('', "Post title is too long.", '', MBQ_ERR_APP); } // search for censored words if (ENABLE_CENSORSHIP) { $result = Censorship::getInstance()->test($oMbqEtForumPost->postTitle->oriValue); if ($result) { MbqError::alert('', "Found censored words in post title.", '', MBQ_ERR_APP); } } //validateText if (empty($oMbqEtForumPost->postContent->oriValue)) { MbqError::alert('', "Need post content.", '', MBQ_ERR_APP); } // check text length if ($maxTextLength != 0 && StringUtil::length($oMbqEtForumPost->postContent->oriValue) > $maxTextLength) { MbqError::alert('', "Post content is too long.", '', MBQ_ERR_APP); } if ($enableBBCodes && $allowedBBCodesPermission) { $disallowedBBCodes = BBCodeParser::getInstance()->validateBBCodes($oMbqEtForumPost->postContent->oriValue, ArrayUtil::trim(explode(',', WCF::getSession()->getPermission($allowedBBCodesPermission)))); if (!empty($disallowedBBCodes)) { MbqError::alert('', "Post content included disallowed bbcodes.", '', MBQ_ERR_APP); } } // search for censored words if (ENABLE_CENSORSHIP) { $result = Censorship::getInstance()->test($oMbqEtForumPost->postContent->oriValue); if ($result) { MbqError::alert('', "Found censored words in post content.", '', MBQ_ERR_APP); } } if ($minCharLength && StringUtil::length($oMbqEtForumPost->postContent->oriValue) < $minCharLength) { MbqError::alert('', "Post content is too short.", '', MBQ_ERR_APP); } if ($minWordCount && count(explode(' ', $oMbqEtForumPost->postContent->oriValue)) < $minWordCount) { MbqError::alert('', "Need more words in Post content", '', MBQ_ERR_APP); } //attachment if (MODULE_ATTACHMENT && $attachmentObjectType) { $attachmentHandler = new AttachmentHandler($attachmentObjectType, $attachmentObjectID, $tmpHash, $attachmentParentObjectID); } //save if ($preParse) { // BBCodes are enabled if ($enableBBCodes) { if ($allowedBBCodesPermission) { $oMbqEtForumPost->postContent->setOriValue(PreParser::getInstance()->parse($oMbqEtForumPost->postContent->oriValue, ArrayUtil::trim(explode(',', WCF::getSession()->getPermission($allowedBBCodesPermission))))); } else { $oMbqEtForumPost->postContent->setOriValue(PreParser::getInstance()->parse($oMbqEtForumPost->postContent->oriValue)); } } else { $oMbqEtForumPost->postContent->setOriValue(PreParser::getInstance()->parse($oMbqEtForumPost->postContent->oriValue, array())); } } // save post $data = array('subject' => $oMbqEtForumPost->postTitle->oriValue, 'message' => $oMbqEtForumPost->postContent->oriValue, 'enableBBCodes' => $enableBBCodes, 'enableHtml' => $enableHtml, 'enableSmilies' => $enableSmilies, 'showSignature' => $showSignature); if (!$hideEditNote && (WCF::getUser()->userID != $oPost->userID || $oPost->time <= TIME_NOW - WBB_POST_EDIT_HIDE_EDIT_NOTE_PERIOD * 60)) { $data['editCount'] = $oPost->editCount + 1; $data['editReason'] = $editReason; $data['editor'] = WCF::getUser()->username; $data['editorID'] = WCF::getUser()->userID; $data['lastEditTime'] = TIME_NOW; } $oPostAction = new PostAction(array($oPost), 'update', array('attachmentHandler' => $attachmentHandler, 'data' => $data, 'isEdit' => true)); $oPostAction->executeAction(); $threadData = array(); if (isset($isFirstPost) && $isFirstPost) { // update title if ($oMbqEtForumPost->postTitle->oriValue != $oMbqEtForumPost->oMbqEtForumTopic->topicTitle->oriValue) { $threadData['topic'] = $oMbqEtForumPost->postTitle->oriValue; } // handle thread type switch ($type) { case Thread::TYPE_DEFAULT: $threadData['isSticky'] = 0; $threadData['isAnnouncement'] = 0; break; case Thread::TYPE_STICKY: $threadData['isSticky'] = 1; $threadData['isAnnouncement'] = 0; break; case Thread::TYPE_ANNOUNCEMENT: $threadData['isSticky'] = 0; $threadData['isAnnouncement'] = 1; break; } } if (isset($isFirstPost) && $isFirstPost || !empty($threadData)) { $threadData = array('data' => $threadData); if ($isFirstPost) { $threadData['announcementBoardIDs'] = array(); } //!!! $threadAction = new ThreadAction(array($oThread), 'update', $threadData); $threadAction->executeAction(); } // save subscription if (WCF::getUser()->userID) { if ($subscribeThread && !$oThread->isSubscribed()) { $action = new UserObjectWatchAction(array(), 'subscribe', array('data' => array('objectID' => $oPost->threadID, 'objectType' => 'com.woltlab.wbb.thread'), 'enableNotification' => UserNotificationHandler::getInstance()->getEventSetting('com.woltlab.wbb.post', 'post') !== false ? 1 : 0)); $action->executeAction(); } else { if (!$subscribeThread && $oThread->isSubscribed()) { $action = new UserObjectWatchAction(array(), 'unsubscribe', array('data' => array('objectID' => $oPost->threadID, 'objectType' => 'com.woltlab.wbb.thread'))); $action->executeAction(); } } } return $oMbqEtForumPost; }
/** * Generates a new temporary filename in TMP_DIR. * * @param string $prefix * @param string $extension * @param string $dir * @return string temporary filename */ public static function getTemporaryFilename($prefix = 'tmpFile_', $extension = '', $dir = TMP_DIR) { $dir = self::addTrailingSlash($dir); do { $tmpFile = $dir . $prefix . StringUtil::getRandomID() . $extension; } while (file_exists($tmpFile)); return $tmpFile; }
/** * Sends the mail notification. * * @param \wcf\data\user\notification\UserNotification $notification * @param \wcf\data\user\User $user * @param \wcf\system\user\notification\event\IUserNotificationEvent $event */ public function sendInstantMailNotification(UserNotification $notification, User $user, IUserNotificationEvent $event) { // no notifications for disabled or banned users if ($user->activationCode) { return; } if ($user->banned) { return; } // recipient's language $event->setLanguage($user->getLanguage()); // add mail header $message = $user->getLanguage()->getDynamicVariable('wcf.user.notification.mail.header', array('user' => $user)) . "\n\n"; // get message $message .= $event->getEmailMessage(); // append notification mail footer $token = $user->notificationMailToken; if (!$token) { // generate token if not present $token = mb_substr(StringUtil::getHash(serialize(array($user->userID, StringUtil::getRandomID()))), 0, 20); $editor = new UserEditor($user); $editor->update(array('notificationMailToken' => $token)); } $message .= "\n\n" . $user->getLanguage()->getDynamicVariable('wcf.user.notification.mail.footer', array('user' => $user, 'token' => $token, 'notification' => $notification)); // build mail $mail = new Mail(array($user->username => $user->email), $user->getLanguage()->getDynamicVariable('wcf.user.notification.mail.subject', array('title' => $event->getEmailTitle())), $message); $mail->setLanguage($user->getLanguage()); $mail->send(); }