/** * Saves posted data for a new/edited forum thread post * * @return void */ public function savethread() { if (User::isGuest()) { App::redirect(Route::url('index.php?option=com_users&view=login&return=' . base64_encode(Route::url($this->base)))); return; } // Incoming $section = Request::getVar('section', ''); $fields = Request::getVar('fields', array(), 'post', 'none', 2); $fields = array_map('trim', $fields); $this->_authorize('thread', intval($fields['id'])); $asset = 'thread'; if ($fields['parent']) { //$asset = 'post'; } if ($fields['id']) { $old = new \Components\Forum\Tables\Post($this->database); $old->load(intval($fields['id'])); if ($old->created_by == User::get('id')) { $this->params->set('access-edit-thread', true); } } if ($fields['id'] && !$this->params->get('access-edit-thread') || !$fields['id'] && !$this->params->get('access-create-thread')) { App::redirect(Route::url('index.php?option=' . $this->option . '&cn=' . $this->group->get('cn') . '&active=forum'), Lang::txt('PLG_GROUPS_FORUM_NOT_AUTHORIZED'), 'warning'); return; } $fields['sticky'] = isset($fields['sticky']) ? $fields['sticky'] : 0; $fields['closed'] = isset($fields['closed']) ? $fields['closed'] : 0; // Bind data $model = new \Components\Forum\Tables\Post($this->database); if (!$model->bind($fields)) { $this->addPluginMessage($model->getError(), 'error'); return $this->editthread($model); } if (!$model->anonymous) { $model->anonymous = 0; } // Check content if (!$model->check()) { $this->addPluginMessage($model->getError(), 'error'); return $this->editthread($model); } // Store new content if (!$model->store()) { $this->addPluginMessage($model->getError(), 'error'); return $this->editthread($model); } $parent = $model->parent ? $model->parent : $model->id; //update $this->upload($parent, $model->id); if ($fields['id']) { if ($old->category_id != $fields['category_id']) { $model->updateReplies(array('category_id' => $fields['category_id']), $model->id); } } $category = new \Components\Forum\Tables\Category($this->database); $category->load(intval($model->category_id)); $sectionTbl = new \Components\Forum\Tables\Section($this->database); $sectionTbl->load(intval($category->section_id)); $tags = Request::getVar('tags', '', 'post'); $tagger = new \Components\Forum\Models\Tags($model->id); $tagger->setTags($tags, User::get('id')); // Determine post save message // Also, get subject of post for outgoing email, either the title of parent post (for replies), or title of current post (for new threads) if (!$fields['parent']) { $message = Lang::txt('PLG_GROUPS_FORUM_THREAD_STARTED'); $posttitle = $model->title; } else { $message = Lang::txt('PLG_GROUPS_FORUM_POST_ADDED'); $parentForumTablePost = new \Components\Forum\Tables\Post($this->database); $parentForumTablePost->load(intval($fields['parent'])); $posttitle = $parentForumTablePost->title; } if ($fields['id']) { $message = $model->modified_by ? Lang::txt('PLG_GROUPS_FORUM_POST_EDITED') : Lang::txt('PLG_GROUPS_FORUM_POST_ADDED'); } // Determine route if ($model->parent) { $thread = $model->thread; } else { $thread = $model->id; } $params = Component::params('com_groups'); // Email the group and insert email tokens to allow them to respond to group posts via email if ($params->get('email_comment_processing')) { $esection = new \Components\Forum\Models\Section($sectionTbl); $ecategory = new \Components\Forum\Models\Category($category); $ecategory->set('section_alias', $esection->get('alias')); $ethread = new \Components\Forum\Models\Thread(intval($thread)); $ethread->set('section', $esection->get('alias')); $ethread->set('category', $ecategory->get('alias')); $epost = new \Components\Forum\Models\Thread($model); $epost->set('section', $esection->get('alias')); $epost->set('category', $ecategory->get('alias')); // Figure out who should be notified about this comment (all group members for now) $userIDsToEmail = array(); foreach ($this->members as $mbr) { //Look up user info $user = User::getInstance($mbr); if ($user->get('id')) { include_once PATH_CORE . DS . 'plugins' . DS . 'groups' . DS . 'memberoptions' . DS . 'memberoption.class.php'; // Find the user's group settings, do they want to get email (0 or 1)? $groupMemberOption = new GroupsTableMemberoption($this->database); $groupMemberOption->loadRecord($this->group->get('gidNumber'), $user->get('id'), GROUPS_MEMBEROPTION_TYPE_DISCUSSION_NOTIFICIATION); $sendEmail = 0; if ($groupMemberOption->id) { $sendEmail = $groupMemberOption->optionvalue; } if ($sendEmail == 1) { $userIDsToEmail[] = $user->get('id'); } } } $encryptor = new \Hubzero\Mail\Token(); $from = array('name' => Config::get('sitename'), 'email' => Config::get('mailfrom')); // Email each group member separately, each needs a user specific token foreach ($userIDsToEmail as $userID) { // Construct User specific Email ThreadToken // Version, type, userid, xforumid $token = $encryptor->buildEmailToken(1, 2, $userID, $parent); // add unsubscribe link $unsubscribeToken = $encryptor->buildEmailToken(1, 3, $userID, $this->group->get('gidNumber')); $unsubscribeLink = rtrim(Request::base(), '/') . '/' . ltrim(Route::url('index.php?option=com_groups&cn=' . $this->group->get('cn') . '&active=forum&action=unsubscribe&t=' . $unsubscribeToken), DS); $msg = array(); // create view object $eview = new \Hubzero\Mail\View(array('base_path' => __DIR__, 'name' => 'email', 'layout' => 'comment_plain')); // plain text $eview->set('delimiter', '~!~!~!~!~!~!~!~!~!~!')->set('unsubscribe', $unsubscribeLink)->set('group', $this->group)->set('section', $esection)->set('category', $ecategory)->set('thread', $ethread)->set('post', $epost); $plain = $eview->loadTemplate(false); $msg['plaintext'] = str_replace("\n", "\r\n", $plain); // HTML $eview->setLayout('comment_html'); $html = $eview->loadTemplate(); $msg['multipart'] = str_replace("\n", "\r\n", $html); $subject = ' - ' . $this->group->get('cn') . ' - ' . $posttitle; $from['replytoemail'] = 'hgm-' . $token . '@' . $_SERVER['HTTP_HOST']; if (!Event::trigger('xmessage.onSendMessage', array('group_message', $subject, $msg, $from, array($userID), $this->option, null, '', $this->group->get('gidNumber')))) { $this->setError(Lang::txt('GROUPS_ERROR_EMAIL_MEMBERS_FAILED')); } } } // Set the redirect App::redirect(Route::url($this->base . '&scope=' . $section . '/' . $category->alias . '/' . $thread), $message, 'passed'); }
/** * Saves posted data for a new/edited forum thread post * * @return void */ public function savethread() { // Login check is handled in the onGroup() method /*if (User::isGuest()) { App::redirect( Route::url('index.php?option=com_users&view=login&return=' . base64_encode(Route::url($this->base, false, true))) ); return; }*/ // Check for request forgeries Request::checkToken(); // Incoming $section = Request::getVar('section', ''); $fields = Request::getVar('fields', array(), 'post', 'none', 2); $fields = array_map('trim', $fields); $fields['sticky'] = isset($fields['sticky']) ? $fields['sticky'] : 0; $fields['closed'] = isset($fields['closed']) ? $fields['closed'] : 0; $fields['anonymous'] = isset($fields['anonymous']) ? $fields['anonymous'] : 0; // Instantiate a Post record $post = Post::oneOrNew($fields['id']); $this->_authorize('thread', intval($fields['id'])); $asset = 'thread'; if ($fields['parent']) { //$asset = 'post'; } $moving = false; // Already present if ($fields['id']) { if ($post->get('created_by') == User::get('id')) { $this->params->set('access-edit-' . $asset, true); } // Determine if we are moving the category for email suppression if ($post->get('category_id') != $fields['category_id']) { $moving = true; } $fields['modified'] = \Date::toSql(); $fields['modified_by'] = User::get('id'); } if (!$this->params->get('access-edit-thread') && !$this->params->get('access-create-thread')) { App::redirect(Route::url('index.php?option=' . $this->option . '&cn=' . $this->group->get('cn') . '&active=forum'), Lang::txt('PLG_GROUPS_FORUM_NOT_AUTHORIZED'), 'warning'); } // Bind data $post->set($fields); // Make sure the thread exists and is accepting new posts if ($post->get('parent') && isset($fields['thread'])) { $thread = Post::oneOrFail($fields['thread']); if (!$thread->get('id') || $thread->get('closed')) { Notify::error(Lang::txt('PLG_GROUPS_FORUM_ERROR_THREAD_CLOSED')); return $this->editthread($post); } } if (!$post->get('category_id')) { Notify::error(Lang::txt('PLG_GROUPS_FORUM_ERROR_MISSING_CATEGORY')); return $this->editthread($post); } // Make sure the category exists and is accepting new posts $category = Category::oneOrFail($post->get('category_id')); if ($category->get('closed')) { Notify::error(Lang::txt('PLG_GROUPS_ERROR_CATEGORY_CLOSED')); return $this->editthread($post); } // Store new content if (!$post->save()) { Notify::error($post->getError()); return $this->editthread($post); } // Upload if (!$this->upload($post->get('thread', $post->get('id')), $post->get('id'))) { Notify::error($this->getError()); return $this->editthread($post); } // Save tags $post->tag(Request::getVar('tags', '', 'post'), User::get('id')); // Set message if (!$fields['id']) { $message = Lang::txt('PLG_GROUPS_FORUM_POST_ADDED'); if (!$fields['parent']) { $message = Lang::txt('PLG_GROUPS_FORUM_THREAD_STARTED'); } } else { $message = $post->get('modified_by') ? Lang::txt('PLG_GROUPS_FORUM_POST_EDITED') : Lang::txt('PLG_GROUPS_FORUM_POST_ADDED'); } $section = $category->section(); $thread = Post::oneOrNew($post->get('thread')); // Disable notifications if ($fields['id'] && !Request::getInt('notify', 0)) { $moving = true; } // Email the group and insert email tokens to allow them to respond to group posts via email $params = Component::params('com_groups'); if ($params->get('email_comment_processing') && (isset($moving) && $moving == false)) { $thread->set('section', $section->get('alias')); $thread->set('category', $category->get('alias')); $post->set('section', $section->get('alias')); $post->set('category', $category->get('alias')); // Figure out who should be notified about this comment (all group members for now) $userIDsToEmail = array(); $memberoptions = false; if (file_exists(PATH_CORE . DS . 'plugins' . DS . 'groups' . DS . 'memberoptions' . DS . 'models' . DS . 'memberoption.php')) { include_once PATH_CORE . DS . 'plugins' . DS . 'groups' . DS . 'memberoptions' . DS . 'models' . DS . 'memberoption.php'; $memberoptions = true; } foreach ($this->members as $mbr) { //Look up user info $user = User::getInstance($mbr); if ($user->get('id') && $memberoptions) { // Find the user's group settings, do they want to get email (0 or 1)? $groupMemberOption = Plugins\Groups\Memberoptions\Models\Memberoption::oneByUserAndOption($this->group->get('gidNumber'), $user->get('id'), 'receive-forum-email'); $sendEmail = $groupMemberOption->get('optionvalue', 0); if ($sendEmail == 1) { $userIDsToEmail[] = $user->get('id'); } } } $allowEmailResponses = true; try { $encryptor = new \Hubzero\Mail\Token(); } catch (Exception $e) { $allowEmailResponses = false; } $from = array('name' => (!$post->get('anonymous') ? $post->creator->get('name', Lang::txt('PLG_GROUPS_FORUM_UNKNOWN')) : Lang::txt('PLG_GROUPS_FORUM_ANONYMOUS')) . ' @ ' . Config::get('sitename'), 'email' => Config::get('mailfrom'), 'replytoname' => Config::get('sitename'), 'replytoemail' => Config::get('mailfrom')); // Email each group member separately, each needs a user specific token foreach ($userIDsToEmail as $userID) { $unsubscribeLink = ''; $delimiter = ''; if ($allowEmailResponses) { $delimiter = '~!~!~!~!~!~!~!~!~!~!'; // Construct User specific Email ThreadToken // Version, type, userid, xforumid $token = $encryptor->buildEmailToken(1, 2, $userID, $post->get('thread', $post->get('id'))); // add unsubscribe link $unsubscribeToken = $encryptor->buildEmailToken(1, 3, $userID, $this->group->get('gidNumber')); $unsubscribeLink = rtrim(Request::base(), '/') . '/' . ltrim(Route::url('index.php?option=com_groups&cn=' . $this->group->get('cn') . '&active=forum&action=unsubscribe&t=' . $unsubscribeToken), DS); $from['replytoname'] = Lang::txt('PLG_GROUPS_FORUM_REPLYTO') . ' @ ' . Config::get('sitename'); $from['replytoemail'] = 'hgm-' . $token . '@' . $_SERVER['HTTP_HOST']; } $msg = array(); // create view object $eview = new \Hubzero\Mail\View(array('base_path' => __DIR__, 'name' => 'email', 'layout' => 'comment_plain')); // plain text $eview->set('delimiter', $delimiter)->set('unsubscribe', $unsubscribeLink)->set('group', $this->group)->set('section', $section)->set('category', $category)->set('thread', $thread)->set('post', $post); $plain = $eview->loadTemplate(false); $msg['plaintext'] = str_replace("\n", "\r\n", $plain); // HTML $eview->setLayout('comment_html'); $html = $eview->loadTemplate(); $msg['multipart'] = str_replace("\n", "\r\n", $html); $subject = Lang::txt('PLG_GROUPS_FORUM') . ': ' . $this->group->get('cn') . ' - ' . $thread->get('title'); if (!Event::trigger('xmessage.onSendMessage', array('group_message', $subject, $msg, $from, array($userID), $this->option, null, '', $this->group->get('gidNumber')))) { $this->setError(Lang::txt('GROUPS_ERROR_EMAIL_MEMBERS_FAILED')); } } } $url = $this->base . '&scope=' . $section->get('alias') . '/' . $category->get('alias') . '/' . $thread->get('id'); // Record the activity $recipients = array(['group', $this->group->get('gidNumber')], ['forum.' . $this->forum->get('scope'), $this->forum->get('scope_id')], ['user', $post->get('created_by')]); foreach ($this->group->get('managers') as $recipient) { $recipients[] = ['user', $recipient]; } $type = 'thread'; $desc = Lang::txt('PLG_GROUPS_FORUM_ACTIVITY_' . strtoupper($type) . '_' . ($fields['id'] ? 'UPDATED' : 'CREATED'), '<a href="' . Route::url($url) . '">' . $post->get('title') . '</a>'); // If this is a post in a thread and not the thread starter... if ($post->get('parent')) { $thread = isset($thread) ? $thread : Post::oneOrFail($post->get('thread')); $thread->set('last_activity', $fields['id'] ? $post->get('modified') : $post->get('created')); $thread->save(); $type = 'post'; $desc = Lang::txt('PLG_GROUPS_FORUM_ACTIVITY_' . strtoupper($type) . '_' . ($fields['id'] ? 'UPDATED' : 'CREATED'), $post->get('id'), '<a href="' . Route::url($url) . '">' . $thread->get('title') . '</a>'); // If the parent post is not the same as the // thread starter (i.e., this is a reply) if ($post->get('parent') != $post->get('thread')) { $parent = Post::oneOrFail($post->get('parent')); $recipients[] = ['user', $parent->get('created_by')]; } } Event::trigger('system.logActivity', ['activity' => ['action' => $fields['id'] ? 'updated' : 'created', 'scope' => 'forum.' . $type, 'scope_id' => $post->get('id'), 'anonymous' => $post->get('anonymous', 0), 'description' => $desc, 'details' => array('thread' => $post->get('thread'), 'url' => Route::url($url))], 'recipients' => $recipients]); // Set the redirect App::redirect(Route::url($url), $message, 'passed'); }
/** * Email Announcement * * @param object $announcement * @param object $group * @return boolean */ public static function send($announcement, $group) { // get all group members $groupMembers = array(); foreach ($group->get('members') as $member) { if ($profile = User::getInstance($member)) { // Skip invalid emails if (preg_match('/^-[0-9]+@invalid$/', $profile->get('email'))) { continue; } $groupMembers[$profile->get('email')] = $profile->get('name'); } } if (!count($groupMembers)) { return true; } // create view object $eview = new \Hubzero\Mail\View(array('base_path' => __DIR__, 'name' => 'email', 'layout' => 'announcement_plain')); // plain text $eview->set('announcement', $announcement); $plain = $eview->loadTemplate(false); $plain = str_replace("\n", "\r\n", $plain); // HTML $eview->setLayout('announcement_html'); $html = $eview->loadTemplate(); $html = str_replace("\n", "\r\n", $html); // set from address $from = array('name' => Config::get('sitename') . ' Groups', 'email' => Config::get('mailfrom')); // define subject $subject = $group->get('description') . ' Group Announcement'; foreach ($groupMembers as $email => $name) { // create message object $message = new \Hubzero\Mail\Message(); // set message details and send $message->setSubject($subject)->addReplyTo($from['email'], $from['name'])->addFrom($from['email'], $from['name'])->setTo($email, $name)->addPart($plain, 'text/plain')->addPart($html, 'text/html')->send(); } // all good return true; }
/** * Utility method to act on a user after it has been saved. * * This method sends a registration email to new users created in the backend. * * @param array $user Holds the new user data. * @param boolean $isnew True if a new user is stored. * @param boolean $success True if user was succesfully stored in the database. * @param string $msg Message. * @return void */ public function onUserAfterSave($user, $isnew, $success, $msg) { // Existing user - nothing to do...yet. if (!$isnew) { return; } // Initialise variables. $config = App::get('config'); if (App::isSite()) { if ($this->params->get('mail_to_admin', 1)) { $lang = App::get('language'); $lang->load('plg_user_' . $this->_name, PATH_APP . DS . 'bootstrap' . DS . 'site') || $lang->load('plg_user_' . $this->_name, PATH_APP . DS . 'bootstrap' . DS . 'administrator') || $lang->load('plg_user_' . $this->_name, __DIR__); $emailAddress = $config->get('mailfrom'); $eview = new Hubzero\Mail\View(array('base_path' => __DIR__, 'name' => 'emails', 'layout' => 'admincreate_plain')); $eview->set('user', $user); $eview->set('sitename', $config->get('sitename')); $plain = $eview->loadTemplate(false); $plain = str_replace("\n", "\r\n", $plain); $eview->setLayout('admincreate_html'); $html = $eview->loadTemplate(); $html = str_replace("\n", "\r\n", $html); // Assemble the email data $mail = new Hubzero\Mail\Message(); $mail->addFrom($emailAddress, Lang::txt('PLG_USER_JOOMLA_EMAIL_ADMIN', $config->get('sitename')))->addTo($emailAddress)->addHeader('X-Component', Request::getCmd('option', 'com_members'))->addHeader('X-Component-Object', 'user_creation_admin_notification')->setSubject(Lang::txt('PLG_USER_JOOMLA_EMAIL_ACCOUNT_CREATION', $config->get('sitename')))->addPart($plain, 'text/plain')->addPart($html, 'text/html'); if (!$mail->send()) { // TODO: Probably should raise a plugin error but this event is not error checked. Log::error(Lang::txt('PLG_USER_JOOMLA_EMAIL_ERROR', $emailAddress)); } } } // TODO: Suck in the frontend registration emails here as well. Job for a rainy day. if (App::isAdmin()) { if ($this->params->get('mail_to_user', 0)) { $lang = App::get('language'); $defaultLocale = $lang->getTag(); // Look for user language. Priority: // 1. User frontend language // 2. User backend language $userParams = new Hubzero\Config\Registry($user['params']); $userLocale = $userParams->get('language', $userParams->get('admin_language', $defaultLocale)); if ($userLocale != $defaultLocale) { $lang->setLanguage($userLocale); } $lang->load('plg_user_' . $this->_name, PATH_APP . DS . 'bootstrap' . DS . 'site') || $lang->load('plg_user_' . $this->_name, PATH_APP . DS . 'bootstrap' . DS . 'administrator') || $lang->load('plg_user_' . $this->_name, __DIR__); // Compute the mail subject. $emailSubject = Lang::txt('PLG_USER_JOOMLA_NEW_USER_EMAIL_SUBJECT', $user['name'], $config->get('sitename')); // Compute the mail body. $emailBody = Lang::txt('PLG_USER_JOOMLA_NEW_USER_EMAIL_BODY', $user['name'], $config->get('sitename'), Request::root(), $user['username'], $user['password_clear']); // Assemble the email data...the sexy way! $mail = new Hubzero\Mail\Message(); $mail->addFrom($config->get('mailfrom'), $config->get('fromname'))->addTo($user['email'])->setSubject($emailSubject)->setBody($emailBody); // Set application language back to default if we changed it if ($userLocale != $defaultLocale) { $lang->setLanguage($defaultLocale); } if (!$mail->send()) { // TODO: Probably should raise a plugin error but this event is not error checked. throw new Exception(Lang::txt('PLG_USER_JOOMLA_EMAIL_ERROR'), 500); } } } }