From 06771e5f1bd918b8479e612a17b9db943312865f Mon Sep 17 00:00:00 2001 From: Louis de Looze Date: Tue, 28 Apr 2026 09:03:13 +0200 Subject: [PATCH 1/2] Adds multistore parameter --- internal/config/types.go | 3 +- internal/nginx/templates/vhost.conf.tmpl | 4 ++ internal/nginx/vhost.go | 2 + internal/nginx/vhost_test.go | 63 ++++++++++++++++++++++++ lib/templates/nginx/vhost.conf.tmpl | 4 ++ 5 files changed, 75 insertions(+), 1 deletion(-) diff --git a/internal/config/types.go b/internal/config/types.go index ca4ea08..81d3bbc 100644 --- a/internal/config/types.go +++ b/internal/config/types.go @@ -20,7 +20,8 @@ type Config struct { Domains []Domain `yaml:"domains"` PHP string `yaml:"php"` PHPINI map[string]string `yaml:"php_ini,omitempty"` - Isolated bool `yaml:"isolated,omitempty"` // Use dedicated PHP-FPM master for this project + Isolated bool `yaml:"isolated,omitempty"` // Use dedicated PHP-FPM master for this project + MultiStore bool `yaml:"multi_store,omitempty"` // Inject MAGE_RUN_CODE/MAGE_RUN_TYPE into Nginx config Services Services `yaml:"services"` Env map[string]string `yaml:"env,omitempty"` Commands map[string]Command `yaml:"commands,omitempty"` diff --git a/internal/nginx/templates/vhost.conf.tmpl b/internal/nginx/templates/vhost.conf.tmpl index d4e494a..5f3c7e1 100644 --- a/internal/nginx/templates/vhost.conf.tmpl +++ b/internal/nginx/templates/vhost.conf.tmpl @@ -106,8 +106,10 @@ server { set $MAGE_ROOT {{.DocumentRoot}}; set $MAGE_MODE developer; +{{- if .MultiStore}} set $MAGE_RUN_CODE {{.StoreCode}}; set $MAGE_RUN_TYPE {{.MageRunType}}; +{{- end}} root $MAGE_ROOT; index index.php; @@ -221,8 +223,10 @@ server { fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; +{{- if .MultiStore}} fastcgi_param MAGE_RUN_CODE $MAGE_RUN_CODE; fastcgi_param MAGE_RUN_TYPE $MAGE_RUN_TYPE; +{{- end}} include fastcgi_params; } diff --git a/internal/nginx/vhost.go b/internal/nginx/vhost.go index 8fd0592..b9ba149 100644 --- a/internal/nginx/vhost.go +++ b/internal/nginx/vhost.go @@ -74,6 +74,7 @@ type VhostConfig struct { HTTPSPort int // 443 on Linux, 8443 on macOS (port forwarding) BackendPort int // Backend port for Varnish (always 8080 when Varnish enabled) EnableIPv6 bool // true on Linux to add [::]:port listen directives + MultiStore bool // Inject MAGE_RUN_CODE/MAGE_RUN_TYPE into Nginx config (default: false) StoreCode string // Magento store code for multi-store setup (default: "default") MageRunType string // Magento run type: "store" or "website" (default: "store") AccessLog string // Path to access log file @@ -167,6 +168,7 @@ func (g *VhostGenerator) Generate(cfg *config.Config, projectPath string) error HTTPSPort: httpsPort, BackendPort: backendPort, EnableIPv6: enableIPv6, + MultiStore: cfg.MultiStore, StoreCode: domain.GetStoreCode(), MageRunType: domain.GetMageRunType(), AccessLog: filepath.Join(logsDir, fmt.Sprintf("%s-access.log", sanitizedDomain)), diff --git a/internal/nginx/vhost_test.go b/internal/nginx/vhost_test.go index 886c9f0..4500e28 100644 --- a/internal/nginx/vhost_test.go +++ b/internal/nginx/vhost_test.go @@ -287,6 +287,69 @@ func TestRenderVhost_SSLEnabled_NoIPv6(t *testing.T) { } } +func TestRenderVhost_MultiStoreDisabled(t *testing.T) { + g, tmpDir := setupTestGenerator(t) + + cfg := VhostConfig{ + ProjectName: "mystore", + Domain: "mystore.test", + DocumentRoot: "/var/www/mystore/pub", + PHPVersion: "8.2", + PHPSocketPath: filepath.Join(tmpDir, ".magebox", "run", "mystore-php8.2.sock"), + MultiStore: false, + StoreCode: "mystore", + MageRunType: "website", + HTTPPort: 80, + HTTPSPort: 443, + } + + content, err := g.renderVhost(cfg) + if err != nil { + t.Fatalf("renderVhost failed: %v", err) + } + + if strings.Contains(content, "MAGE_RUN_CODE") { + t.Error("Vhost with MultiStore=false should not contain MAGE_RUN_CODE") + } + if strings.Contains(content, "MAGE_RUN_TYPE") { + t.Error("Vhost with MultiStore=false should not contain MAGE_RUN_TYPE") + } +} + +func TestRenderVhost_MultiStoreEnabled(t *testing.T) { + g, tmpDir := setupTestGenerator(t) + + cfg := VhostConfig{ + ProjectName: "mystore", + Domain: "mystore.test", + DocumentRoot: "/var/www/mystore/pub", + PHPVersion: "8.2", + PHPSocketPath: filepath.Join(tmpDir, ".magebox", "run", "mystore-php8.2.sock"), + MultiStore: true, + StoreCode: "mystore_en", + MageRunType: "website", + HTTPPort: 80, + HTTPSPort: 443, + } + + content, err := g.renderVhost(cfg) + if err != nil { + t.Fatalf("renderVhost failed: %v", err) + } + + checks := []string{ + "set $MAGE_RUN_CODE mystore_en", + "set $MAGE_RUN_TYPE website", + "fastcgi_param MAGE_RUN_CODE $MAGE_RUN_CODE", + "fastcgi_param MAGE_RUN_TYPE $MAGE_RUN_TYPE", + } + for _, check := range checks { + if !strings.Contains(content, check) { + t.Errorf("Vhost with MultiStore=true should contain %q", check) + } + } +} + func TestRenderVhost_SSLDisabled(t *testing.T) { g, tmpDir := setupTestGenerator(t) diff --git a/lib/templates/nginx/vhost.conf.tmpl b/lib/templates/nginx/vhost.conf.tmpl index d4e494a..5f3c7e1 100644 --- a/lib/templates/nginx/vhost.conf.tmpl +++ b/lib/templates/nginx/vhost.conf.tmpl @@ -106,8 +106,10 @@ server { set $MAGE_ROOT {{.DocumentRoot}}; set $MAGE_MODE developer; +{{- if .MultiStore}} set $MAGE_RUN_CODE {{.StoreCode}}; set $MAGE_RUN_TYPE {{.MageRunType}}; +{{- end}} root $MAGE_ROOT; index index.php; @@ -221,8 +223,10 @@ server { fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; +{{- if .MultiStore}} fastcgi_param MAGE_RUN_CODE $MAGE_RUN_CODE; fastcgi_param MAGE_RUN_TYPE $MAGE_RUN_TYPE; +{{- end}} include fastcgi_params; } From 050d881130ac7ccdc48acc5df5f89ce10b1b864d Mon Sep 17 00:00:00 2001 From: Louis de Looze Date: Thu, 14 May 2026 08:11:52 +0200 Subject: [PATCH 2/2] Remove multistore + implement map --- cmd/magebox/domain.go | 19 ++-- internal/config/types.go | 35 +++---- internal/lib/templates.go | 1 + internal/nginx/templates/map.conf.tmpl | 17 ++++ internal/nginx/templates/vhost.conf.tmpl | 10 +- internal/nginx/vhost.go | 59 +++++++++-- internal/nginx/vhost_test.go | 124 ++++++++++++++++++++--- lib/templates/nginx/map.conf.tmpl | 17 ++++ lib/templates/nginx/vhost.conf.tmpl | 10 +- 9 files changed, 234 insertions(+), 58 deletions(-) create mode 100644 internal/nginx/templates/map.conf.tmpl create mode 100644 lib/templates/nginx/map.conf.tmpl diff --git a/cmd/magebox/domain.go b/cmd/magebox/domain.go index 5f4b687..5da1dd1 100644 --- a/cmd/magebox/domain.go +++ b/cmd/magebox/domain.go @@ -53,12 +53,14 @@ var domainListCmd = &cobra.Command{ var ( domainStoreCode string + domainStoreType string domainRoot string domainSSL bool ) func init() { - domainAddCmd.Flags().StringVar(&domainStoreCode, "store-code", "", "Magento store code (default: \"default\")") + domainAddCmd.Flags().StringVar(&domainStoreCode, "store-code", "", "Magento store/website code for multi-store setup") + domainAddCmd.Flags().StringVar(&domainStoreType, "store-type", "", "Magento run type: \"store\" or \"website\" (default: \"store\")") domainAddCmd.Flags().StringVar(&domainRoot, "root", "", "Document root relative to project (default: \"pub\" for Magento, \"public\" for Laravel)") domainAddCmd.Flags().BoolVar(&domainSSL, "ssl", true, "Enable SSL for the domain") @@ -92,9 +94,10 @@ func runDomainAdd(cmd *cobra.Command, args []string) error { // Create new domain newDomain := config.Domain{ - Host: host, - Root: domainRoot, - MageRunCode: domainStoreCode, + Host: host, + Root: domainRoot, + StoreCode: domainStoreCode, + StoreType: domainStoreType, } // Only set SSL if explicitly changed from default (true) @@ -163,7 +166,9 @@ func runDomainAdd(cmd *cobra.Command, args []string) error { } fmt.Println() - cli.PrintInfo("Domain %s configured with store code: %s", host, newDomain.GetStoreCode()) + if newDomain.StoreCode != "" { + cli.PrintInfo("Domain %s configured with store code: %s (%s)", host, newDomain.StoreCode, newDomain.GetStoreType()) + } return nil } @@ -284,7 +289,9 @@ func runDomainList(cmd *cobra.Command, args []string) error { fmt.Printf(" %s\n", cli.Highlight(d.Host)) fmt.Printf(" URL: %s://%s\n", protocol, d.Host) fmt.Printf(" Root: %s\n", d.GetRoot()) - fmt.Printf(" Store Code: %s\n", d.GetStoreCode()) + if d.StoreCode != "" { + fmt.Printf(" Store Code: %s (%s)\n", d.StoreCode, d.GetStoreType()) + } fmt.Printf(" SSL: %s\n", sslStatus) fmt.Println() } diff --git a/internal/config/types.go b/internal/config/types.go index 81d3bbc..c1aa867 100644 --- a/internal/config/types.go +++ b/internal/config/types.go @@ -20,8 +20,7 @@ type Config struct { Domains []Domain `yaml:"domains"` PHP string `yaml:"php"` PHPINI map[string]string `yaml:"php_ini,omitempty"` - Isolated bool `yaml:"isolated,omitempty"` // Use dedicated PHP-FPM master for this project - MultiStore bool `yaml:"multi_store,omitempty"` // Inject MAGE_RUN_CODE/MAGE_RUN_TYPE into Nginx config + Isolated bool `yaml:"isolated,omitempty"` // Use dedicated PHP-FPM master for this project Services Services `yaml:"services"` Env map[string]string `yaml:"env,omitempty"` Commands map[string]Command `yaml:"commands,omitempty"` @@ -174,11 +173,11 @@ func (c *Command) UnmarshalYAML(unmarshal func(interface{}) error) error { // Domain represents a domain configuration type Domain struct { - Host string `yaml:"host"` - Root string `yaml:"root,omitempty"` - SSL *bool `yaml:"ssl,omitempty"` - MageRunCode string `yaml:"mage_run_code,omitempty"` // Magento store/website code for multi-store setup - MageRunType string `yaml:"mage_run_type,omitempty"` // "store" or "website" (default: "store") + Host string `yaml:"host"` + Root string `yaml:"root,omitempty"` + SSL *bool `yaml:"ssl,omitempty"` + StoreCode string `yaml:"store_code,omitempty"` // Magento store/website code for multi-store setup + StoreType string `yaml:"store_type,omitempty"` // "store" or "website" (default: "store") } // Services represents the services configuration @@ -321,20 +320,22 @@ func (d *Domain) IsSSLEnabled() bool { return *d.SSL } -// GetStoreCode returns the Magento store code, defaulting to "default" -func (d *Domain) GetStoreCode() string { - if d.MageRunCode == "" { - return "default" +// GetStoreType returns the Magento run type, defaulting to "store" +func (d *Domain) GetStoreType() string { + if d.StoreType == "" { + return "store" } - return d.MageRunCode + return d.StoreType } -// GetMageRunType returns the Magento run type, defaulting to "store" -func (d *Domain) GetMageRunType() string { - if d.MageRunType == "" { - return "store" +// HasMultiStore returns true if any domain has a store code configured +func (c *Config) HasMultiStore() bool { + for _, d := range c.Domains { + if d.StoreCode != "" { + return true + } } - return d.MageRunType + return false } // Validate checks if the configuration is valid diff --git a/internal/lib/templates.go b/internal/lib/templates.go index e357883..d665cc6 100644 --- a/internal/lib/templates.go +++ b/internal/lib/templates.go @@ -100,6 +100,7 @@ var TemplateNames = map[string][]string{ "vhost.conf.tmpl", "proxy.conf.tmpl", "upstream.conf.tmpl", + "map.conf.tmpl", }, TemplatePHP: { "pool.conf.tmpl", diff --git a/internal/nginx/templates/map.conf.tmpl b/internal/nginx/templates/map.conf.tmpl new file mode 100644 index 0000000..6d1a360 --- /dev/null +++ b/internal/nginx/templates/map.conf.tmpl @@ -0,0 +1,17 @@ +# MageBox multi-store map for {{.ProjectName}} +# Generated from store_code settings in domains configuration +# Do not edit manually - regenerated on magebox start + +map $host $MAGE_RUN_CODE { + hostnames; +{{- range .Domains}}{{if .StoreCode}} + .{{.Host}} {{.StoreCode}}; +{{- end}}{{end}} +} + +map $host $MAGE_RUN_TYPE { + hostnames; +{{- range .Domains}}{{if .StoreCode}} + .{{.Host}} {{.GetStoreType}}; +{{- end}}{{end}} +} diff --git a/internal/nginx/templates/vhost.conf.tmpl b/internal/nginx/templates/vhost.conf.tmpl index 5f3c7e1..b83babf 100644 --- a/internal/nginx/templates/vhost.conf.tmpl +++ b/internal/nginx/templates/vhost.conf.tmpl @@ -106,10 +106,6 @@ server { set $MAGE_ROOT {{.DocumentRoot}}; set $MAGE_MODE developer; -{{- if .MultiStore}} - set $MAGE_RUN_CODE {{.StoreCode}}; - set $MAGE_RUN_TYPE {{.MageRunType}}; -{{- end}} root $MAGE_ROOT; index index.php; @@ -223,9 +219,9 @@ server { fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; -{{- if .MultiStore}} - fastcgi_param MAGE_RUN_CODE $MAGE_RUN_CODE; - fastcgi_param MAGE_RUN_TYPE $MAGE_RUN_TYPE; +{{- if .HasStoreCodes}} + fastcgi_param MAGE_RUN_CODE $MAGE_RUN_CODE if_not_empty; + fastcgi_param MAGE_RUN_TYPE $MAGE_RUN_TYPE if_not_empty; {{- end}} include fastcgi_params; } diff --git a/internal/nginx/vhost.go b/internal/nginx/vhost.go index b9ba149..17dc991 100644 --- a/internal/nginx/vhost.go +++ b/internal/nginx/vhost.go @@ -29,12 +29,16 @@ var proxyTemplateEmbed string //go:embed templates/upstream.conf.tmpl var upstreamTemplateEmbed string +//go:embed templates/map.conf.tmpl +var mapTemplateEmbed string + func init() { // Register embedded templates as fallbacks lib.RegisterFallbackTemplate(lib.TemplateNginx, "vhost.conf.tmpl", vhostTemplateEmbed) lib.RegisterFallbackTemplate(lib.TemplateNginx, "vhost-laravel.conf.tmpl", vhostLaravelTemplateEmbed) lib.RegisterFallbackTemplate(lib.TemplateNginx, "proxy.conf.tmpl", proxyTemplateEmbed) lib.RegisterFallbackTemplate(lib.TemplateNginx, "upstream.conf.tmpl", upstreamTemplateEmbed) + lib.RegisterFallbackTemplate(lib.TemplateNginx, "map.conf.tmpl", mapTemplateEmbed) } // Template variables available in vhost.conf.tmpl: @@ -74,14 +78,18 @@ type VhostConfig struct { HTTPSPort int // 443 on Linux, 8443 on macOS (port forwarding) BackendPort int // Backend port for Varnish (always 8080 when Varnish enabled) EnableIPv6 bool // true on Linux to add [::]:port listen directives - MultiStore bool // Inject MAGE_RUN_CODE/MAGE_RUN_TYPE into Nginx config (default: false) - StoreCode string // Magento store code for multi-store setup (default: "default") - MageRunType string // Magento run type: "store" or "website" (default: "store") + HasStoreCodes bool // True when any domain has a store_code; enables MAGE_RUN_* fastcgi params AccessLog string // Path to access log file ErrorLog string // Path to error log file CustomNginxDir string // Path to project-level custom nginx snippets directory (if it exists) } +// MapConfig contains data needed to generate the multi-store map config +type MapConfig struct { + ProjectName string + Domains []config.Domain +} + // ProxyConfig contains data needed to generate a proxy vhost type ProxyConfig struct { Name string @@ -133,6 +141,18 @@ func (g *VhostGenerator) Generate(cfg *config.Config, projectPath string) error return fmt.Errorf("failed to generate upstream config: %w", err) } + // Generate or remove the multi-store map config depending on whether any domain has a store_code + hasStoreCodes := cfg.HasMultiStore() + mapFile := filepath.Join(g.vhostsDir, fmt.Sprintf("%s-map.conf", cfg.Name)) + if hasStoreCodes { + mapCfg := MapConfig{ProjectName: cfg.Name, Domains: cfg.Domains} + if err := g.generateMap(mapCfg, mapFile); err != nil { + return fmt.Errorf("failed to generate map config: %w", err) + } + } else { + os.Remove(mapFile) // clean up stale map file if store codes were removed + } + // Determine ports based on platform // macOS uses port forwarding (80->8080, 443->8443), Linux uses standard ports httpPort := 80 @@ -168,9 +188,7 @@ func (g *VhostGenerator) Generate(cfg *config.Config, projectPath string) error HTTPSPort: httpsPort, BackendPort: backendPort, EnableIPv6: enableIPv6, - MultiStore: cfg.MultiStore, - StoreCode: domain.GetStoreCode(), - MageRunType: domain.GetMageRunType(), + HasStoreCodes: hasStoreCodes, AccessLog: filepath.Join(logsDir, fmt.Sprintf("%s-access.log", sanitizedDomain)), ErrorLog: filepath.Join(logsDir, fmt.Sprintf("%s-error.log", sanitizedDomain)), } @@ -271,6 +289,35 @@ func (g *VhostGenerator) renderVhost(cfg VhostConfig) (string, error) { return buf.String(), nil } +// generateMap generates the multi-store map config file +func (g *VhostGenerator) generateMap(cfg MapConfig, destFile string) error { + content, err := g.renderMap(cfg) + if err != nil { + return err + } + return os.WriteFile(destFile, []byte(content), 0644) +} + +// renderMap renders the map template +func (g *VhostGenerator) renderMap(cfg MapConfig) (string, error) { + tmplContent, err := lib.GetTemplate(lib.TemplateNginx, "map.conf.tmpl") + if err != nil { + return "", err + } + + tmpl, err := template.New("map").Parse(tmplContent) + if err != nil { + return "", err + } + + var buf bytes.Buffer + if err := tmpl.Execute(&buf, cfg); err != nil { + return "", err + } + + return buf.String(), nil +} + // generateUpstream generates the upstream config file for a project func (g *VhostGenerator) generateUpstream(cfg UpstreamConfig) error { content, err := g.renderUpstream(cfg) diff --git a/internal/nginx/vhost_test.go b/internal/nginx/vhost_test.go index 4500e28..2623d10 100644 --- a/internal/nginx/vhost_test.go +++ b/internal/nginx/vhost_test.go @@ -287,7 +287,7 @@ func TestRenderVhost_SSLEnabled_NoIPv6(t *testing.T) { } } -func TestRenderVhost_MultiStoreDisabled(t *testing.T) { +func TestRenderVhost_NoStoreCodes(t *testing.T) { g, tmpDir := setupTestGenerator(t) cfg := VhostConfig{ @@ -296,9 +296,7 @@ func TestRenderVhost_MultiStoreDisabled(t *testing.T) { DocumentRoot: "/var/www/mystore/pub", PHPVersion: "8.2", PHPSocketPath: filepath.Join(tmpDir, ".magebox", "run", "mystore-php8.2.sock"), - MultiStore: false, - StoreCode: "mystore", - MageRunType: "website", + HasStoreCodes: false, HTTPPort: 80, HTTPSPort: 443, } @@ -309,14 +307,17 @@ func TestRenderVhost_MultiStoreDisabled(t *testing.T) { } if strings.Contains(content, "MAGE_RUN_CODE") { - t.Error("Vhost with MultiStore=false should not contain MAGE_RUN_CODE") + t.Error("Vhost without store codes should not contain MAGE_RUN_CODE") } if strings.Contains(content, "MAGE_RUN_TYPE") { - t.Error("Vhost with MultiStore=false should not contain MAGE_RUN_TYPE") + t.Error("Vhost without store codes should not contain MAGE_RUN_TYPE") + } + if strings.Contains(content, "set $MAGE_RUN") { + t.Error("Vhost without store codes should not contain set $MAGE_RUN_* directives") } } -func TestRenderVhost_MultiStoreEnabled(t *testing.T) { +func TestRenderVhost_WithStoreCodes(t *testing.T) { g, tmpDir := setupTestGenerator(t) cfg := VhostConfig{ @@ -325,9 +326,7 @@ func TestRenderVhost_MultiStoreEnabled(t *testing.T) { DocumentRoot: "/var/www/mystore/pub", PHPVersion: "8.2", PHPSocketPath: filepath.Join(tmpDir, ".magebox", "run", "mystore-php8.2.sock"), - MultiStore: true, - StoreCode: "mystore_en", - MageRunType: "website", + HasStoreCodes: true, HTTPPort: 80, HTTPSPort: 443, } @@ -338,16 +337,111 @@ func TestRenderVhost_MultiStoreEnabled(t *testing.T) { } checks := []string{ - "set $MAGE_RUN_CODE mystore_en", - "set $MAGE_RUN_TYPE website", - "fastcgi_param MAGE_RUN_CODE $MAGE_RUN_CODE", - "fastcgi_param MAGE_RUN_TYPE $MAGE_RUN_TYPE", + "fastcgi_param MAGE_RUN_CODE $MAGE_RUN_CODE if_not_empty", + "fastcgi_param MAGE_RUN_TYPE $MAGE_RUN_TYPE if_not_empty", + } + for _, check := range checks { + if !strings.Contains(content, check) { + t.Errorf("Vhost with store codes should contain %q", check) + } + } + // map-based setup: no set directives in the server block + if strings.Contains(content, "set $MAGE_RUN_CODE") { + t.Error("Vhost should not use set $MAGE_RUN_CODE (handled by map block)") + } +} + +func TestRenderMap(t *testing.T) { + g, _ := setupTestGenerator(t) + + cfg := MapConfig{ + ProjectName: "mystore", + Domains: []config.Domain{ + {Host: "mystore.test", StoreCode: "default"}, + {Host: "de.mystore.test", StoreCode: "german"}, + {Host: "fr.mystore.test", StoreCode: "french", StoreType: "website"}, + {Host: "admin.mystore.test"}, // no store code — should be omitted + }, + } + + content, err := g.renderMap(cfg) + if err != nil { + t.Fatalf("renderMap failed: %v", err) + } + + checks := []string{ + "map $host $MAGE_RUN_CODE", + "map $host $MAGE_RUN_TYPE", + "hostnames;", + ".mystore.test default", + ".de.mystore.test german", + ".fr.mystore.test french", + ".fr.mystore.test website", } for _, check := range checks { if !strings.Contains(content, check) { - t.Errorf("Vhost with MultiStore=true should contain %q", check) + t.Errorf("Map content should contain %q\nGot:\n%s", check, content) } } + + // Domains without store code should not appear in the map + if strings.Contains(content, "admin.mystore.test") { + t.Error("Domain without store code should not appear in map") + } + // Default store type should be "store" + if !strings.Contains(content, ".mystore.test store") { + t.Error("Domain with no store_type should default to store in MAGE_RUN_TYPE map") + } +} + +func TestGenerate_CreatesMapFileWhenStoreCodesPresent(t *testing.T) { + g, tmpDir := setupTestGenerator(t) + + projectPath := filepath.Join(tmpDir, "projects", "mystore") + cfg := &config.Config{ + Name: "mystore", + Domains: []config.Domain{ + {Host: "mystore.test", Root: "pub", StoreCode: "default"}, + {Host: "de.mystore.test", Root: "pub", StoreCode: "german"}, + }, + PHP: "8.2", + } + + if err := g.Generate(cfg, projectPath); err != nil { + t.Fatalf("Generate failed: %v", err) + } + + mapFile := filepath.Join(g.vhostsDir, "mystore-map.conf") + if _, err := os.Stat(mapFile); os.IsNotExist(err) { + t.Error("Map file should have been created when store codes are present") + } + + content, _ := os.ReadFile(mapFile) + if !strings.Contains(string(content), "map $host $MAGE_RUN_CODE") { + t.Error("Map file should contain MAGE_RUN_CODE map block") + } +} + +func TestGenerate_NoMapFileWithoutStoreCodes(t *testing.T) { + g, tmpDir := setupTestGenerator(t) + + projectPath := filepath.Join(tmpDir, "projects", "mystore") + cfg := &config.Config{ + Name: "mystore", + Domains: []config.Domain{ + {Host: "mystore.test", Root: "pub"}, + }, + PHP: "8.2", + } + + if err := g.Generate(cfg, projectPath); err != nil { + t.Fatalf("Generate failed: %v", err) + } + + mapFile := filepath.Join(g.vhostsDir, "mystore-map.conf") + if _, err := os.Stat(mapFile); !os.IsNotExist(err) { + t.Error("Map file should NOT be created when no store codes are configured") + } } func TestRenderVhost_SSLDisabled(t *testing.T) { diff --git a/lib/templates/nginx/map.conf.tmpl b/lib/templates/nginx/map.conf.tmpl new file mode 100644 index 0000000..6d1a360 --- /dev/null +++ b/lib/templates/nginx/map.conf.tmpl @@ -0,0 +1,17 @@ +# MageBox multi-store map for {{.ProjectName}} +# Generated from store_code settings in domains configuration +# Do not edit manually - regenerated on magebox start + +map $host $MAGE_RUN_CODE { + hostnames; +{{- range .Domains}}{{if .StoreCode}} + .{{.Host}} {{.StoreCode}}; +{{- end}}{{end}} +} + +map $host $MAGE_RUN_TYPE { + hostnames; +{{- range .Domains}}{{if .StoreCode}} + .{{.Host}} {{.GetStoreType}}; +{{- end}}{{end}} +} diff --git a/lib/templates/nginx/vhost.conf.tmpl b/lib/templates/nginx/vhost.conf.tmpl index 5f3c7e1..b83babf 100644 --- a/lib/templates/nginx/vhost.conf.tmpl +++ b/lib/templates/nginx/vhost.conf.tmpl @@ -106,10 +106,6 @@ server { set $MAGE_ROOT {{.DocumentRoot}}; set $MAGE_MODE developer; -{{- if .MultiStore}} - set $MAGE_RUN_CODE {{.StoreCode}}; - set $MAGE_RUN_TYPE {{.MageRunType}}; -{{- end}} root $MAGE_ROOT; index index.php; @@ -223,9 +219,9 @@ server { fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; -{{- if .MultiStore}} - fastcgi_param MAGE_RUN_CODE $MAGE_RUN_CODE; - fastcgi_param MAGE_RUN_TYPE $MAGE_RUN_TYPE; +{{- if .HasStoreCodes}} + fastcgi_param MAGE_RUN_CODE $MAGE_RUN_CODE if_not_empty; + fastcgi_param MAGE_RUN_TYPE $MAGE_RUN_TYPE if_not_empty; {{- end}} include fastcgi_params; }