diff --git a/models/repo/repo_manifest.go b/models/repo/repo_manifest.go index 989342530c..0934b33ff1 100644 --- a/models/repo/repo_manifest.go +++ b/models/repo/repo_manifest.go @@ -5,6 +5,7 @@ package repo import ( "context" + "strings" "code.mokoconsulting.tech/MokoConsulting/MokoGitea/models/db" "code.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/timeutil" @@ -60,25 +61,42 @@ func (RepoManifest) TableName() string { } // joomlaTypePrefix maps Joomla extension types to their element name prefixes. +// Derived from Joomla 6 source: libraries/src/Installer/Adapter/*Adapter.php +// Plugins use bare names (no prefix) — Joomla stores them as just the element name. var joomlaTypePrefix = map[string]string{ "component": "com_", "module": "mod_", - "plugin": "plg_", "package": "pkg_", "template": "tpl_", "library": "lib_", "file": "file_", } -// AutoElementName returns the auto-constructed Joomla element name (e.g. pkg_mokowaas). +// cleanJoomlaElement replicates Joomla's InputFilter::clean($value, 'cmd') +// which lowercases and strips all characters except [a-z0-9._-]. +func cleanJoomlaElement(name string) string { + lower := strings.ToLower(name) + var b strings.Builder + b.Grow(len(lower)) + for _, r := range lower { + if (r >= 'a' && r <= 'z') || (r >= '0' && r <= '9') || r == '.' || r == '_' || r == '-' { + b.WriteRune(r) + } + } + return b.String() +} + +// AutoElementName returns the auto-constructed Joomla element name (e.g. pkg_mokosuitebackup). +// The name is lowercased and cleaned to match Joomla's InputFilter::clean('cmd') behavior. func (m *RepoManifest) AutoElementName() string { if m.Name == "" || m.PackageType == "" { return "" } + cleaned := cleanJoomlaElement(m.Name) if prefix, ok := joomlaTypePrefix[m.PackageType]; ok { - return prefix + m.Name + return prefix + cleaned } - return m.Name + return cleaned } // FullElementName returns the effective element name: override if set, otherwise auto-constructed.