From 8897d38f529d1095c6ebca76f668efd0721bebc7 Mon Sep 17 00:00:00 2001 From: Bogdanova Olga Date: Wed, 1 Dec 2021 22:45:12 +0300 Subject: [PATCH 01/16] MFE-issues-9:redirect to mf forums --- Topcoder/class.topcoder.plugin.php | 71 ++++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 3 deletions(-) diff --git a/Topcoder/class.topcoder.plugin.php b/Topcoder/class.topcoder.plugin.php index af258f1..0d034c5 100644 --- a/Topcoder/class.topcoder.plugin.php +++ b/Topcoder/class.topcoder.plugin.php @@ -187,6 +187,10 @@ public function settingsController_topcoder_create($sender) { $cf->form()->validateRule('Plugins.Topcoder.RoleApiURI', 'ValidateRequired', t('You must provide Role API URI.')); $cf->form()->validateRule('Plugins.Topcoder.ResourceRolesApiURI', 'ValidateRequired', t('You must provide Resource Roles API URI.')); $cf->form()->validateRule('Plugins.Topcoder.ResourcesApiURI', 'ValidateRequired', t('You must provide Resources API URI.')); + $isEmbedded = (bool) c('Garden.Embed.Allow'); + if ($isEmbedded) { + $cf->form()->validateRule('Plugins.Topcoder.MicroFrontendsForumsURL', 'ValidateRequired', t('You must provide Micro-Frontends Forums URL.')); + } $cf->form()->validateRule('Plugins.Topcoder.MemberProfileURL', 'ValidateRequired', t('You must provide Member Profile URL.')); if($cf->form()->getFormValue('Plugins.Topcoder.UseTopcoderAuthToken') == 1) { $cf->form()->validateRule('AuthenticationProvider.SignInUrl', 'ValidateRequired', t('You must provide SignIn URL.')); @@ -209,6 +213,7 @@ public function settingsController_topcoder_create($sender) { 'Plugins.Topcoder.RoleApiURI' => ['Control' => 'TextBox', 'Default' => '', 'Description' => 'Topcoder Role API URI'], 'Plugins.Topcoder.ResourceRolesApiURI' => ['Control' => 'TextBox', 'Default' => '', 'Description' => 'Topcoder Resource Roles API URI'], 'Plugins.Topcoder.ResourcesApiURI' => ['Control' => 'TextBox', 'Default' => '', 'Description' => 'Topcoder Resources API URI'], + 'Plugins.Topcoder.MicroFrontendsForumsURL' => ['Control' => 'TextBox', 'Default' => '', 'Description' => 'Topcoder Micro-Frontends Forums URL'], 'Plugins.Topcoder.MemberProfileURL' => ['Control' => 'TextBox', 'Default' => '', 'Description' => 'Topcoder Member Profile URL'], 'Plugins.Topcoder.UseTopcoderAuthToken' => ['Control' => 'CheckBox', 'Default' => false, 'Description' => 'Use Topcoder access token to log in to Vanilla'], 'AuthenticationProvider.SignInUrl' => ['Control' => 'TextBox', 'Default' => '', 'Description' => 'Topcoder SignIn URL'], @@ -284,6 +289,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()) { @@ -1955,11 +1962,69 @@ 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("Plugins.Topcoder.MicroFrontendsForumsURL"); + $deliveryType = Gdn::request()->getQueryItem("DeliveryType"); + $remoteUrl = Gdn::request()->getQueryItem("remote")? urldecode(Gdn::request()->getQueryItem("remote")):""; + $isEmbedded = (bool) c('Garden.Embed.Allow', false); + + $data = array( + 'Garden.Embed.Allow' => c('Garden.Embed.Allow'), + 'MFEUrl' => $mfeUrl, + 'RemoteQueryParam("remote")' => $remoteUrl, + 'RemoteQueryParam("remote") == mfeUrl' => strcmp($mfeUrl, $remoteUrl) === 0, + 'Request(current fullPath)' => Gdn::request()->getFullPath(), + 'Request(current url)'=> Gdn::request()->getUrl(), + 'currentUrl == mfeUrl' => strcmp($mfeUrl, Gdn::request()->getUrl()) === 0, + 'Request(pathAndQuery)' => Gdn::request()->pathAndQuery(), + 'Request(Method)'=> Gdn::request()->getMethod(), + 'Request(DeliveryType)' =>Gdn::request()->getQueryItem("DeliveryType"), + 'Request(DeliveryType calculated)'=> !($deliveryType == "" || $deliveryType == DELIVERY_TYPE_ALL), 'Permissions' => Gdn::session()->getPermissionsArray(), - ]); + ); + logMessage(__FILE__, __LINE__, 'TopcoderPlugin', "Data", json_encode($data )); + + self::log('gdn_dispatcher_beforeDispatch_handler', $data); + + + if(!$isEmbedded) { + return; + } + + if(Gdn::request()->getMethod() != Gdn::request()::METHOD_GET) { + return; + } + if(stringBeginsWith(Gdn::request()->getPath(), '/api/') || stringBeginsWith(Gdn::request()->getPath(), '/dashboard') + || stringBeginsWith(Gdn::request()->getPath(), '/settings') + || stringBeginsWith(Gdn::request()->getPath(), '/embed/') + || stringBeginsWith(Gdn::request()->getPath(), '/social/') + || stringBeginsWith(Gdn::request()->getPath(), '/vanilla/') + || stringBeginsWith(Gdn::request()->getPath(), '/utility/') || stringBeginsWith(Gdn::request()->getPath(), '/notifications/') + || stringBeginsWith(Gdn::request()->getPath(), '/js/') + || stringBeginsWith(Gdn::request()->getPath(), '/applications/') + || stringBeginsWith(Gdn::request()->getPath(), '/themes/') + || stringBeginsWith(Gdn::request()->getPath(), '/dist/') + || stringBeginsWith(Gdn::request()->getPath(), '/css/') + || stringBeginsWith(Gdn::request()->getPath(), '/plugins/') + || stringBeginsWith(Gdn::request()->getPath(), '/resources/')) { + return; + } + + if(!($deliveryType == "" || $deliveryType == DELIVERY_TYPE_ALL)) { + return; + } + if(stringBeginsWith(Gdn::request()->getUrl(), $mfeUrl)) { + return; + } + + if(strlen($remoteUrl) > 0){ + return; + } else { + safeHeader("HTTP/1.1 301 Moved Permanently"); + safeHeader("Location: " . url($mfeUrl."/#/" . Gdn::request()->pathAndQuery())); + exit(); + } } // Topcoder Cache is used for caching Topcoder Users by handle. From 0a522f60a5879e61ce20ec314a79e77616812a68 Mon Sep 17 00:00:00 2001 From: Bogdanova Olga Date: Sat, 4 Dec 2021 19:50:46 +0300 Subject: [PATCH 02/16] mfe-issues-8: Rollback some changes --- Topcoder/class.topcoder.plugin.php | 61 ++---------------------------- 1 file changed, 4 insertions(+), 57 deletions(-) diff --git a/Topcoder/class.topcoder.plugin.php b/Topcoder/class.topcoder.plugin.php index 0d034c5..522bdbf 100644 --- a/Topcoder/class.topcoder.plugin.php +++ b/Topcoder/class.topcoder.plugin.php @@ -187,10 +187,6 @@ public function settingsController_topcoder_create($sender) { $cf->form()->validateRule('Plugins.Topcoder.RoleApiURI', 'ValidateRequired', t('You must provide Role API URI.')); $cf->form()->validateRule('Plugins.Topcoder.ResourceRolesApiURI', 'ValidateRequired', t('You must provide Resource Roles API URI.')); $cf->form()->validateRule('Plugins.Topcoder.ResourcesApiURI', 'ValidateRequired', t('You must provide Resources API URI.')); - $isEmbedded = (bool) c('Garden.Embed.Allow'); - if ($isEmbedded) { - $cf->form()->validateRule('Plugins.Topcoder.MicroFrontendsForumsURL', 'ValidateRequired', t('You must provide Micro-Frontends Forums URL.')); - } $cf->form()->validateRule('Plugins.Topcoder.MemberProfileURL', 'ValidateRequired', t('You must provide Member Profile URL.')); if($cf->form()->getFormValue('Plugins.Topcoder.UseTopcoderAuthToken') == 1) { $cf->form()->validateRule('AuthenticationProvider.SignInUrl', 'ValidateRequired', t('You must provide SignIn URL.')); @@ -213,7 +209,6 @@ public function settingsController_topcoder_create($sender) { 'Plugins.Topcoder.RoleApiURI' => ['Control' => 'TextBox', 'Default' => '', 'Description' => 'Topcoder Role API URI'], 'Plugins.Topcoder.ResourceRolesApiURI' => ['Control' => 'TextBox', 'Default' => '', 'Description' => 'Topcoder Resource Roles API URI'], 'Plugins.Topcoder.ResourcesApiURI' => ['Control' => 'TextBox', 'Default' => '', 'Description' => 'Topcoder Resources API URI'], - 'Plugins.Topcoder.MicroFrontendsForumsURL' => ['Control' => 'TextBox', 'Default' => '', 'Description' => 'Topcoder Micro-Frontends Forums URL'], 'Plugins.Topcoder.MemberProfileURL' => ['Control' => 'TextBox', 'Default' => '', 'Description' => 'Topcoder Member Profile URL'], 'Plugins.Topcoder.UseTopcoderAuthToken' => ['Control' => 'CheckBox', 'Default' => false, 'Description' => 'Use Topcoder access token to log in to Vanilla'], 'AuthenticationProvider.SignInUrl' => ['Control' => 'TextBox', 'Default' => '', 'Description' => 'Topcoder SignIn URL'], @@ -1964,67 +1959,19 @@ private static function topcoderUserCache($userFields) { // Support Micro-frontends forums app public function gdn_dispatcher_beforeDispatch_handler($sender, $args) { - $mfeUrl = c("Plugins.Topcoder.MicroFrontendsForumsURL"); - $deliveryType = Gdn::request()->getQueryItem("DeliveryType"); - $remoteUrl = Gdn::request()->getQueryItem("remote")? urldecode(Gdn::request()->getQueryItem("remote")):""; + $mfeUrl = c("Garden.Embed.RemoteUrl"); $isEmbedded = (bool) c('Garden.Embed.Allow', false); $data = array( - 'Garden.Embed.Allow' => c('Garden.Embed.Allow'), + 'Garden.Embed.Allow' => $isEmbedded, 'MFEUrl' => $mfeUrl, - 'RemoteQueryParam("remote")' => $remoteUrl, - 'RemoteQueryParam("remote") == mfeUrl' => strcmp($mfeUrl, $remoteUrl) === 0, 'Request(current fullPath)' => Gdn::request()->getFullPath(), - 'Request(current url)'=> Gdn::request()->getUrl(), - 'currentUrl == mfeUrl' => strcmp($mfeUrl, Gdn::request()->getUrl()) === 0, 'Request(pathAndQuery)' => Gdn::request()->pathAndQuery(), 'Request(Method)'=> Gdn::request()->getMethod(), - 'Request(DeliveryType)' =>Gdn::request()->getQueryItem("DeliveryType"), - 'Request(DeliveryType calculated)'=> !($deliveryType == "" || $deliveryType == DELIVERY_TYPE_ALL), 'Permissions' => Gdn::session()->getPermissionsArray(), - ); + ); logMessage(__FILE__, __LINE__, 'TopcoderPlugin', "Data", json_encode($data )); - - self::log('gdn_dispatcher_beforeDispatch_handler', $data); - - - if(!$isEmbedded) { - return; - } - - if(Gdn::request()->getMethod() != Gdn::request()::METHOD_GET) { - return; - } - if(stringBeginsWith(Gdn::request()->getPath(), '/api/') || stringBeginsWith(Gdn::request()->getPath(), '/dashboard') - || stringBeginsWith(Gdn::request()->getPath(), '/settings') - || stringBeginsWith(Gdn::request()->getPath(), '/embed/') - || stringBeginsWith(Gdn::request()->getPath(), '/social/') - || stringBeginsWith(Gdn::request()->getPath(), '/vanilla/') - || stringBeginsWith(Gdn::request()->getPath(), '/utility/') || stringBeginsWith(Gdn::request()->getPath(), '/notifications/') - || stringBeginsWith(Gdn::request()->getPath(), '/js/') - || stringBeginsWith(Gdn::request()->getPath(), '/applications/') - || stringBeginsWith(Gdn::request()->getPath(), '/themes/') - || stringBeginsWith(Gdn::request()->getPath(), '/dist/') - || stringBeginsWith(Gdn::request()->getPath(), '/css/') - || stringBeginsWith(Gdn::request()->getPath(), '/plugins/') - || stringBeginsWith(Gdn::request()->getPath(), '/resources/')) { - return; - } - - if(!($deliveryType == "" || $deliveryType == DELIVERY_TYPE_ALL)) { - return; - } - if(stringBeginsWith(Gdn::request()->getUrl(), $mfeUrl)) { - return; - } - - if(strlen($remoteUrl) > 0){ - return; - } else { - safeHeader("HTTP/1.1 301 Moved Permanently"); - safeHeader("Location: " . url($mfeUrl."/#/" . Gdn::request()->pathAndQuery())); - exit(); - } + // self::log('gdn_dispatcher_beforeDispatch_handler', $data); } // Topcoder Cache is used for caching Topcoder Users by handle. From ef6270f5e8d06c843b890879bd613aa1076548a4 Mon Sep 17 00:00:00 2001 From: Bogdanova Olga Date: Thu, 6 Jan 2022 23:09:34 +0300 Subject: [PATCH 03/16] Issues-648: disable links for MFE --- Topcoder/class.topcoder.plugin.php | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/Topcoder/class.topcoder.plugin.php b/Topcoder/class.topcoder.plugin.php index 522bdbf..f32afbf 100644 --- a/Topcoder/class.topcoder.plugin.php +++ b/Topcoder/class.topcoder.plugin.php @@ -947,6 +947,23 @@ function gdn_dispatcher_beforeControllerMethod_handler($sender, $args){ * 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()); } @@ -2450,7 +2467,7 @@ function userPhoto($user, $options = []) { $isTopcoderAdmin = val('IsAdmin', $topcoderProfile); $photoUrl = isset($photoUrl) && !empty(trim($photoUrl)) ? $photoUrl: UserModel::getDefaultAvatarUrl(); $isUnlickableUser = TopcoderPlugin::isUnclickableUser($name); - $href = (val('NoLink', $options)) || $isUnlickableUser ? '' : ' href="'.url($userLink).'"'; + $href = (val('NoLink', $options)) || $isUnlickableUser || getIncomingValue('embed_type') == 'mfe' ? '' : ' href="'.url($userLink).'"'; Gdn::controller()->EventArguments['User'] = $user; Gdn::controller()->EventArguments['Title'] =& $title; @@ -2540,7 +2557,7 @@ function userAnchor($user, $cssClass = null, $options = null) { } // Go to Topcoder user profile link instead of Vanilla profile link - $isUnlickableUser = TopcoderPlugin::isUnclickableUser($name); + $isUnlickableUser = getIncomingValue('embed_type') == 'mfe' || TopcoderPlugin::isUnclickableUser($name); $userUrl = $isUnlickableUser? '#' : topcoderUserUrl($user, $px); $topcoderProfile = TopcoderPlugin::getTopcoderUser($userID); From 7aec19f391f5037972fe665f275a1c9f2ac93d44 Mon Sep 17 00:00:00 2001 From: Bogdanova Olga Date: Tue, 11 Jan 2022 21:59:24 +0300 Subject: [PATCH 04/16] Issues-652: Client Manger - no navigation when embedded --- Topcoder/class.topcoder.plugin.php | 56 +++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 4 deletions(-) diff --git a/Topcoder/class.topcoder.plugin.php b/Topcoder/class.topcoder.plugin.php index f32afbf..bbc816a 100644 --- a/Topcoder/class.topcoder.plugin.php +++ b/Topcoder/class.topcoder.plugin.php @@ -943,6 +943,14 @@ function gdn_dispatcher_beforeControllerMethod_handler($sender, $args){ } } + + 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. */ @@ -1769,6 +1777,21 @@ private static function isTopcoderAdmin($topcoderRoles = false) { return false; } + /** + * Check if the list of Topcoder roles includes 'Client Manager' role + * @param false $topcoderRoles + * @return bool true, if the list of Topcoder roles includes 'Client Manager' + */ + private static function isTopcoderClientManager($topcoderRoles = false) { + if($topcoderRoles) { + $roleNames = array_column($topcoderRoles, 'roleName'); + $lowerRoleNames = array_map('strtolower', $roleNames); + return count(array_intersect($lowerRoleNames, ["client manager"])) > 0; + } + + return false; + } + /** * Get Topcoder Role names * @param false $topcoderRoles @@ -1801,6 +1824,7 @@ private static function loadTopcoderUserDetails($vanillaUser) { $topcoderRoles = self::loadTopcoderRoles($topcoderProfile->userId); $cachedUser['Roles'] = self::getTopcoderRoleNames($topcoderRoles); $cachedUser['IsAdmin'] = self::isTopcoderAdmin($topcoderRoles); + $cachedUser['IsClientManager'] = self::isTopcoderClientManager($topcoderRoles); $topcoderRating = self::loadTopcoderRating($username); //loaded by handle if($topcoderRating) { $cachedUser['Rating'] = $topcoderRating; @@ -2066,6 +2090,7 @@ private static function loadTopcoderUserDetailsByHandle($topcoderHandle) { $topcoderRoles = self::loadTopcoderRoles($topcoderProfile->userId); $cachedUser['Roles'] = self::getTopcoderRoleNames($topcoderRoles); $cachedUser['IsAdmin'] = self::isTopcoderAdmin($topcoderRoles); + $cachedUser['IsClientManager'] = self::isTopcoderClientManager($topcoderRoles); $topcoderRating = self::loadTopcoderRating($topcoderHandle); //loaded by handle if($topcoderRating) { $cachedUser['Rating'] = $topcoderRating; @@ -2465,9 +2490,11 @@ function userPhoto($user, $options = []) { } $isTopcoderAdmin = val('IsAdmin', $topcoderProfile); + $isTopcoderClientManager = val('IsClientManager', $topcoderProfile); $photoUrl = isset($photoUrl) && !empty(trim($photoUrl)) ? $photoUrl: UserModel::getDefaultAvatarUrl(); $isUnlickableUser = TopcoderPlugin::isUnclickableUser($name); - $href = (val('NoLink', $options)) || $isUnlickableUser || getIncomingValue('embed_type') == 'mfe' ? '' : ' href="'.url($userLink).'"'; + $href = (val('NoLink', $options)) || $isUnlickableUser || + ($isTopcoderClientManager && getIncomingValue('embed_type') == 'mfe') ? '' : ' href="'.url($userLink).'"'; Gdn::controller()->EventArguments['User'] = $user; Gdn::controller()->EventArguments['Title'] =& $title; @@ -2556,11 +2583,14 @@ function userAnchor($user, $cssClass = null, $options = null) { $attributes['title'] = $options['title']; } + $topcoderProfile = TopcoderPlugin::getTopcoderUser($userID); + // Go to Topcoder user profile link instead of Vanilla profile link - $isUnlickableUser = getIncomingValue('embed_type') == 'mfe' || TopcoderPlugin::isUnclickableUser($name); + $isTopcoderClientManager = val('IsClientManager', $topcoderProfile); + $isUnlickableUser = ( $isTopcoderClientManager && getIncomingValue('embed_type') == 'mfe') || TopcoderPlugin::isUnclickableUser($name); $userUrl = $isUnlickableUser? '#' : topcoderUserUrl($user, $px); - $topcoderProfile = TopcoderPlugin::getTopcoderUser($userID); + $topcoderRating = val('Rating',$topcoderProfile, false); if($topcoderRating != false || $topcoderRating == null) { $coderStyles = TopcoderPlugin::getRatingCssClass($topcoderRating); @@ -2867,4 +2897,22 @@ function watchingSorts($extraClasses = '') { 'Sort' ); } -} \ No newline at end of file +} + +if (!function_exists('hideInMFE')) { + function hideInMFE() { + if (!Gdn::session()->isValid()) { + return false; + } + //FIX Issues-652: Client Manager - no navigation when embedded + $isMFE = getIncomingValue('embed_type') == 'mfe'; + $user = Gdn::userModel()->getID(Gdn::session()->UserID, DATASET_TYPE_ARRAY); + $topcoderProfile = TopcoderPlugin::getTopcoderUser($user); + $isTopcoderClientManager = val('IsClientManager', $topcoderProfile); + + if ($isMFE && $isTopcoderClientManager) { + return true; + } + return false; + } +} From be8d124dfd5e4b30a00be13415ab359757fa1caa Mon Sep 17 00:00:00 2001 From: Bogdanova Olga Date: Mon, 17 Jan 2022 14:52:31 +0300 Subject: [PATCH 05/16] Issues-652: fixed Client Manager role --- Topcoder/class.topcoder.plugin.php | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/Topcoder/class.topcoder.plugin.php b/Topcoder/class.topcoder.plugin.php index bbc816a..8bc8a60 100644 --- a/Topcoder/class.topcoder.plugin.php +++ b/Topcoder/class.topcoder.plugin.php @@ -1782,10 +1782,13 @@ private static function isTopcoderAdmin($topcoderRoles = false) { * @param false $topcoderRoles * @return bool true, if the list of Topcoder roles includes 'Client Manager' */ - private static function isTopcoderClientManager($topcoderRoles = false) { + public static function isTopcoderClientManager() { + if(!Gdn::session()->isValid()) { + return false; + } + $topcoderRoles = Gdn::controller()->data("ChallengeCurrentUserProjectRoles"); if($topcoderRoles) { - $roleNames = array_column($topcoderRoles, 'roleName'); - $lowerRoleNames = array_map('strtolower', $roleNames); + $lowerRoleNames = array_map('strtolower', $topcoderRoles); return count(array_intersect($lowerRoleNames, ["client manager"])) > 0; } @@ -1824,7 +1827,6 @@ private static function loadTopcoderUserDetails($vanillaUser) { $topcoderRoles = self::loadTopcoderRoles($topcoderProfile->userId); $cachedUser['Roles'] = self::getTopcoderRoleNames($topcoderRoles); $cachedUser['IsAdmin'] = self::isTopcoderAdmin($topcoderRoles); - $cachedUser['IsClientManager'] = self::isTopcoderClientManager($topcoderRoles); $topcoderRating = self::loadTopcoderRating($username); //loaded by handle if($topcoderRating) { $cachedUser['Rating'] = $topcoderRating; @@ -1914,7 +1916,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]); } @@ -2011,7 +2013,7 @@ public function gdn_dispatcher_beforeDispatch_handler($sender, $args) { 'Request(Method)'=> Gdn::request()->getMethod(), 'Permissions' => Gdn::session()->getPermissionsArray(), ); - logMessage(__FILE__, __LINE__, 'TopcoderPlugin', "Data", json_encode($data )); + // logMessage(__FILE__, __LINE__, 'TopcoderPlugin', "Data", json_encode($data )); // self::log('gdn_dispatcher_beforeDispatch_handler', $data); } @@ -2090,7 +2092,6 @@ private static function loadTopcoderUserDetailsByHandle($topcoderHandle) { $topcoderRoles = self::loadTopcoderRoles($topcoderProfile->userId); $cachedUser['Roles'] = self::getTopcoderRoleNames($topcoderRoles); $cachedUser['IsAdmin'] = self::isTopcoderAdmin($topcoderRoles); - $cachedUser['IsClientManager'] = self::isTopcoderClientManager($topcoderRoles); $topcoderRating = self::loadTopcoderRating($topcoderHandle); //loaded by handle if($topcoderRating) { $cachedUser['Rating'] = $topcoderRating; @@ -2490,7 +2491,7 @@ function userPhoto($user, $options = []) { } $isTopcoderAdmin = val('IsAdmin', $topcoderProfile); - $isTopcoderClientManager = val('IsClientManager', $topcoderProfile); + $isTopcoderClientManager = TopcoderPlugin::isTopcoderClientManager(); $photoUrl = isset($photoUrl) && !empty(trim($photoUrl)) ? $photoUrl: UserModel::getDefaultAvatarUrl(); $isUnlickableUser = TopcoderPlugin::isUnclickableUser($name); $href = (val('NoLink', $options)) || $isUnlickableUser || @@ -2586,7 +2587,7 @@ function userAnchor($user, $cssClass = null, $options = null) { $topcoderProfile = TopcoderPlugin::getTopcoderUser($userID); // Go to Topcoder user profile link instead of Vanilla profile link - $isTopcoderClientManager = val('IsClientManager', $topcoderProfile); + $isTopcoderClientManager = TopcoderPlugin::isTopcoderClientManager(); $isUnlickableUser = ( $isTopcoderClientManager && getIncomingValue('embed_type') == 'mfe') || TopcoderPlugin::isUnclickableUser($name); $userUrl = $isUnlickableUser? '#' : topcoderUserUrl($user, $px); @@ -2906,9 +2907,7 @@ function hideInMFE() { } //FIX Issues-652: Client Manager - no navigation when embedded $isMFE = getIncomingValue('embed_type') == 'mfe'; - $user = Gdn::userModel()->getID(Gdn::session()->UserID, DATASET_TYPE_ARRAY); - $topcoderProfile = TopcoderPlugin::getTopcoderUser($user); - $isTopcoderClientManager = val('IsClientManager', $topcoderProfile); + $isTopcoderClientManager = TopcoderPlugin::isTopcoderClientManager(); if ($isMFE && $isTopcoderClientManager) { return true; From cddd78235ed59fadda192008b8390969278c809f Mon Sep 17 00:00:00 2001 From: Bogdanova Olga Date: Tue, 18 Jan 2022 14:00:23 +0300 Subject: [PATCH 06/16] Issues-652: fixed ChallengeID in Vanilla Dispatcher --- Topcoder/class.topcoder.plugin.php | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/Topcoder/class.topcoder.plugin.php b/Topcoder/class.topcoder.plugin.php index 8bc8a60..fdb1542 100644 --- a/Topcoder/class.topcoder.plugin.php +++ b/Topcoder/class.topcoder.plugin.php @@ -897,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)) { @@ -943,6 +943,29 @@ function gdn_dispatcher_beforeControllerMethod_handler($sender, $args){ } } + 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()) { From 99fd3095a134f64639e9af722d37c514ce9b8fcd Mon Sep 17 00:00:00 2001 From: Bogdanova Olga Date: Fri, 21 Jan 2022 22:13:56 +0300 Subject: [PATCH 07/16] Support a self-service flag --- Topcoder/class.topcoder.plugin.php | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/Topcoder/class.topcoder.plugin.php b/Topcoder/class.topcoder.plugin.php index fdb1542..d96d2b4 100644 --- a/Topcoder/class.topcoder.plugin.php +++ b/Topcoder/class.topcoder.plugin.php @@ -1624,6 +1624,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); @@ -1802,7 +1803,6 @@ private static function isTopcoderAdmin($topcoderRoles = false) { /** * Check if the list of Topcoder roles includes 'Client Manager' role - * @param false $topcoderRoles * @return bool true, if the list of Topcoder roles includes 'Client Manager' */ public static function isTopcoderClientManager() { @@ -1818,6 +1818,22 @@ public static function isTopcoderClientManager() { 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 @@ -2938,3 +2954,12 @@ function hideInMFE() { return false; } } + +if (!function_exists('isSelfService')) { + function isSelfService() { + if (!Gdn::session()->isValid()) { + return false; + } + return TopcoderPlugin::isChallengeSelfService(); + } +} \ No newline at end of file From da272cdd3b75a3efa756a6d034437e7a35b266e8 Mon Sep 17 00:00:00 2001 From: Bogdanova Olga Date: Sat, 22 Jan 2022 12:10:05 +0300 Subject: [PATCH 08/16] Issues-662: email massage tweaks for MFE --- Topcoder/class.topcoder.plugin.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/Topcoder/class.topcoder.plugin.php b/Topcoder/class.topcoder.plugin.php index d96d2b4..cb1640e 100644 --- a/Topcoder/class.topcoder.plugin.php +++ b/Topcoder/class.topcoder.plugin.php @@ -2387,6 +2387,30 @@ 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 + 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) { + $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) { + $activity['Data']['EmailUrl'] = val('EmbedUrl',$data); + return; + } + } + } + $activity['Data']['EmailUrl'] = externalUrl(val('Route', $activity) == '' ? '/' : val('Route', $activity)); + } } if(!function_exists('topcoderRatingCssClass')) { From 5d7d277b09a1fb8c9b38921de3469fa3f8584363 Mon Sep 17 00:00:00 2001 From: Bogdanova Olga Date: Wed, 26 Jan 2022 21:39:01 +0300 Subject: [PATCH 09/16] Use a new email template for Client Manager --- Topcoder/class.topcoder.plugin.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Topcoder/class.topcoder.plugin.php b/Topcoder/class.topcoder.plugin.php index cb1640e..02a551f 100644 --- a/Topcoder/class.topcoder.plugin.php +++ b/Topcoder/class.topcoder.plugin.php @@ -2388,7 +2388,7 @@ public function profileController_preferences_create($sender, $userReference = ' $sender->render(); } - // All notified users have been added in an activity + // 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); @@ -2405,11 +2405,23 @@ public function activityModel_BeforeCheckPreference_handler($sender, $args) { $isClientManager = count(array_intersect($currentProjectRoles, ["client manager"])) > 0; if($isClientManager) { $activity['Data']['EmailUrl'] = val('EmbedUrl',$data); + $activity['Data']['EmailTemplate'] = 'email-selfservice'; + $category = CategoryModel::categories($challengeID); + $categoryName = val('Name', $category); + $headline = 'Message From a Topcoder Member on Your Work - Please See'; + $activity['HeadlineFormat'] = $headline; + $activity['Headline'] = $headline; + $activity['Story']= sprintf('A new message has been posted on your work forum tied to your Topcoder Work "%s". You can read the full message below.
+To answer, click here to be taken to this discussion.
+Please do not reply to this email.
+Thank you! +The Topcoder Team', $categoryName); return; } } } $activity['Data']['EmailUrl'] = externalUrl(val('Route', $activity) == '' ? '/' : val('Route', $activity)); + $activity['Data']['EmailTemplate'] = 'email-basic'; } } From 45abf079e4791b36c5d46cb7e179318bcb51a97b Mon Sep 17 00:00:00 2001 From: Justin Gasper Date: Thu, 27 Jan 2022 09:21:19 +1100 Subject: [PATCH 10/16] Tweak template text --- Topcoder/class.topcoder.plugin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Topcoder/class.topcoder.plugin.php b/Topcoder/class.topcoder.plugin.php index 02a551f..63332f0 100644 --- a/Topcoder/class.topcoder.plugin.php +++ b/Topcoder/class.topcoder.plugin.php @@ -2412,7 +2412,7 @@ public function activityModel_BeforeCheckPreference_handler($sender, $args) { $activity['HeadlineFormat'] = $headline; $activity['Headline'] = $headline; $activity['Story']= sprintf('A new message has been posted on your work forum tied to your Topcoder Work "%s". You can read the full message below.
-To answer, click here to be taken to this discussion.
+To answer, click "Open Discussion" below to be taken to this discussion.
Please do not reply to this email.
Thank you! The Topcoder Team', $categoryName); From 2b4c9f64e1b1eb03db6a0469f258dd7cff1e8926 Mon Sep 17 00:00:00 2001 From: Bogdanova Olga Date: Thu, 27 Jan 2022 10:52:49 +0300 Subject: [PATCH 11/16] Issues-670: Updated email message for Client Manager --- Topcoder/class.topcoder.plugin.php | 97 ++++++++++++++++++++++++------ 1 file changed, 78 insertions(+), 19 deletions(-) diff --git a/Topcoder/class.topcoder.plugin.php b/Topcoder/class.topcoder.plugin.php index 02a551f..81864ce 100644 --- a/Topcoder/class.topcoder.plugin.php +++ b/Topcoder/class.topcoder.plugin.php @@ -2397,27 +2397,86 @@ public function activityModel_BeforeCheckPreference_handler($sender, $args) { $data = $activity['Data']; $challengeID = $data['ChallengeID']; if($challengeID) { - $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) { - $activity['Data']['EmailUrl'] = val('EmbedUrl',$data); - $activity['Data']['EmailTemplate'] = 'email-selfservice'; - $category = CategoryModel::categories($challengeID); - $categoryName = val('Name', $category); - $headline = 'Message From a Topcoder Member on Your Work - Please See'; - $activity['HeadlineFormat'] = $headline; - $activity['Headline'] = $headline; - $activity['Story']= sprintf('A new message has been posted on your work forum tied to your Topcoder Work "%s". You can read the full message below.
-To answer, click here to be taken to this discussion.
+ $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'] = + '

A new message has been posted on your work forum 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 here to be taken to this discussion.
+ Please do not reply to this email.
+ Thank you! + The Topcoder Team

' . + '
' . + '
'; + + } else { // Comment + $commentModel = new CommentModel(); + $comment = $commentModel->getID($recordID); + // $discussion = $discussionModel->getID(val('DiscussionID', $comment)); + // $discussionName = val('Name',$discussion); + $commentDateInserted = Gdn_Format::dateFull(val('DateInserted',$comment)); + $commentAuthor = $userModel->getID(val('InsertUserID',$comment)); + $commentStory = Gdn::formatService()->renderQuote(val('Body',$comment), val('Format',$comment)); + $activity['Story'] = + '

A new message has been posted on your work forum tied to your Topcoder Work "' . $categoryName . '" ' . + 'which was updated ' . $commentDateInserted . ' by ' . val('Name',$commentAuthor) . ':

' . + '
' . + '

Message:'.'

' . + $commentStory . + '

'; + + $parentCommentID = (int)val('ParentCommentID',$comment); + if($parentCommentID > 0) { + $parentComment = $commentModel->getID($parentCommentID, DATASET_TYPE_ARRAY); + $parentCommentAuthor = $userModel->getID($parentComment['InsertUserID']); + $parentCommentStory = condense(Gdn_Format::to($parentComment['Body'], $parentComment['Format'])); + $activity['Story'] .= + '

Original Message (by '.$parentCommentAuthor->Name.' ):

'. + '

' . + $parentCommentStory. + '

' . + '
'; + } + $activity['Story'] .= '

To answer, click here to be taken to this discussion.
Please do not reply to this email.
Thank you! -The Topcoder Team', $categoryName); - return; - } +The Topcoder Team

'; + } + + $headline = 'Message From a Topcoder Member on Your Work - Please See'; + $activity['HeadlineFormat'] = $headline; + $activity['Headline'] = $headline; + $activity['Data']['EmailUrl'] = val('EmbedUrl', $data); + $activity['Data']['EmailTemplate'] = 'email-selfservice'; + return; + } + } } } $activity['Data']['EmailUrl'] = externalUrl(val('Route', $activity) == '' ? '/' : val('Route', $activity)); From 2a496afaf4e1b3c544f9554a4c11a59c4b303306 Mon Sep 17 00:00:00 2001 From: Bogdanova Olga Date: Thu, 27 Jan 2022 10:58:56 +0300 Subject: [PATCH 12/16] Issues-670: Updated email message for Client Manager --- Topcoder/class.topcoder.plugin.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Topcoder/class.topcoder.plugin.php b/Topcoder/class.topcoder.plugin.php index 81864ce..4d3ef86 100644 --- a/Topcoder/class.topcoder.plugin.php +++ b/Topcoder/class.topcoder.plugin.php @@ -2428,7 +2428,7 @@ public function activityModel_BeforeCheckPreference_handler($sender, $args) { // '

Category: ' . implode('›', $categoryBreadcrumbs) . '

' . '

Message: ' . $message . '

' . '
'. - '

To answer, click here to be taken to this discussion.
+ '

To answer, click "Open Discussion" below to be taken to this discussion.
Please do not reply to this email.
Thank you! The Topcoder Team

' . @@ -2463,7 +2463,7 @@ public function activityModel_BeforeCheckPreference_handler($sender, $args) { '

' . '
'; } - $activity['Story'] .= '

To answer, click here to be taken to this discussion.
+ $activity['Story'] .= '

To answer, click "Open Discussion" below to be taken to this discussion.
Please do not reply to this email.
Thank you! The Topcoder Team

'; From a3c6c03689278ae36efa0512779daca4e5a588dd Mon Sep 17 00:00:00 2001 From: Justin Gasper Date: Thu, 27 Jan 2022 20:13:46 +1100 Subject: [PATCH 13/16] Template tweak, at Topcoder's request --- Topcoder/class.topcoder.plugin.php | 1 + 1 file changed, 1 insertion(+) diff --git a/Topcoder/class.topcoder.plugin.php b/Topcoder/class.topcoder.plugin.php index 4d3ef86..3c178d2 100644 --- a/Topcoder/class.topcoder.plugin.php +++ b/Topcoder/class.topcoder.plugin.php @@ -2419,6 +2419,7 @@ public function activityModel_BeforeCheckPreference_handler($sender, $args) { // $categoryBreadcrumbs = array_column(array_values(CategoryModel::getAncestors(val('CategoryID',$discussion))), 'Name'); $activity['Story'] = + '

Hi there,

' '

A new message has been posted on your work forum tied to your Topcoder Work "' . $categoryName . '" ' . 'which was updated ' . $dateInserted . ' by ' . $author->Name . ':

' . '


' . From cf698db22b0c4aad180602b204394db10cba5890 Mon Sep 17 00:00:00 2001 From: Justin Gasper Date: Thu, 27 Jan 2022 20:23:37 +1100 Subject: [PATCH 14/16] Template fix for compile error --- Topcoder/class.topcoder.plugin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Topcoder/class.topcoder.plugin.php b/Topcoder/class.topcoder.plugin.php index 3c178d2..54dd24c 100644 --- a/Topcoder/class.topcoder.plugin.php +++ b/Topcoder/class.topcoder.plugin.php @@ -2419,7 +2419,7 @@ public function activityModel_BeforeCheckPreference_handler($sender, $args) { // $categoryBreadcrumbs = array_column(array_values(CategoryModel::getAncestors(val('CategoryID',$discussion))), 'Name'); $activity['Story'] = - '

Hi there,

' + '

Hi there,

' . '

A new message has been posted on your work forum tied to your Topcoder Work "' . $categoryName . '" ' . 'which was updated ' . $dateInserted . ' by ' . $author->Name . ':

' . '


' . From bc8f34de4a693166579a13061ce4b76ddb8cdfe1 Mon Sep 17 00:00:00 2001 From: Justin Gasper Date: Thu, 27 Jan 2022 20:41:18 +1100 Subject: [PATCH 15/16] Template tweak for Topcoder --- Topcoder/class.topcoder.plugin.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Topcoder/class.topcoder.plugin.php b/Topcoder/class.topcoder.plugin.php index 54dd24c..683fd14 100644 --- a/Topcoder/class.topcoder.plugin.php +++ b/Topcoder/class.topcoder.plugin.php @@ -2420,7 +2420,7 @@ public function activityModel_BeforeCheckPreference_handler($sender, $args) { $activity['Story'] = '

Hi there,

' . - '

A new message has been posted on your work forum tied to your Topcoder Work "' . $categoryName . '" ' . + '

A new message has been posted on the discussion tied to your Topcoder Work "' . $categoryName . '" ' . 'which was updated ' . $dateInserted . ' by ' . $author->Name . ':

' . '


' . '
' . @@ -2445,7 +2445,8 @@ public function activityModel_BeforeCheckPreference_handler($sender, $args) { $commentAuthor = $userModel->getID(val('InsertUserID',$comment)); $commentStory = Gdn::formatService()->renderQuote(val('Body',$comment), val('Format',$comment)); $activity['Story'] = - '

A new message has been posted on your work forum tied to your Topcoder Work "' . $categoryName . '" ' . + '

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:'.'

' . From 2b516b54f09de98ad3a68988a73df2297cb54fca Mon Sep 17 00:00:00 2001 From: Bogdanova Olga Date: Fri, 28 Jan 2022 09:52:34 +0300 Subject: [PATCH 16/16] Issues-674: fix a breadcrumb for sel-service --- Topcoder/class.topcoder.plugin.php | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/Topcoder/class.topcoder.plugin.php b/Topcoder/class.topcoder.plugin.php index 683fd14..18391ae 100644 --- a/Topcoder/class.topcoder.plugin.php +++ b/Topcoder/class.topcoder.plugin.php @@ -934,11 +934,12 @@ 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); } } } @@ -3036,15 +3037,20 @@ function watchingSorts($extraClasses = '') { } } +if (!function_exists('isMFE')) { + function isMFE() { + return getIncomingValue('embed_type') == 'mfe'; + } +} + if (!function_exists('hideInMFE')) { function hideInMFE() { if (!Gdn::session()->isValid()) { return false; } //FIX Issues-652: Client Manager - no navigation when embedded - $isMFE = getIncomingValue('embed_type') == 'mfe'; + $isMFE = isMFE(); $isTopcoderClientManager = TopcoderPlugin::isTopcoderClientManager(); - if ($isMFE && $isTopcoderClientManager) { return true; }