public function processIncomingEmailAccount(IncomingEmailAccount $account) { $count = 0; if ($emails = $account->getUnprocessedEmails()) { try { $current_user = framework\Context::getUser(); foreach ($emails as $email) { $user = $this->getOrCreateUserFromEmailString($email->from); if ($user instanceof User) { if (framework\Context::getUser()->getID() != $user->getID()) { framework\Context::switchUserContext($user); } $message = $account->getMessage($email); $data = $message->getBodyPlain() ? $message->getBodyPlain() : strip_tags($message->getBodyHTML()); if ($data) { if (mb_detect_encoding($data, 'UTF-8', true) === false) { $data = utf8_encode($data); } $new_data = ''; foreach (explode("\n", $data) as $line) { $line = trim($line); if ($line) { $line = preg_replace('/^(_{2,}|-{2,})$/', "<hr>", $line); $new_data .= $line . "\n"; } else { $new_data .= "\n"; } } $data = nl2br($new_data, false); } // Parse the subject, and obtain the issues. $parsed_commit = Issue::getIssuesFromTextByRegex(mb_decode_mimeheader($email->subject)); $issues = $parsed_commit["issues"]; // If any issues were found, add new comment to each issue. if ($issues) { foreach ($issues as $issue) { $text = preg_replace('#(^\\w.+:\\n)?(^>.*(\\n|$))+#mi', "", $data); $text = trim($text); if (!$this->processIncomingEmailCommand($text, $issue) && $user->canPostComments()) { $comment = new Comment(); $comment->setContent($text); $comment->setPostedBy($user); $comment->setTargetID($issue->getID()); $comment->setTargetType(Comment::TYPE_ISSUE); $comment->save(); } } } else { if ($user->canReportIssues($account->getProject())) { $issue = new Issue(); $issue->setProject($account->getProject()); $issue->setTitle(mb_decode_mimeheader($email->subject)); $issue->setDescription($data); $issue->setPostedBy($user); $issue->setIssuetype($account->getIssuetype()); $issue->save(); // Append the new issue to the list of affected issues. This // is necessary in order to process the attachments properly. $issues[] = $issue; } } // If there was at least a single affected issue, and mail // contains attachments, add those attachments to related issues. if ($issues && $message->hasAttachments()) { foreach ($message->getAttachments() as $attachment_no => $attachment) { echo 'saving attachment ' . $attachment_no; $name = $attachment['filename']; $new_filename = framework\Context::getUser()->getID() . '_' . NOW . '_' . basename($name); if (framework\Settings::getUploadStorage() == 'files') { $files_dir = framework\Settings::getUploadsLocalpath(); $filename = $files_dir . $new_filename; } else { $filename = $name; } Logging::log('Creating issue attachment ' . $filename . ' from attachment ' . $attachment_no); echo 'Creating issue attachment ' . $filename . ' from attachment ' . $attachment_no; $content_type = $attachment['type'] . '/' . $attachment['subtype']; $file = new File(); $file->setRealFilename($new_filename); $file->setOriginalFilename(basename($name)); $file->setContentType($content_type); $file->setDescription($name); $file->setUploadedBy(framework\Context::getUser()); if (framework\Settings::getUploadStorage() == 'database') { $file->setContent($attachment['data']); } else { Logging::log('Saving file ' . $new_filename . ' with content from attachment ' . $attachment_no); file_put_contents($new_filename, $attachment['data']); } $file->save(); // Attach file to each related issue. foreach ($issues as $issue) { $issue->attachFile($file); } } } $count++; } } } catch (\Exception $e) { } if (framework\Context::getUser()->getID() != $current_user->getID()) { framework\Context::switchUserContext($current_user); } } $account->setTimeLastFetched(time()); $account->setNumberOfEmailsLastFetched($count); $account->save(); return $count; }
public function getMentionedUsers() { $users = array(); if ($this->hasMentions()) { foreach ($this->getMentions() as $user) { $users[$user->getID()] = $user; } } foreach (Comment::getComments($this->getID(), Comment::TYPE_ARTICLE) as $comment) { foreach ($comment->getMentions() as $user) { $users[$user->getID()] = $user; } } return $users; }
public function runUpdateIssueDetails(framework\Request $request) { $this->forward403if(framework\Context::getCurrentProject()->isArchived()); $this->error = false; try { $i18n = framework\Context::getI18n(); $issue = entities\Issue::getIssueFromLink($request['issue_no']); if ($issue->getProject()->getID() != $this->selected_project->getID()) { throw new \Exception($i18n->__('This issue is not valid for this project')); } if (!$issue instanceof entities\Issue) { throw new \Exception($i18n->__('Cannot find this issue')); } $workflow_transition = null; if ($passed_transition = $request['workflow_transition']) { //echo "looking for transition "; $key = str_replace(' ', '', mb_strtolower($passed_transition)); //echo $key . "\n"; foreach ($issue->getAvailableWorkflowTransitions() as $transition) { //echo str_replace(' ', '', mb_strtolower($transition->getName())) . "?"; if (mb_strpos(str_replace(' ', '', mb_strtolower($transition->getName())), $key) !== false) { $workflow_transition = $transition; //echo "found transition " . $transition->getID(); break; } //echo "no"; } if (!$workflow_transition instanceof entities\WorkflowTransition) { throw new \Exception("This transition ({$key}) is not valid"); } } $fields = $request->getRawParameter('fields', array()); $return_values = array(); if ($workflow_transition instanceof entities\WorkflowTransition) { foreach ($fields as $field_key => $field_value) { $classname = "\\thebuggenie\\core\\entities\\" . ucfirst($field_key); $method = "set" . ucfirst($field_key); $choices = $classname::getAll(); $found = false; foreach ($choices as $choice_key => $choice) { if (mb_strpos(str_replace(' ', '', mb_strtolower($choice->getName())), str_replace(' ', '', mb_strtolower($field_value))) !== false) { $request->setParameter($field_key . '_id', $choice->getId()); break; } } } $request->setParameter('comment_body', $request['message']); $return_values['applied_transition'] = $workflow_transition->getName(); if ($workflow_transition->validateFromRequest($request)) { $retval = $workflow_transition->transitionIssueToOutgoingStepFromRequest($issue, $request); $return_values['transition_ok'] = $retval === false ? false : true; } else { $return_values['transition_ok'] = false; $return_values['message'] = "Please pass all information required for this transition"; } } elseif ($issue->isUpdateable()) { foreach ($fields as $field_key => $field_value) { try { if (in_array($field_key, array_merge(array('title', 'state'), entities\Datatype::getAvailableFields(true)))) { switch ($field_key) { case 'state': $issue->setState($field_value == 'open' ? entities\Issue::STATE_OPEN : entities\Issue::STATE_CLOSED); break; case 'title': if ($field_value != '') { $issue->setTitle($field_value); } else { throw new \Exception($i18n->__('Invalid title')); } break; case 'shortname': case 'description': case 'reproduction_steps': $method = "set" . ucfirst($field_key); $issue->{$method}($field_value); break; case 'status': case 'resolution': case 'reproducability': case 'priority': case 'severity': case 'category': $classname = "\\thebuggenie\\core\\entities\\" . ucfirst($field_key); $method = "set" . ucfirst($field_key); $choices = $classname::getAll(); $found = false; foreach ($choices as $choice_key => $choice) { if (str_replace(' ', '', mb_strtolower($choice->getName())) == str_replace(' ', '', mb_strtolower($field_value))) { $issue->{$method}($choice); $found = true; } } if (!$found) { throw new \Exception('Could not find this value'); } break; case 'percent_complete': $issue->setPercentCompleted($field_value); break; case 'owner': case 'assignee': $set_method = "set" . ucfirst($field_key); $unset_method = "un{$set_method}"; switch (mb_strtolower($field_value)) { case 'me': $issue->{$set_method}(framework\Context::getUser()); break; case 'none': $issue->{$unset_method}(); break; default: try { $user = entities\User::findUser(mb_strtolower($field_value)); if ($user instanceof entities\User) { $issue->{$set_method}($user); } } catch (\Exception $e) { throw new \Exception('No such user found'); } break; } break; case 'estimated_time': case 'spent_time': $set_method = "set" . ucfirst(str_replace('_', '', $field_key)); $issue->{$set_method}($field_value); break; case 'milestone': $found = false; foreach ($this->selected_project->getMilestones() as $milestone) { if (str_replace(' ', '', mb_strtolower($milestone->getName())) == str_replace(' ', '', mb_strtolower($field_value))) { $issue->setMilestone($milestone->getID()); $found = true; } } if (!$found) { throw new \Exception('Could not find this milestone'); } break; default: throw new \Exception($i18n->__('Invalid field')); } } $return_values[$field_key] = array('success' => true); } catch (\Exception $e) { $return_values[$field_key] = array('success' => false, 'error' => $e->getMessage()); } } } if (!$workflow_transition instanceof entities\WorkflowTransition) { $issue->getWorkflow()->moveIssueToMatchingWorkflowStep($issue); } if (!array_key_exists('transition_ok', $return_values) || $return_values['transition_ok']) { $comment = new entities\Comment(); $comment->setContent($request->getParameter('message', null, false)); $comment->setPostedBy(framework\Context::getUser()->getID()); $comment->setTargetID($issue->getID()); $comment->setTargetType(entities\Comment::TYPE_ISSUE); $comment->setModuleName('core'); $comment->setIsPublic(true); $comment->setSystemComment(false); $comment->save(); $issue->setSaveComment($comment); $issue->save(); } $this->return_values = $return_values; } catch (\Exception $e) { //$this->getResponse()->setHttpStatus(400); return $this->renderJSON(array('failed' => true, 'error' => $e->getMessage())); } }
if (!isset($include_issue_title) || $include_issue_title == false) { ?> margin-top: -7px; margin-bottom: 10px;<?php } ?> "> <?php switch ($log_action['change_type']) { case \thebuggenie\core\entities\tables\Log::LOG_ISSUE_CREATED: echo '<i>' . __('Issue created') . '</i>'; if (isset($include_details) && $include_details) { echo '<div class="timeline_inline_details">' . nl2br(__e($issue->getDescription())) . '</div>'; } break; case \thebuggenie\core\entities\tables\Log::LOG_COMMENT: $comment = \thebuggenie\core\entities\Comment::getB2DBTable()->selectById((int) $log_action['text']); echo '<div class="timeline_inline_details">'; echo nl2br(tbg_truncateText(tbg_decodeUTF8($comment->getContent()))); echo '</div>'; break; case \thebuggenie\core\entities\tables\Log::LOG_ISSUE_CLOSE: echo '<span class="issue_closed"><i>' . __('Issue closed %text', array('%text' => $log_action['text'])) . '</i></span>'; break; case \thebuggenie\core\entities\tables\Log::LOG_ISSUE_REOPEN: echo '<i>' . __('Issue reopened') . '</i>'; break; case \thebuggenie\core\entities\tables\Log::LOG_ISSUE_UPDATE: echo '<i>' . $log_action['text'] . '</i>'; break; case \thebuggenie\core\entities\tables\Log::LOG_ISSUE_PAIN_BUG_TYPE: echo '<i>' . __('Triaged bug type: %text', array('%text' => $log_action['text'])) . '</i>';
</div> </div> <?php } ?> <div class="faded_out comments_none" id="comments_none" <?php if (\thebuggenie\core\entities\Comment::countComments($target_id, $target_type) != 0) { ?> style="display: none;"<?php } ?> ><?php echo __('There are no comments'); ?> </div> <div id="comments_box"> <?php foreach (\thebuggenie\core\entities\Comment::getComments($target_id, $target_type, \b2db\Criteria::SORT_DESC) as $comment) { ?> <?php $options = compact('comment', 'comment_count_div', 'mentionable_target_type'); if (isset($issue)) { $options['issue'] = $issue; } include_component('main/comment', $options); ?> <?php } ?> </div>
public function componentDashboardViewRecentComments() { $this->comments = entities\Comment::getRecentCommentsByAuthor($this->getUser()->getID()); }
public function countUserComments() { if ($this->_num_user_comments === null) { $this->_num_user_comments = Comment::countComments($this->getID(), Comment::TYPE_ISSUE, false); } return (int) $this->_num_user_comments; }
');"><?php echo __('Attach a file'); ?> </button> <?php } ?> </h4> <?php include_component('publish/attachments', array('article' => $article, 'attachments' => $attachments)); ?> </div> <div id="article_comments"> <h4> <?php echo __('Article comments (%count)', array('%count' => \thebuggenie\core\entities\Comment::countComments($article->getID(), \thebuggenie\core\entities\Comment::TYPE_ARTICLE))); ?> <?php if ($tbg_user->canPostComments() && (\thebuggenie\core\framework\Context::isProjectContext() && !\thebuggenie\core\framework\Context::getCurrentProject()->isArchived() || !\thebuggenie\core\framework\Context::isProjectContext())) { ?> <button id="comment_add_button" class="button button-silver" onclick="TBG.Main.Comment.showPost();"><?php echo __('Post comment'); ?> </button> <?php } ?> </h4> <?php include_component('main/comments', array('target_id' => $article->getID(), 'mentionable_target_type' => 'article', 'target_type' => \thebuggenie\core\entities\Comment::TYPE_ARTICLE, 'show_button' => false, 'comment_count_div' => 'article_comment_count', 'forward_url' => make_url('publish_article', array('article_name' => $article->getName())))); ?>
public function runAddComment(framework\Request $request) { $i18n = framework\Context::getI18n(); $comment_applies_type = $request['comment_applies_type']; try { if (!$this->getUser()->canPostComments()) { throw new \Exception($i18n->__('You are not allowed to do this')); } if (!trim($request['comment_body'])) { throw new \Exception($i18n->__('The comment must have some content')); } $comment = new entities\Comment(); $comment->setContent($request->getParameter('comment_body', null, false)); $comment->setPostedBy($this->getUser()->getID()); $comment->setTargetID($request['comment_applies_id']); $comment->setTargetType($request['comment_applies_type']); $comment->setReplyToComment($request['reply_to_comment_id']); $comment->setModuleName($request['comment_module']); $comment->setIsPublic((bool) $request['comment_visibility']); $comment->setSyntax($request['comment_body_syntax']); $comment->save(); if ($comment_applies_type == entities\Comment::TYPE_ISSUE) { $issue = entities\Issue::getB2DBTable()->selectById((int) $request['comment_applies_id']); if (!$request->isAjaxCall() || $request['comment_save_changes']) { $issue->setSaveComment($comment); $issue->save(); } else { \thebuggenie\core\framework\Event::createNew('core', 'thebuggenie\\core\\entities\\Comment::createNew', $comment, compact('issue'))->trigger(); } } elseif ($comment_applies_type == entities\Comment::TYPE_ARTICLE) { $article = \thebuggenie\modules\publish\entities\tables\Articles::getTable()->selectById((int) $request['comment_applies_id']); \thebuggenie\core\framework\Event::createNew('core', 'thebuggenie\\core\\entities\\Comment::createNew', $comment, compact('article'))->trigger(); } switch ($comment_applies_type) { case entities\Comment::TYPE_ISSUE: $issue = entities\Issue::getB2DBTable()->selectById($request['comment_applies_id']); framework\Context::setCurrentProject($issue->getProject()); $comment_html = $this->getComponentHTML('main/comment', array('comment' => $comment, 'issue' => $issue, 'mentionable_target_type' => 'issue', 'comment_count_div' => 'viewissue_comment_count')); break; case entities\Comment::TYPE_ARTICLE: $comment_html = $this->getComponentHTML('main/comment', array('comment' => $comment, 'mentionable_target_type' => 'article', 'comment_count_div' => 'article_comment_count')); break; default: $comment_html = 'OH NO!'; } } catch (\Exception $e) { if ($request->isAjaxCall()) { $this->getResponse()->setHttpStatus(400); return $this->renderJSON(array('error' => $e->getMessage())); } else { framework\Context::setMessage('comment_error', $e->getMessage()); framework\Context::setMessage('comment_error_body', $request['comment_body']); framework\Context::setMessage('comment_error_visibility', $request['comment_visibility']); } } if ($request->isAjaxCall()) { return $this->renderJSON(array('title' => $i18n->__('Comment added!'), 'comment_data' => $comment_html, 'continue_url' => $request['forward_url'], 'commentcount' => entities\Comment::countComments($request['comment_applies_id'], $request['comment_applies_type']))); } if (isset($comment) && $comment instanceof entities\Comment) { $this->forward($request['forward_url'] . "#comment_{$request['comment_applies_type']}_{$request['comment_applies_id']}_{$comment->getID()}"); } else { $this->forward($request['forward_url']); } }
?> ","<?php echo $issue->getVotes(); ?> ","<?php echo str_replace('"', '\\"', html_entity_decode($issue->getDescription(), ENT_QUOTES, \thebuggenie\core\framework\Context::getI18n()->getCharset())); ?> ", "<?php echo str_replace('"', '\\"', html_entity_decode($reproductionsteps, ENT_QUOTES, \thebuggenie\core\framework\Context::getI18n()->getCharset())); ?> ", " <?php if ($issue->getCommentCount() == 0) { echo '-'; } foreach (\thebuggenie\core\entities\Comment::getComments($issue->getFormattedIssueNo(), '1') as $comment) { ?> <?php $options = compact('comment', 'comment_count_div'); if (isset($issue)) { echo $comment->getPostedBy() . ' : ' . $comment->getContent() . ' '; } ?> <?php } ?> " <?php } }
</div> </div> <?php } ?> <div class="faded_out comments_none" id="comments_none" <?php if (\thebuggenie\core\entities\Comment::countComments($target_id, $target_type) != 0) { ?> style="display: none;"<?php } ?> ><?php echo __('There are no comments'); ?> </div> <div id="comments_box"> <?php foreach (\thebuggenie\core\entities\Comment::getComments($target_id, $target_type) as $comment) { ?> <?php $options = compact('comment', 'comment_count_div'); if (isset($issue)) { $options['issue'] = $issue; } include_component('main/comment', $options); ?> <?php } ?> </div>