diff --git a/Topcoder/class.topcoder.plugin.php b/Topcoder/class.topcoder.plugin.php index af258f1..18391ae 100644 --- a/Topcoder/class.topcoder.plugin.php +++ b/Topcoder/class.topcoder.plugin.php @@ -284,6 +284,8 @@ public function gdn_auth_startAuthenticator_handler() { if(!c('Garden.Installed')) { return; } + self::log('Embedded Settings', ['Garden.Embed.Allow' => c('Garden.Embed.Allow')]); + self::log('Cache', ['Active Cache' => Gdn_Cache::activeCache(), 'Type' =>Gdn::cache()->type()]); if(!$this->isDefault()) { @@ -895,7 +897,7 @@ function gdn_dispatcher_beforeControllerMethod_handler($sender, $args){ } } else if($args['Controller'] instanceof GroupController) { if (array_key_exists('groupid', $methodArgs)) { - $groupID = (int) $methodArgs['groupid']; + $groupID = self::convertToGroupID($methodArgs['groupid']); } } else if($args['Controller'] instanceof PostController) { if (array_key_exists('discussionid', $methodArgs)) { @@ -932,19 +934,68 @@ function gdn_dispatcher_beforeControllerMethod_handler($sender, $args){ $group = $groupModel->getByGroupID($groupID); $category = $categoryModel->getByCode($group->ChallengeID); $categoryID= val('CategoryID', $category); - Gdn::controller()->setData('Breadcrumbs.Options.GroupCategoryID', $categoryID); - Gdn::controller()->setData('Breadcrumbs.Options.GroupID', $groupID); - Gdn::controller()->setData('Breadcrumbs.Options.ChallengeID', $group->ChallengeID); + $controller = $args['Controller']; + $controller->setData('BreadcrumbsOptionsGroupCategoryID', $categoryID); + $controller->setData('BreadcrumbsOptionsGroupID', $groupID); + $controller->setData('BreadcrumbsOptionsChallengeID', $group->ChallengeID); if ($group->ChallengeID) { - $this->setTopcoderProjectData($args['Controller'], $group->ChallengeID); + $this->setTopcoderProjectData($controller, $group->ChallengeID); } } } + private static function convertToGroupID($id) { + if(is_numeric($id) && $id > 0) { + return $id; + } + + if(self::isValidUuid($id) === true) { + $categoryModel = new CategoryModel(); + $category = $categoryModel->getByCode($id); + return val('GroupID', $category, 0); + } + + return 0; + } + + private static function isValidUuid($uuid) { + if(!is_string($uuid)) { + return false; + } + if (!\preg_match('/^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$/', $uuid)) { + return false; + } + return true; + } + + public function base_beforeBuildBreadcrumbs_handler($sender, $args) { + if(Gdn::session()->isValid()) { + $showFullBreadcrumbs = & $args['ShowFullBreadcrumbs']; + //FIX Issues-652: Client Manager - no navigation when embedded + $showFullBreadcrumbs = !hideInMFE(); + } + } /** * Add scripts. Add script to hide iPhone browser bar on pageload. */ public function base_render_before($sender) { + if(isset($_SERVER['HTTP_REFERER'])) { + $url = $_SERVER['HTTP_REFERER']; + parse_str( parse_url( $url, PHP_URL_QUERY), $array ); + $embedType = $array['mbed_type']; + if($embedType == 'mfe') { + $sender->addDefinition('MFEEmbedded', '1'); + $sender->MasterView = 'mfe'; + // logMessage(__FILE__,__LINE__,'TopcoderPlugin','base_render_before',"Use Embed Master Template due to HTTP_REFERER".$url); + } + } + + // Force view options + if(getIncomingValue('embed_type') == 'mfe') { + $sender->addDefinition('MFEEmbedded', '1'); + $sender->MasterView = 'mfe'; + // logMessage(__FILE__,__LINE__,'TopcoderPlugin','base_render_before',"Use Embed Master Template due to Query Param"); + } if (is_object($sender->Head)) { $sender->Head->addString($this->getJS()); } @@ -1574,6 +1625,7 @@ public function getChallenge($challengeId) { $cachedChallenge['StartDate'] = $startDate; $cachedChallenge['EndDate'] = $endDate; $cachedChallenge['Track'] = $challenge->track; + $cachedChallenge['IsSelfService'] = $challenge->legacy->selfService; $termIDs = array_column($challenge->terms, 'id'); $NDA_UUID = c('Plugins.Topcoder.NDA_UUID'); $cachedChallenge['IsNDA'] = in_array($NDA_UUID, $termIDs); @@ -1750,6 +1802,39 @@ private static function isTopcoderAdmin($topcoderRoles = false) { return false; } + /** + * Check if the list of Topcoder roles includes 'Client Manager' role + * @return bool true, if the list of Topcoder roles includes 'Client Manager' + */ + public static function isTopcoderClientManager() { + if(!Gdn::session()->isValid()) { + return false; + } + $topcoderRoles = Gdn::controller()->data("ChallengeCurrentUserProjectRoles"); + if($topcoderRoles) { + $lowerRoleNames = array_map('strtolower', $topcoderRoles); + return count(array_intersect($lowerRoleNames, ["client manager"])) > 0; + } + + return false; + } + + /** + * Check if the challenge has self-service flag + * @return bool true, if the challenge has self-service flag + */ + public static function isChallengeSelfService() { + if(!Gdn::session()->isValid()) { + return false; + } + $challenge = Gdn::controller()->data("Challenge"); + if($challenge) { + return $challenge['IsSelfService']; + } + + return false; + } + /** * Get Topcoder Role names * @param false $topcoderRoles @@ -1871,7 +1956,7 @@ private function setTopcoderProjectData($sender, $challengeID) { // if($sender->GroupModel) { // $sender->GroupModel->setCurrentUserTopcoderProjectRoles($currentProjectRoles); // } - self::log('setTopcoderProjectData', ['ChallengeID' => $challengeID, 'currentUser' => $currentProjectRoles, + self::log('setTopcoderProjectData', ['ChallengeID' => $challengeID, 'CurrentUserProjectRoles' => $currentProjectRoles, 'Topcoder Resources' => $resources , 'Topcoder RoleResources' => $roleResources, 'challenge' =>$challenge]); } @@ -1955,11 +2040,21 @@ private static function topcoderUserCache($userFields) { return $cached; } - // TODO: Debugging issues-108 + // Support Micro-frontends forums app public function gdn_dispatcher_beforeDispatch_handler($sender, $args) { - self::log('gdn_dispatcher_beforeDispatch_handler', [ + $mfeUrl = c("Garden.Embed.RemoteUrl"); + $isEmbedded = (bool) c('Garden.Embed.Allow', false); + + $data = array( + 'Garden.Embed.Allow' => $isEmbedded, + 'MFEUrl' => $mfeUrl, + 'Request(current fullPath)' => Gdn::request()->getFullPath(), + 'Request(pathAndQuery)' => Gdn::request()->pathAndQuery(), + 'Request(Method)'=> Gdn::request()->getMethod(), 'Permissions' => Gdn::session()->getPermissionsArray(), - ]); + ); + // logMessage(__FILE__, __LINE__, 'TopcoderPlugin', "Data", json_encode($data )); + // self::log('gdn_dispatcher_beforeDispatch_handler', $data); } // Topcoder Cache is used for caching Topcoder Users by handle. @@ -2293,6 +2388,103 @@ public function profileController_preferences_create($sender, $userReference = ' $sender->_setBreadcrumbs($sender->data('Title'), $sender->canonicalUrl()); $sender->render(); } + + // All notified users have been added in an activity. This called before adding an activity in an activity Queue and sending+saving it in DB + public function activityModel_BeforeCheckPreference_handler($sender, $args) { + $activity = &$args['Data']; + $notifyUserID = val('NotifyUserID', $activity); + $userModel = new UserModel(); + $user = $userModel->getID($notifyUserID); + $data = $activity['Data']; + $challengeID = $data['ChallengeID']; + if($challengeID) { + $activityType = $activity['RecordType']; + if($activityType == 'Discussion' || $activityType == 'Comment') { + $resources = $this->getChallengeResources($challengeID); + $roleResources = $this->getRoleResources(); + $currentProjectRoles = $this->getTopcoderProjectRoles($user, $resources, $roleResources); + if($currentProjectRoles) { + $currentProjectRoles = array_map('strtolower', $currentProjectRoles); + $isClientManager = count(array_intersect($currentProjectRoles, ["client manager"])) > 0; + if ($isClientManager) { + $recordID = $activity['RecordID']; + $category = CategoryModel::categories($challengeID); + $categoryName = val('Name', $category); + $userModel = new UserModel(); + $discussionModel = new DiscussionModel(); + if ($activityType == 'Discussion') { + $discussion = $discussionModel->getID($recordID); + $message = Gdn::formatService()->renderQuote(val('Body', $discussion), val('Format', $discussion)); + $author = $userModel->getID(val('InsertUserID', $discussion)); + $dateInserted = Gdn_Format::dateFull(val('DateInserted',$discussion)); + // $categoryBreadcrumbs = array_column(array_values(CategoryModel::getAncestors(val('CategoryID',$discussion))), 'Name'); + + $activity['Story'] = + '
Hi there,
' . + 'A new message has been posted on the discussion tied to your Topcoder Work "' . $categoryName . '" ' . + 'which was updated ' . $dateInserted . ' by ' . $author->Name . ':
' . + 'Discussion: ' . val('Name', $discussion) . '
' . + 'Author: ' . val('Name', $author) . '
' . + // 'Category: ' . implode('›', $categoryBreadcrumbs) . '
' . + 'Message: ' . $message . '
' . + 'To answer, click "Open Discussion" below to be taken to this discussion.
+ Please do not reply to this email.
+ Thank you!
+ The Topcoder Team
Hi there,
' . + 'A new message has been posted on the discussion tied to your Topcoder Work "' . $categoryName . '" ' . + 'which was updated ' . $commentDateInserted . ' by ' . val('Name',$commentAuthor) . ':
' . + 'Message:'.'
' . + $commentStory . + 'Original Message (by '.$parentCommentAuthor->Name.' ):
'. + '' . + $parentCommentStory. + '
' . + 'To answer, click "Open Discussion" below to be taken to this discussion.
+Please do not reply to this email.
+Thank you!
+The Topcoder Team