Skip to content

Commit

Permalink
feat: add and implement site switcher
Browse files Browse the repository at this point in the history
  • Loading branch information
Sebastian Thulin committed Jan 17, 2025
1 parent dc2282d commit 5bc5a35
Show file tree
Hide file tree
Showing 3 changed files with 206 additions and 44 deletions.
17 changes: 13 additions & 4 deletions library/App.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@
use WpService\WpService;
use Municipio\Helper\User\Config\UserConfig;
use Municipio\Helper\User\User;
use Municipio\Helper\SiteSwitcher\SiteSwitcher;


/**
* Class App
Expand Down Expand Up @@ -95,7 +97,14 @@ public function __construct(
*/
$userGroupConfig = new \Municipio\UserGroup\Config\UserGroupConfig($this->wpService);
$userHelperConfig = new \Municipio\Helper\User\Config\UserConfig();
$userHelper = new \Municipio\Helper\User\User($this->wpService, $this->acfService, $userHelperConfig, $userGroupConfig, new \Municipio\Helper\Term\Term($this->wpService, $this->acfService));
$userHelper = new \Municipio\Helper\User\User(
$this->wpService,
$this->acfService,
$userHelperConfig,
$userGroupConfig,
new \Municipio\Helper\Term\Term($this->wpService, $this->acfService),
new \Municipio\Helper\SiteSwitcher\SiteSwitcher()
);

/**
* User group
Expand Down Expand Up @@ -391,7 +400,7 @@ private function setUpBrokenLinksIntegration(): void
private function setupLoginLogout(): void
{
//Needs setUser to be called before using the user object
$userHelper = new User($this->wpService, $this->acfService, new UserConfig(), new \Municipio\UserGroup\Config\UserGroupConfig($this->wpService), new \Municipio\Helper\Term\Term($this->wpService, $this->acfService));
$userHelper = new User($this->wpService, $this->acfService, new UserConfig(), new \Municipio\UserGroup\Config\UserGroupConfig($this->wpService), new \Municipio\Helper\Term\Term($this->wpService, $this->acfService), new \Municipio\Helper\SiteSwitcher\SiteSwitcher());

$filterAuthUrls = new \Municipio\Admin\Login\RelationalLoginLogourUrls($this->wpService);
$filterAuthUrls->addHooks();
Expand Down Expand Up @@ -432,7 +441,7 @@ private function setupUserGroupFeature(): void
// Setup dependencies
$userGroupRestrictionConfig = new \Municipio\Admin\Private\Config\UserGroupRestrictionConfig();
$userHelperConfig = new \Municipio\Helper\User\Config\UserConfig();
$userHelper = new \Municipio\Helper\User\User($this->wpService, $this->acfService, $userHelperConfig, $config, new \Municipio\Helper\Term\Term($this->wpService, $this->acfService));
$userHelper = new \Municipio\Helper\User\User($this->wpService, $this->acfService, $userHelperConfig, $config, new \Municipio\Helper\Term\Term($this->wpService, $this->acfService), new \Municipio\Helper\SiteSwitcher\SiteSwitcher());

// Create user group taxonomy
(new \Municipio\UserGroup\CreateUserGroupTaxonomy($this->wpService, $config))->addHooks();
Expand Down Expand Up @@ -468,7 +477,7 @@ private function setupUserGroupFeature(): void
*/
private function setUpMiniOrangeIntegration(): void
{
$userHelper = new \Municipio\Helper\User\User($this->wpService, $this->acfService, new \Municipio\Helper\User\Config\UserConfig(), new \Municipio\UserGroup\Config\UserGroupConfig($this->wpService), new \Municipio\Helper\Term\Term($this->wpService, $this->acfService));
$userHelper = new \Municipio\Helper\User\User($this->wpService, $this->acfService, new \Municipio\Helper\User\Config\UserConfig(), new \Municipio\UserGroup\Config\UserGroupConfig($this->wpService), new \Municipio\Helper\Term\Term($this->wpService, $this->acfService), new \Municipio\Helper\SiteSwitcher\SiteSwitcher());
$termHelper = new \Municipio\Helper\Term\Term($this->wpService, $this->acfService);
$userGroupConfig = new \Municipio\UserGroup\Config\UserGroupConfig($this->wpService);
$config = new \Municipio\Integrations\MiniOrange\Config\MiniOrangeConfig($this->wpService);
Expand Down
25 changes: 25 additions & 0 deletions library/Helper/SiteSwitcher/SiteSwitcher.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace Municipio\Helper\SiteSwitcher;

class SiteSwitcher
{
/**
* Execute a callable within the context of a specific site.
*
* @param int $siteId
* @param callable $callable
* @param mixed $callableContext Contextual data to pass to the callable.
* @return mixed The result of the callable execution.
*/
public function runInSite(int $siteId, callable $callable, mixed $callableContext = null): mixed
{
switch_to_blog($siteId);

try {
return $callable(...func_get_args());
} finally {
restore_current_blog();
}
}
}
208 changes: 168 additions & 40 deletions library/Helper/User/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Municipio\Helper\User\Config\UserConfigInterface;
use Municipio\Helper\User\Contracts\{GetRedirectToGroupUrl, UserHasRole, GetUserGroup, GetUserGroupUrl, GetUserGroupUrlType, GetUserPrefersGroupUrl, GetUser, SetUserGroup};
use Municipio\Helper\User\FieldResolver\UserGroupUrl;
use Municipio\Helper\SiteSwitcher\SiteSwitcher;
use Municipio\UserGroup\Config\UserGroupConfigInterface;
use WP_Term;
use WP_User;
Expand All @@ -25,7 +26,68 @@ class User implements
GetRedirectToGroupUrl,
SetUserGroup
{
// Constructor and other methods...
/**
* Constructor.
*/
public function __construct(
private WpService $wpService,
private GetField $acfService,
private UserConfigInterface $userConfig,
private UserGroupConfigInterface $userGroupConfig,
private CreateOrGetTermIdFromString $termHelper,
private SiteSwitcher $siteSwitcher
) {
}

/**
* @inheritDoc
*/
public function getUser(null|WP_User|int $user = null): ?WP_User
{
if (is_a($user, 'WP_User') && $user->ID > 0) {
return $user;
}

if (is_int($user) && $user > 0) {
$retrievedUser = $this->wpService->getUserBy('ID', $user);

if (is_a($retrievedUser, 'WP_User')) {
return $retrievedUser;
}
}

if (is_null($user)) {
$retrievedUser = $this->wpService->wpGetCurrentUser();

if (is_a($retrievedUser, 'WP_User') && $retrievedUser->ID > 0) {
return $retrievedUser;
}
}

return null;
}

/**
* @inheritDoc
*/
public function userHasRole(string|array $roles, null|WP_User|int $user = null): bool
{
$user = $this->getUser($user);

if (!$user) {
return false;
}

if (is_string($roles)) {
$roles = array($roles);
}

if (!array_intersect($roles, $user->roles)) {
return false;
}

return true;
}

/**
* @inheritDoc
Expand All @@ -38,37 +100,86 @@ public function getUserGroup(null|\WP_User|int $user = null): ?WP_Term
return null;
}

$userGroup = null;

$this->runInAnotherSite($this->wpService->getMainSiteId(), function () use ($user, &$userGroup) {
$terms = $this->wpService->wpGetObjectTerms($user->ID, $this->userGroupConfig->getUserGroupTaxonomy());
if (!empty($terms) && !$this->wpService->isWpError($terms)) {
$userGroup = is_array($terms) ? array_shift($terms) : $terms;
$userGroup = $this->siteSwitcher->runInSite(
$this->wpService->getMainSiteId(),
function() use ($user) {
return $this->wpService->wpGetObjectTerms(
$user->ID,
$this->userGroupConfig->getUserGroupTaxonomy()
);
}
});
);

if (empty($userGroup) || $this->wpService->isWpError($userGroup)) {
return null;
}

if (is_array($userGroup)) {
$userGroup = array_shift($userGroup);
}

return is_a($userGroup, 'WP_Term') ? $userGroup : null;
}

/**
* @inheritDoc
*/
public function getUserGroupUrlType(?WP_Term $term = null, null|WP_User|int $user = null): ?string
public function getUserGroupUrl(?WP_Term $term = null, null|WP_User|int $user = null): ?string
{
$user = $this->getUser($user);

if (!$user) {
return null;
}

// Get the user group
$term ??= $this->getUserGroup($user);

// Ensure term exists
if (!$term) {
return null;
}

$typeOfLink = null;
// Get the selected type of link
$typeOfLink = $this->getUserGroupUrlType($term, $user);

// Initialize the URL resolver
$urlResolver = new UserGroupUrl(
$typeOfLink,
$term,
$this->acfService,
$this->wpService,
$this->userConfig,
$this->userGroupConfig
);

// Resolve the URL
$resolvedUrl = $this->siteSwitcher->runInSite(
$this->wpService->getMainSiteId(),
function() use ($urlResolver) {
return $urlResolver->get();
}
);

return $resolvedUrl;
}

/**
* @inheritDoc
*/
public function getUserGroupUrlType(?WP_Term $term = null, null|WP_User|int $user = null): ?string
{
$term ??= $this->getUserGroup($user);
$termId = $this->userGroupConfig->getUserGroupTaxonomy($user) . '_' . $term->term_id;

$this->runInAnotherSite($this->wpService->getMainSiteId(), function () use ($term, &$typeOfLink) {
$termId = $this->userGroupConfig->getUserGroupTaxonomy() . '_' . $term->term_id;
$typeOfLink = $this->acfService->getField('user_group_type_of_link', $termId) ?: null;
});
$userGroupUrlType = $this->siteSwitcher->runInSite(
$this->wpService->getMainSiteId(),
function() use ($termId) {
return $this->acfService->getField('user_group_type_of_link', $termId) ?: null;
}
);

return $typeOfLink;
return $userGroupUrlType;
}

/**
Expand All @@ -82,50 +193,67 @@ public function getUserPrefersGroupUrl(null|WP_User|int $user = null): ?bool
return null;
}

$prefersGroupUrl = false;

$this->runInAnotherSite($this->wpService->getMainSiteId(), function () use ($user, &$prefersGroupUrl) {
$prefersGroupUrl = $this->wpService->getUserMeta(
$user->ID,
$this->userConfig->getUserPrefersGroupUrlMetaKey(),
true
);
});
$perfersGroupUrl = $this->siteSwitcher->runInSite(
$this->wpService->getMainSiteId(),
function() use ($user) {
return $this->wpService->getUserMeta(
$user->ID,
$this->userConfig->getUserPrefersGroupUrlMetaKey(),
true
);
}
);

return (bool) $prefersGroupUrl;
if ($perfersGroupUrl) {
return true;
}
return false;
}

/**
* @inheritDoc
*/
public function setUserGroup(string $groupName, null|WP_User|int $user = null): void
public function getRedirectToGroupUrl(null|WP_User|int $user = null): ?string
{
$user = $this->getUser($user);

if (!$user) {
return;
return null;
}

$taxonomy = $this->userGroupConfig->getUserGroupTaxonomy();
$perfersGroupUrl = $this->getUserPrefersGroupUrl($user);
$groupUrl = $this->getUserGroupUrl(null, $user);

$this->runInAnotherSite($this->wpService->getMainSiteId(), function () use ($groupName, $user, $taxonomy) {
if ($termId = $this->termHelper->createOrGetTermIdFromString($groupName, $taxonomy)) {
$this->wpService->wpSetObjectTerms($user->ID, $termId, $taxonomy, false);
}
});
if ($perfersGroupUrl && $groupUrl) {
return $this->wpService->addQueryArg([
'loggedin' => 'true',
'prefersgroup' => 'true'
], $groupUrl);
}

return null;
}

/**
* Run code in the context of another site.
* @inheritDoc
*/
private function runInAnotherSite(int $siteId, callable $callable): void
public function setUserGroup(string $groupName, null|WP_User|int $user = null): void
{
$this->wpService->switchToBlog($siteId);
$user = $this->getUser($user);

try {
$callable();
} finally {
$this->wpService->restoreCurrentBlog();
if (!$user) {
return;
}

$taxonomy = $this->userGroupConfig->getUserGroupTaxonomy();

$this->siteSwitcher->runInSite(
$this->wpService->getMainSiteId(),
function() use ($groupName, $taxonomy, $user) {
if ($termId = $this->termHelper->createOrGetTermIdFromString($groupName, $taxonomy)) {
$this->wpService->wpSetObjectTerms($user->ID, $termId, $taxonomy, false);
}
}
);
}
}

0 comments on commit 5bc5a35

Please sign in to comment.