Skip to content

Commit 2f7af4c

Browse files
scqcodyfinegan
authored andcommitted
feat: Support subdirectories/behat with front controller
1 parent 1f4d3a3 commit 2f7af4c

5 files changed

Lines changed: 60 additions & 6 deletions

File tree

apache/conf.d/server.conf

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,33 @@ RewriteRule \.php - [H=proxy:fcgi://php-%1.%2-debug:9000]
3737
RewriteCond %{HTTP_HOST} ^([\w-]+)\.totara\d
3838
RewriteRule ^ - [E=SITENAME:%1]
3939

40+
# Path-based multisite support (front-controller / v21+ sites only).
41+
# In addition to the subdomain form (mysite.totara83.localhost/foobar), allow the
42+
# path form totara83.localhost/mysite/foobar. This only applies when no sitename was
43+
# supplied as a subdomain; capture the first path segment as the candidate site.
44+
# Unlike the subdomain form, the /<site> prefix stays in the request URI so that
45+
# SCRIPT_NAME keeps the /<site> prefix once the request reaches the front controller.
46+
RewriteCond %{ENV:SITENAME} ^$
47+
RewriteCond %{REQUEST_URI} ^/([\w-]+)
48+
RewriteRule ^ - [E=PATHSITE:%1]
49+
50+
# v21+ front controller (path form): totara83.localhost/mysite/foobar.
51+
# Checked before the subdomain form below so a real path-based site takes precedence
52+
# over the base site's own front controller. Only matches when the candidate site has
53+
# a public/ webroot (front-controller / v21+ install). The host condition that captures
54+
# the php version is kept last so its %1.%2 backrefs survive into the RewriteRule.
55+
RewriteCond %{HTTP_HOST} !\.debug
56+
RewriteCond %{ENV:PATHSITE} ^.+$
57+
RewriteCond %{DOCUMENT_ROOT}/%{ENV:PATHSITE}/public/index.php -f
58+
RewriteCond %{HTTP_HOST} totara(\d)(\d)
59+
RewriteRule ^ %{DOCUMENT_ROOT}/%{ENV:PATHSITE}/public/index.php [QSA,L,H=proxy:fcgi://php-%1.%2:9000]
60+
61+
# v21+ front controller (path form, debug variant): routes to the debug PHP-FPM container
62+
RewriteCond %{ENV:PATHSITE} ^.+$
63+
RewriteCond %{DOCUMENT_ROOT}/%{ENV:PATHSITE}/public/index.php -f
64+
RewriteCond %{HTTP_HOST} totara(\d)(\d).*\.debug
65+
RewriteRule ^ %{DOCUMENT_ROOT}/%{ENV:PATHSITE}/public/index.php [QSA,L,H=proxy:fcgi://php-%1.%2-debug:9000]
66+
4067
# v21+ (public/ directory exists): route all requests through the front controller.
4168
# The [H=proxy:...] flag is set here (not only for .php URLs) so that requests like /
4269
# or static-looking URLs are also processed by PHP-FPM via public/index.php.

nginx/config/local-server.conf

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ include totara/server.conf;
88
client_max_body_size 1G;
99

1010
location / {
11-
# Redirect non-existing files to index.php for "pretty" URLs
11+
# Redirect non-existing files to the front controller for "pretty" URLs.
1212
# For v21+ installs (public/ webroot), all PHP requests are routed through
13-
# public/index.php (the front controller).
13+
# public/index.php (the front controller).
1414
# For v13-20 installs the real script exists under server/ and is served directly.
15-
try_files $uri $uri/ /index.php?$query_string;
15+
# $front_controller is /index.php normally, or /<site>/index.php for path-based
16+
# sites (see server.conf) so SCRIPT_NAME keeps the /<site> prefix.
17+
try_files $uri $uri/ $front_controller?$query_string;
1618
}
1719

1820
location ~ [^/]\.php(/|$) {
@@ -45,5 +47,5 @@ location ~ [^/]\.php(/|$) {
4547
location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt)$ {
4648
access_log off;
4749
expires max;
48-
try_files $uri /index.php?$query_string;
50+
try_files $uri $front_controller?$query_string;
4951
}

nginx/config/server.conf

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,27 @@ if ($sitename != "") {
3131
set $base_rootdir $base_rootdir/$sitename;
3232
}
3333

34+
# Path-based multisite support (front-controller / v21+ sites only).
35+
# In addition to the subdomain form (mysite.totara83.localhost/foobar), allow the
36+
# path form totara83.localhost/mysite/foobar.
37+
set $path_site "";
38+
if ($request_uri ~ "^/([\w-]+)") {
39+
set $path_site $1;
40+
}
41+
# The front controller URI used as the try_files fallback for "pretty"/modern-routed
42+
# URLs that don't map to a real file. For path-based sites it must include the /<site>
43+
# prefix so that, after the internal redirect, SCRIPT_NAME becomes /<site>/index.php
44+
# rather than /index.php.
45+
set $front_controller "/index.php";
46+
set $path_route "${sitename}::";
47+
if (-f "$REMOTE_SRC/$path_site/public/index.php") {
48+
set $path_route "${sitename}::fc";
49+
}
50+
if ($path_route = "::fc") {
51+
set $base_rootdir "$REMOTE_SRC/$path_site";
52+
set $front_controller "/$path_site/index.php";
53+
}
54+
3455
set $use_front_controller 0;
3556
set $rootdir $base_rootdir;
3657

php/includes/config-after.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
if ($DOCKER_DEV->is_multi_site) {
6565
$CFG->behat_wwwroot .= '/' . $DOCKER_DEV->site_name;
6666
}
67-
if ($DOCKER_DEV->has_server_dir) {
67+
if ($DOCKER_DEV->has_server_dir && !$DOCKER_DEV->has_front_controller) {
6868
$CFG->behat_wwwroot .= '/server';
6969
}
7070

@@ -269,7 +269,10 @@
269269

270270
if ($DOCKER_DEV->is_multi_site && strpos($hostname, $DOCKER_DEV->site_name) === false) {
271271
$CFG->wwwroot .= '/' . $DOCKER_DEV->site_name;
272-
if ($DOCKER_DEV->has_server_dir) {
272+
// Front-controller sites (v21+) serve from public/ and strip the /<site> base
273+
// path themselves, so /server must not be part of the wwwroot. Only legacy sites
274+
// (server/ webroot, no front controller) are served under /<site>/server.
275+
if ($DOCKER_DEV->has_server_dir && !$DOCKER_DEV->has_front_controller) {
273276
$CFG->wwwroot .= '/server';
274277
}
275278
}

php/includes/config-before.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
// Docker-dev specific variable setup
77
$DOCKER_DEV->has_server_dir = file_exists($DOCKER_DEV->dir . '/server/config.php');
8+
$DOCKER_DEV->has_front_controller = file_exists($DOCKER_DEV->dir . '/public/index.php');
89
$DOCKER_DEV->is_multi_site = $DOCKER_DEV->dir !== '/var/www/totara/src';
910
$DOCKER_DEV->site_name = $DOCKER_DEV->is_multi_site ? basename($DOCKER_DEV->dir) : 'totara';
1011

0 commit comments

Comments
 (0)