Skip to content

Commit 316e972

Browse files
committed
[FIX] Plugin.
1 parent c548d87 commit 316e972

File tree

2 files changed

+176
-39
lines changed

2 files changed

+176
-39
lines changed

plugins/sMultisitePlugin.php

Lines changed: 175 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
11
<?php
22
/**
3-
* Plugin for Seiger Multisite Tools to Evolution CMS.
3+
* Seiger Multisite Tools plugin for Evolution CMS.
44
*
5-
* SSO across multiple domains living in the same Evolution CMS instance:
6-
* - After Manager login: propagates the session to other domains.
7-
* - After Manager logout: clears the session on other domains.
8-
* - Uses short-lived signed tokens (HS256) and a per-login "run plan" (steps).
9-
* - Runs in the same tab via location.replace() to avoid popup blockers.
5+
* Provides multisite runtime configuration and Manager UX improvements:
6+
* - Switches Evolution config (site_key/start pages) by the current domain.
7+
* - Namespaces page cache keys per site_key.
8+
* - Rebuilds cached multi-domain tree on cache refresh.
9+
* - Adjusts Manager document URLs to point to the owning domain.
10+
* - Enhances Manager tree with extra domain roots and special node icons.
11+
*
12+
* Also provides optional cross-domain Manager SSO (single sign-on):
13+
* - After Manager login: propagates the session SID to other domains.
14+
* - After Manager logout: clears the session SID on other domains.
15+
* - Uses short-lived signed tokens (HS256) and a per-run "plan" (steps).
16+
* - Executes in the same tab via location.replace() to avoid popup blockers.
17+
*
18+
* Endpoints (friendly_url_suffix is respected):
19+
* - /_ms-run, /_ms-run-logout Runner endpoints (step sequencer)
20+
* - /_ms-sso, /_ms-sso-logout Receiver endpoints (set/unset SID)
1021
*/
1122

1223
use EvolutionCMS\Facades\UrlProcessor;
@@ -17,6 +28,16 @@
1728

1829
// Load SSO functions if needed
1930
if (!function_exists('ms_sso_load_functions')) {
31+
/**
32+
* Load SSO helper functions once.
33+
*
34+
* The helpers are expected at: ../functions/sso.php
35+
* - ms_sso_token_make()
36+
* - ms_sso_token_parse()
37+
* - ms_run_put(), ms_run_get(), ms_run_touch(), ms_run_del()
38+
*
39+
* @return void
40+
*/
2041
function ms_sso_load_functions(): void {
2142
static $loaded = false;
2243
if (!$loaded) {
@@ -30,8 +51,18 @@ function ms_sso_load_functions(): void {
3051
}
3152

3253
/**
33-
* OnLoadSettings:
34-
* Switch Evolution config by domain (site_key, start pages), and hydrate documentListing from cache.
54+
* OnLoadSettings
55+
*
56+
* Switches Evolution configuration by domain:
57+
* - site_key, site_root, site_name
58+
* - site_start, error_page, unauthorized_page
59+
* - site_color
60+
*
61+
* Also hydrates UrlProcessor::documentListing from cache for the selected site_key.
62+
*
63+
* @param array $params Event payload (may include ['config']['setHost'] override)
64+
*
65+
* @return void
3566
*/
3667
Event::listen('evolution.OnLoadSettings', function($params) {
3768
$host = $_SERVER['HTTP_HOST'];
@@ -58,9 +89,13 @@ function ms_sso_load_functions(): void {
5889
});
5990

6091
/**
61-
* OnWebPageInit:
62-
* Enforce resource access per domain on the front-end.
63-
* Whitelist SSO endpoints to avoid accidental 404.
92+
* OnWebPageInit
93+
*
94+
* Enforces resource access per domain on the front-end:
95+
* - Compares evo()->documentIdentifier against cached allowed resource IDs for the current site_key.
96+
* - Whitelists SSO service endpoints to avoid accidental 404 / access blocks.
97+
*
98+
* @return void
6499
*/
65100
Event::listen('evolution.OnWebPageInit', function () {
66101
$uri = strtok($_SERVER['REQUEST_URI'] ?? '/', '?');
@@ -76,8 +111,16 @@ function ms_sso_load_functions(): void {
76111
});
77112

78113
/**
79-
* OnMakeDocUrl:
80-
* For Manager links, prefix URLs with the appropriate domain.
114+
* OnMakeDocUrl
115+
*
116+
* For Manager links, prefixes document URLs with the domain that owns the resource root.
117+
* This allows correct cross-domain navigation from Manager UI.
118+
*
119+
* @param array $params Event payload:
120+
* - int $params['id'] Document ID
121+
* - string $params['url'] Generated (relative) URL
122+
*
123+
* @return string|null Prefixed URL for Manager context, otherwise null to keep default behavior
81124
*/
82125
Event::listen('evolution.OnMakeDocUrl', function($params) {
83126
if (evo()->isBackend()) {
@@ -100,33 +143,57 @@ function ms_sso_load_functions(): void {
100143
});
101144

102145
/**
103-
* OnMakePageCacheKey:
104-
* Namespaces page cache by site_key.
146+
* OnMakePageCacheKey
147+
*
148+
* Namespaces page cache keys by site_key to prevent collisions across domains.
149+
*
150+
* @param array $params Event payload:
151+
* - string $params['hash'] Base cache key hash
152+
*
153+
* @return string
105154
*/
106155
Event::listen('evolution.OnMakePageCacheKey', function($params) {
107156
return evo()->getConfig('site_key', 'default') . '_' . $params['hash'];
108157
});
109158

110159
/**
111-
* OnCacheUpdate:
112-
* Rebuild cached multi-domain tree.
160+
* OnCacheUpdate
161+
*
162+
* Rebuilds the cached multi-domain tree/listings.
163+
*
164+
* @param array $params Event payload (unused)
165+
*
166+
* @return void
113167
*/
114168
Event::listen('evolution.OnCacheUpdate', function($params) {
115169
sMultisite::domainsTree();
116170
});
117171

118172
/**
119-
* OnDocFormPrerender:
120-
* Ensure System Settings panel loads values from the domain the document belongs to.
173+
* OnDocFormPrerender
174+
*
175+
* Ensures the System Settings panel loads values for the domain the document belongs to.
176+
* It resolves a host for the given document ID and triggers OnLoadSettings with setHost override.
177+
*
178+
* @param array $params Event payload:
179+
* - int|string $params['id'] Document ID being edited
180+
*
181+
* @return void
121182
*/
122183
Event::listen('evolution.OnDocFormPrerender', function($params) {
123184
$config = array_merge(evo()->config, ['setHost' => parse_url(url($params['id']), PHP_URL_HOST)]);
124185
evo()->invokeEvent('OnLoadSettings', ['config' => &$config]);
125186
});
126187

127188
/**
128-
* OnManagerMenuPrerender:
129-
* Adds “sMultisite” entry to Tools (for users with 'settings' permission).
189+
* OnManagerMenuPrerender
190+
*
191+
* Adds “sMultisite” entry to Tools for users with 'settings' permission.
192+
*
193+
* @param array $params Event payload:
194+
* - array $params['menu'] Current Manager menu structure
195+
*
196+
* @return string|null Serialized updated menu, or null to keep default behavior
130197
*/
131198
Event::listen('evolution.OnManagerMenuPrerender', function($params) {
132199
if (evo()->hasPermission('settings')) {
@@ -148,9 +215,16 @@ function ms_sso_load_functions(): void {
148215
});
149216

150217
/**
151-
* OnManagerLogin:
218+
* OnManagerLogin
219+
*
152220
* After successful Manager login, builds a "run plan" to authenticate on other domains.
153-
* Stores runId in session; the plan is executed from OnManagerWelcomeHome.
221+
* Stores runId in PHP session; the plan is executed from evolution.OnManagerWelcomeHome.
222+
*
223+
* Notes:
224+
* - Uses current session_id() as SID value to propagate.
225+
* - Tokens are short-lived and include mode/login, sid, and host.
226+
*
227+
* @return void
154228
*/
155229
Event::listen('evolution.OnManagerLogin', function () {
156230
ms_sso_load_functions();
@@ -196,9 +270,16 @@ function ms_sso_load_functions(): void {
196270
});
197271

198272
/**
199-
* OnManagerLogout:
273+
* OnManagerLogout
274+
*
200275
* Builds a "run plan" to logout on other domains.
201-
* Stores runId in a cookie so we can start from OnManagerWelcomeHome.
276+
* Stores runId in a cookie so we can start from evolution.OnManagerWelcomeHome (session may be gone).
277+
*
278+
* Notes:
279+
* - Tokens are short-lived and include mode/logout and host.
280+
* - Cookie is intentionally not HttpOnly to allow JS-less redirections.
281+
*
282+
* @return void
202283
*/
203284
Event::listen('evolution.OnManagerLogout', function () {
204285
ms_sso_load_functions();
@@ -237,9 +318,12 @@ function ms_sso_load_functions(): void {
237318
});
238319

239320
/**
240-
* OnManagerWelcomeHome:
321+
* OnManagerWelcomeHome
322+
*
241323
* Kicks off the run (login/logout) in the same tab using location.replace().
242-
* We pass "ret" (final Manager URL) so the flow comes back automatically.
324+
* Passes "ret" (final Manager URL) so the flow returns automatically.
325+
*
326+
* @return void
243327
*/
244328
Event::listen('evolution.OnManagerWelcomeHome', function () {
245329
ms_sso_load_functions();
@@ -296,11 +380,17 @@ function ms_sso_load_functions(): void {
296380
});
297381

298382
/**
299-
* OnBeforeLoadDocumentObject:
383+
* OnBeforeLoadDocumentObject
384+
*
300385
* Implements service endpoints:
301-
* - /_ms-run, /_ms-run-logout → runners (sequence executor across domains)
302-
* - /_ms-sso, /_ms-sso-logout → receivers (set/unset SID and bounce to next/ret)
303-
* Has <meta refresh> fallback and blocks preloads to avoid consuming tokens prematurely.
386+
* - /_ms-run, /_ms-run-logout Runner endpoints (sequence executor across domains)
387+
* - /_ms-sso, /_ms-sso-logout Receiver endpoints (set/unset SID and bounce to next/ret)
388+
*
389+
* Security/behavior:
390+
* - Has <meta refresh> fallback for no-JS.
391+
* - Blocks speculative preloads/prerenders to avoid consuming one-shot tokens prematurely.
392+
*
393+
* @return void
304394
*/
305395
Event::listen('evolution.OnBeforeLoadDocumentObject', function () {
306396
$uri = strtok($_SERVER['REQUEST_URI'] ?? '/', '?');
@@ -503,8 +593,37 @@ function ms_sso_load_functions(): void {
503593
});
504594

505595
/**
506-
* OnManagerTreeRender:
507-
* Renders extra root nodes for each domain in the Resources tree.
596+
* OnManagerTreePrerender
597+
*
598+
* Forces Manager tree context to the "default" domain settings.
599+
* This avoids Manager tree inconsistencies when switching documents/domains.
600+
*
601+
* @param array $params Event payload (unused)
602+
*
603+
* @return void
604+
*/
605+
Event::listen('evolution.OnManagerTreePrerender', function($params) {
606+
$domain = \Seiger\sMultisite\Models\sMultisite::where('key', 'default')->first();
607+
if ($domain) {
608+
evo()->setConfig('site_key', $domain->key);
609+
evo()->setConfig('site_name', $domain->site_name);
610+
evo()->setConfig('site_start', $domain->site_start);
611+
evo()->setConfig('error_page', $domain->error_page);
612+
evo()->setConfig('unauthorized_page', $domain->unauthorized_page);
613+
evo()->setConfig('site_root', (int)$domain->resource);
614+
evo()->setConfig('site_color', $domain->site_color);
615+
}
616+
});
617+
618+
/**
619+
* OnManagerTreeRender
620+
*
621+
* Renders extra root nodes for each domain in the Resources tree (except default).
622+
* Each domain is rendered as a "rootNode" container with its own treeRoot placeholder.
623+
*
624+
* @param array $params Event payload (unused)
625+
*
626+
* @return string|null HTML markup for extra roots, or null to keep default behavior
508627
*/
509628
Event::listen('evolution.OnManagerTreeRender', function($params) {
510629
$tree = '';
@@ -528,11 +647,22 @@ function ms_sso_load_functions(): void {
528647
});
529648

530649
/**
531-
* OnManagerNodePrerender:
532-
* Sets special icons and disables move for domain's key pages (home/error/unauthorized).
650+
* OnManagerNodePrerender
651+
*
652+
* Sets special icons and disables move for domain key pages:
653+
* - home (site_start)
654+
* - error_page
655+
* - unauthorized_page
656+
*
657+
* Also optionally marks sCommerce catalog root categories if enabled (check_sCommerce).
658+
*
659+
* @param array $params Event payload:
660+
* - array $params['ph'] Placeholder array for a node (must be returned serialized)
661+
*
662+
* @return string|null Serialized placeholders, or null to keep default behavior
533663
*/
534664
Event::listen('evolution.OnManagerNodePrerender', function($params) {
535-
$domains = \Seiger\sMultisite\Models\sMultisite::where('hide_from_tree', 0)->whereNot('key', 'default')->get();
665+
$domains = \Seiger\sMultisite\Models\sMultisite::where('hide_from_tree', 0)->get();
536666
if ($domains) {
537667
$_style = ManagerTheme::getStyle();
538668
$startResources = $domains->pluck('site_start')->toArray();
@@ -575,8 +705,15 @@ function ms_sso_load_functions(): void {
575705
});
576706

577707
/**
578-
* OnManagerNodeRender:
579-
* Hides root resources that act as domain containers from the tree.
708+
* OnManagerNodeRender
709+
*
710+
* Hides domain container root resources from the tree.
711+
* If the current node ID is one of sMultisite domain container resources, returns a blank string.
712+
*
713+
* @param array $params Event payload:
714+
* - int $params['id'] Node document ID
715+
*
716+
* @return string|null Blank string to hide, or null to keep default behavior
580717
*/
581718
Event::listen('evolution.OnManagerNodeRender', function($params) {
582719
$domains = \Seiger\sMultisite\Models\sMultisite::all();

views/partials/menu.blade.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<aside :class="open ? 'w-60' : 'w-16'" class="s-nav" @mouseenter="handleEnter" @mouseleave="handleLeave">
1+
<aside :class="open ? 'w-60' : 'w-16'" class="s-nav">
22
<div class="s-nav-header">
33
<a href="{{sMultisite::route('sMultisite.configure')}}" class="flex items-center gap-1 text-xl font-bold" x-show="open" x-cloak>
44
sMultisite

0 commit comments

Comments
 (0)