landed code for creating community (untested)
This commit is contained in:
+133
-7
@@ -54,6 +54,7 @@ func CommunityAdminMenu(ctxt ui.AmContext) (string, any, error) {
|
|||||||
return "framed_template", "menu.jet", nil
|
return "framed_template", "menu.jet", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setupCommunityProfileDialog sets up fields in the Community Profile dialog.
|
||||||
func setupCommunityProfileDialog(dlg *ui.Dialog, comm *database.Community) {
|
func setupCommunityProfileDialog(dlg *ui.Dialog, comm *database.Community) {
|
||||||
dlg.SetCommunity(comm)
|
dlg.SetCommunity(comm)
|
||||||
if comm.IsAdmin {
|
if comm.IsAdmin {
|
||||||
@@ -108,7 +109,6 @@ func CommunityProfileForm(ctxt ui.AmContext) (string, any, error) {
|
|||||||
dlg, err := ui.AmLoadDialog("commprofile")
|
dlg, err := ui.AmLoadDialog("commprofile")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
setupCommunityProfileDialog(dlg, comm)
|
setupCommunityProfileDialog(dlg, comm)
|
||||||
dlg.Field("cc").Value = fmt.Sprintf("%d", comm.Id)
|
|
||||||
dlg.Field("name").Value = comm.Name
|
dlg.Field("name").Value = comm.Name
|
||||||
dlg.Field("alias").Value = comm.Alias
|
dlg.Field("alias").Value = comm.Alias
|
||||||
dlg.Field("synopsis").SetVal(comm.Synopsis)
|
dlg.Field("synopsis").SetVal(comm.Synopsis)
|
||||||
@@ -143,10 +143,16 @@ func CommunityProfileForm(ctxt ui.AmContext) (string, any, error) {
|
|||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// levelFld is a quick routine to extract a level value from a drop-down.
|
// validateJoinKey is an extra validation step for the join key.
|
||||||
func levelFld(d *ui.Dialog, name string) uint16 {
|
func validateJoinKey(dlg *ui.Dialog) error {
|
||||||
v, _ := strconv.Atoi(d.Field(name).Value)
|
if dlg.Field("comtype").Value == "1" {
|
||||||
return uint16(v)
|
if dlg.Field("joinkey").IsEmpty() {
|
||||||
|
return errors.New("private community must specify a join key")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dlg.Field("joinkey").Value = ""
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EditCommunityProfile updates the community's profile from the dialog.
|
/* EditCommunityProfile updates the community's profile from the dialog.
|
||||||
@@ -182,6 +188,10 @@ func EditCommunityProfile(ctxt ui.AmContext) (string, any, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return dlg.RenderError(ctxt, err.Error())
|
return dlg.RenderError(ctxt, err.Error())
|
||||||
}
|
}
|
||||||
|
err = validateJoinKey(dlg)
|
||||||
|
if err != nil {
|
||||||
|
return dlg.RenderError(ctxt, err.Error())
|
||||||
|
}
|
||||||
var ci *database.ContactInfo
|
var ci *database.ContactInfo
|
||||||
ci, err = comm.ContactInfo()
|
ci, err = comm.ContactInfo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -222,8 +232,8 @@ func EditCommunityProfile(ctxt ui.AmContext) (string, any, error) {
|
|||||||
}
|
}
|
||||||
err = comm.SetProfileData(dlg.Field("name").Value, dlg.Field("alias").Value, dlg.Field("synopsis").ValPtr(),
|
err = comm.SetProfileData(dlg.Field("name").Value, dlg.Field("alias").Value, dlg.Field("synopsis").ValPtr(),
|
||||||
dlg.Field("rules").ValPtr(), dlg.Field("language").ValPtr(), joinkey, dlg.Field("membersonly").IsChecked(),
|
dlg.Field("rules").ValPtr(), dlg.Field("language").ValPtr(), joinkey, dlg.Field("membersonly").IsChecked(),
|
||||||
hidedir, hidesearch, levelFld(dlg, "read_lvl"), levelFld(dlg, "write_lvl"), levelFld(dlg, "create_lvl"),
|
hidedir, hidesearch, dlg.Field("read_lvl").GetLevel(), dlg.Field("write_lvl").GetLevel(),
|
||||||
levelFld(dlg, "delete_lvl"), levelFld(dlg, "join_lvl"))
|
dlg.Field("create_lvl").GetLevel(), dlg.Field("delete_lvl").GetLevel(), dlg.Field("join_lvl").GetLevel())
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
flags.Set(database.CommunityFlagPicturesInPosts, dlg.Field("pic_in_post").IsChecked())
|
flags.Set(database.CommunityFlagPicturesInPosts, dlg.Field("pic_in_post").IsChecked())
|
||||||
@@ -241,6 +251,14 @@ func EditCommunityProfile(ctxt ui.AmContext) (string, any, error) {
|
|||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* CommunityLogoForm renders the form for changing the community logo.
|
||||||
|
* Parameters:
|
||||||
|
* ctxt - The AmContext for the request.
|
||||||
|
* Returns:
|
||||||
|
* Command string dictating what to be rendered.
|
||||||
|
* Data as a parameter for the command string.
|
||||||
|
* Standard Go error status.
|
||||||
|
*/
|
||||||
func CommunityLogoForm(ctxt ui.AmContext) (string, any, error) {
|
func CommunityLogoForm(ctxt ui.AmContext) (string, any, error) {
|
||||||
err := ctxt.SetCommunityContext(ctxt.URLParam("cid"))
|
err := ctxt.SetCommunityContext(ctxt.URLParam("cid"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -263,6 +281,14 @@ func CommunityLogoForm(ctxt ui.AmContext) (string, any, error) {
|
|||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* EditCommunityLogo handles setting the community logo.
|
||||||
|
* Parameters:
|
||||||
|
* ctxt - The AmContext for the request.
|
||||||
|
* Returns:
|
||||||
|
* Command string dictating what to be rendered.
|
||||||
|
* Data as a parameter for the command string.
|
||||||
|
* Standard Go error status.
|
||||||
|
*/
|
||||||
func EditCommunityLogo(ctxt ui.AmContext) (string, any, error) {
|
func EditCommunityLogo(ctxt ui.AmContext) (string, any, error) {
|
||||||
err := ctxt.SetCommunityContext(ctxt.URLParam("cid"))
|
err := ctxt.SetCommunityContext(ctxt.URLParam("cid"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -341,3 +367,103 @@ func EditCommunityLogo(ctxt ui.AmContext) (string, any, error) {
|
|||||||
}
|
}
|
||||||
return ui.ErrorPage(ctxt, errors.New("invalid button detected in logo upload"))
|
return ui.ErrorPage(ctxt, errors.New("invalid button detected in logo upload"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* CreateCommunityForm renders the form for creating a new community.
|
||||||
|
* Parameters:
|
||||||
|
* ctxt - The AmContext for the request.
|
||||||
|
* Returns:
|
||||||
|
* Command string dictating what to be rendered.
|
||||||
|
* Data as a parameter for the command string.
|
||||||
|
* Standard Go error status.
|
||||||
|
*/
|
||||||
|
func CreateCommunityForm(ctxt ui.AmContext) (string, any, error) {
|
||||||
|
user := ctxt.CurrentUser()
|
||||||
|
if user.BaseLevel < uint16(ctxt.Globals().CommunityCreateLevel) {
|
||||||
|
ctxt.SetRC(http.StatusForbidden)
|
||||||
|
return ui.ErrorPage(ctxt, errors.New("you are not permitted to create a community"))
|
||||||
|
}
|
||||||
|
dlg, err := ui.AmLoadDialog("create_comm")
|
||||||
|
if err != nil {
|
||||||
|
dlg.Field("language").Value = "en-US"
|
||||||
|
dlg.Field("country").Value = "US"
|
||||||
|
return dlg.Render(ctxt)
|
||||||
|
}
|
||||||
|
return ui.ErrorPage(ctxt, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CreateCommunity creates a new community.
|
||||||
|
* Parameters:
|
||||||
|
* ctxt - The AmContext for the request.
|
||||||
|
* Returns:
|
||||||
|
* Command string dictating what to be rendered.
|
||||||
|
* Data as a parameter for the command string.
|
||||||
|
* Standard Go error status.
|
||||||
|
*/
|
||||||
|
func CreateCommunity(ctxt ui.AmContext) (string, any, error) {
|
||||||
|
user := ctxt.CurrentUser()
|
||||||
|
if user.BaseLevel < uint16(ctxt.Globals().CommunityCreateLevel) {
|
||||||
|
ctxt.SetRC(http.StatusForbidden)
|
||||||
|
return ui.ErrorPage(ctxt, errors.New("you are not permitted to create a community"))
|
||||||
|
}
|
||||||
|
dlg, err := ui.AmLoadDialog("create_comm")
|
||||||
|
if err != nil {
|
||||||
|
dlg.LoadFromForm(ctxt)
|
||||||
|
action := dlg.WhichButton(ctxt)
|
||||||
|
if action == "cancel" {
|
||||||
|
return "redirect", "/", nil
|
||||||
|
}
|
||||||
|
if action == "create" {
|
||||||
|
err = dlg.Validate()
|
||||||
|
if err != nil {
|
||||||
|
return dlg.RenderError(ctxt, err.Error())
|
||||||
|
}
|
||||||
|
err = validateJoinKey(dlg)
|
||||||
|
if err != nil {
|
||||||
|
return dlg.RenderError(ctxt, err.Error())
|
||||||
|
}
|
||||||
|
var testcomm *database.Community
|
||||||
|
testcomm, err = database.AmGetCommunityByAlias(dlg.Field("alias").Value)
|
||||||
|
if err != nil {
|
||||||
|
return dlg.RenderError(ctxt, err.Error())
|
||||||
|
}
|
||||||
|
if testcomm != nil {
|
||||||
|
return dlg.RenderError(ctxt, fmt.Sprintf("A community with the alias \"%s\" already exists; please try again.", testcomm.Alias))
|
||||||
|
}
|
||||||
|
var hideDir, hideSearch bool
|
||||||
|
switch dlg.Field("hidemode").Value {
|
||||||
|
case "NONE":
|
||||||
|
hideDir = false
|
||||||
|
hideSearch = false
|
||||||
|
case "DIRECTORY":
|
||||||
|
hideDir = true
|
||||||
|
hideSearch = false
|
||||||
|
case "BOTH":
|
||||||
|
hideDir = true
|
||||||
|
hideSearch = true
|
||||||
|
}
|
||||||
|
var comm *database.Community
|
||||||
|
comm, err = database.AmCreateCommunity(dlg.Field("name").Value, dlg.Field("alias").Value, user.Uid,
|
||||||
|
dlg.Field("language").ValPtr(), dlg.Field("synopsis").ValPtr(), dlg.Field("rules").ValPtr(),
|
||||||
|
dlg.Field("joinkey").ValPtr(), hideDir, hideSearch, ctxt.RemoteIP())
|
||||||
|
if err != nil {
|
||||||
|
return dlg.RenderError(ctxt, err.Error())
|
||||||
|
}
|
||||||
|
ci := database.AmNewCommunityContactInfo(user.Uid, comm.Id)
|
||||||
|
ci.Locality = dlg.Field("loc").ValPtr()
|
||||||
|
ci.Region = dlg.Field("reg").ValPtr()
|
||||||
|
ci.PostalCode = dlg.Field("pcode").ValPtr()
|
||||||
|
ci.Country = dlg.Field("country").ValPtr()
|
||||||
|
_, err = ci.Save()
|
||||||
|
if err == nil {
|
||||||
|
err = comm.SetContactID(ci.ContactId)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return dlg.RenderError(ctxt, err.Error())
|
||||||
|
}
|
||||||
|
// new community is now created! redirect to the new profile
|
||||||
|
return "redirect", fmt.Sprintf("/comm/%s/profile", comm.Alias), nil
|
||||||
|
}
|
||||||
|
return dlg.RenderError(ctxt, "No known button click on POST to community creation.")
|
||||||
|
}
|
||||||
|
return ui.ErrorPage(ctxt, err)
|
||||||
|
}
|
||||||
|
|||||||
@@ -46,6 +46,18 @@ const (
|
|||||||
AuditAdminChangeUserAccount = 111
|
AuditAdminChangeUserAccount = 111
|
||||||
AuditAdminSetAccountSecurity = 112
|
AuditAdminSetAccountSecurity = 112
|
||||||
AuditAdminLockUnlockAccount = 113
|
AuditAdminLockUnlockAccount = 113
|
||||||
|
AuditCommunityCreate = 201
|
||||||
|
AuditCommunitySetMembership = 202
|
||||||
|
AuditCommuntiyContactInfo = 203
|
||||||
|
AuditCommunityFeatureSet = 204
|
||||||
|
AuditCommunityName = 205
|
||||||
|
AuditCommunityAlias = 206
|
||||||
|
AuditCommunityCategory = 207
|
||||||
|
AuditCommunityHideInfo = 208
|
||||||
|
AuditCommunityMembersOnly = 209
|
||||||
|
AuditCommunityJoinKey = 210
|
||||||
|
AuditCommunitySecurity = 211
|
||||||
|
AuditCommunityDelete = 212
|
||||||
)
|
)
|
||||||
|
|
||||||
// auditWriteQueue is a channel to store audit records in the background.
|
// auditWriteQueue is a channel to store audit records in the background.
|
||||||
|
|||||||
+125
-9
@@ -10,6 +10,7 @@
|
|||||||
package database
|
package database
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"slices"
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -248,10 +249,11 @@ func (c *Community) Flags() (*util.OptionSet, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if s == nil {
|
if s == nil {
|
||||||
return nil, fmt.Errorf("missing flags for community %d", c.Id)
|
c.flags = util.NewOptionSet()
|
||||||
}
|
} else {
|
||||||
c.flags = util.OptionSetFromString(*s)
|
c.flags = util.OptionSetFromString(*s)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return c.flags, nil
|
return c.flags, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,6 +304,17 @@ func (c *Community) SetProfileData(name string, alias string, synopsis *string,
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetContactID sets the contact ID for the community.
|
||||||
|
func (c *Community) SetContactID(cid int32) error {
|
||||||
|
c.Mutex.Lock()
|
||||||
|
defer c.Mutex.Unlock()
|
||||||
|
if _, err := amdb.Exec("UPDATE communities SET contactid = ? WHERE commid = ?", cid, c.Id); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
c.ContactId = cid
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
/* AmGetCommunity returns a reference to the specified community.
|
/* AmGetCommunity returns a reference to the specified community.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* id - The ID of the community.
|
* id - The ID of the community.
|
||||||
@@ -331,6 +344,27 @@ func AmGetCommunity(id int32) (*Community, error) {
|
|||||||
return rc.(*Community), err
|
return rc.(*Community), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* AmGetCommunityByAlias returns a reference to the specified community.
|
||||||
|
* Parameters:
|
||||||
|
* alias - The alias for the community.
|
||||||
|
* Returns:
|
||||||
|
* Pointer to Community containing community data, or nil
|
||||||
|
* Standard Go error status (nil if community not found)
|
||||||
|
*/
|
||||||
|
func AmGetCommunityByAlias(alias string) (*Community, error) {
|
||||||
|
rs, err := amdb.Query("SELECT commid FROM communities WHERE alias = ?", alias)
|
||||||
|
if err == nil {
|
||||||
|
if rs.Next() {
|
||||||
|
var cid int32
|
||||||
|
rs.Scan(&cid)
|
||||||
|
return AmGetCommunity(cid)
|
||||||
|
} else {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
/* AmGetCommunityFromParam returns a reference to the specified community based on the parameter.
|
/* AmGetCommunityFromParam returns a reference to the specified community based on the parameter.
|
||||||
* If the parameter is numeric, it's interpreted as a community ID. Otherwise, it's interpreted
|
* If the parameter is numeric, it's interpreted as a community ID. Otherwise, it's interpreted
|
||||||
* as a community alias.
|
* as a community alias.
|
||||||
@@ -349,17 +383,13 @@ func AmGetCommunityFromParam(param string) (*Community, error) {
|
|||||||
}
|
}
|
||||||
// else fall through to trying as alias
|
// else fall through to trying as alias
|
||||||
}
|
}
|
||||||
rs, err := amdb.Query("SELECT commid FROM communities WHERE alias = ?", param)
|
rc, err := AmGetCommunityByAlias(param)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if rs.Next() {
|
if rc == nil {
|
||||||
var cid int32
|
|
||||||
rs.Scan(&cid)
|
|
||||||
return AmGetCommunity(cid)
|
|
||||||
} else {
|
|
||||||
return nil, fmt.Errorf("community with alias \"%s\" not found", param)
|
return nil, fmt.Errorf("community with alias \"%s\" not found", param)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, err
|
return rc, err
|
||||||
}
|
}
|
||||||
|
|
||||||
/* AmGetCommunitiesForUser returns a list of communities the user is a member of.
|
/* AmGetCommunitiesForUser returns a list of communities the user is a member of.
|
||||||
@@ -482,6 +512,8 @@ func AmGetCommunityProperty(cid int32, ndx int32) (*string, error) {
|
|||||||
p, err := internalGetCommProp(cid, ndx)
|
p, err := internalGetCommProp(cid, ndx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
} else if p == nil {
|
||||||
|
return nil, nil
|
||||||
}
|
}
|
||||||
return p.Data, nil
|
return p.Data, nil
|
||||||
}
|
}
|
||||||
@@ -515,3 +547,87 @@ func AmSetCommunityProperty(cid int32, ndx int32, val *string) error {
|
|||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* AmCreateCommunity creates a new community.
|
||||||
|
* Parameters:
|
||||||
|
* name - The name for the new community.
|
||||||
|
* alias - The alias for the new community. Must be unique.
|
||||||
|
* hostUid - The UID of the creator and new host of the community.
|
||||||
|
* language - Community default language.
|
||||||
|
* synopsis - Community synopsis string.
|
||||||
|
* rules - Community rules string.
|
||||||
|
* joinkey - Community join key, or empty string for a public community.
|
||||||
|
* hideDirectory - true to hide this community from the directory listings.
|
||||||
|
* hideSearch - true to hide this community from searches.
|
||||||
|
* remoteIP - Remote IP address for audit record.
|
||||||
|
* Returns:
|
||||||
|
* Pointer to new Community record, or nil.
|
||||||
|
* Standard Go error status.
|
||||||
|
*/
|
||||||
|
func AmCreateCommunity(name string, alias string, hostUid int32, language *string, synopsis *string,
|
||||||
|
rules *string, joinkey *string, hideDirectory bool, hideSearch bool, remoteIP string) (*Community, error) {
|
||||||
|
var ar *AuditRecord = nil
|
||||||
|
defer func() {
|
||||||
|
AmStoreAudit(ar)
|
||||||
|
}()
|
||||||
|
|
||||||
|
unlock := true
|
||||||
|
amdb.Exec("LOCK TABLES communities WRITE, commftrs WRITE, commmember WRITE;")
|
||||||
|
defer func() {
|
||||||
|
if unlock {
|
||||||
|
amdb.Exec("UNLOCK TABLES;")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// validate alias does not already exist
|
||||||
|
rs, err := amdb.Query("SELECT commid FROM communities WHERE alias = ?", alias)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if rs.Next() {
|
||||||
|
return nil, errors.New("a community with that alias already exists")
|
||||||
|
}
|
||||||
|
|
||||||
|
// establish the community record
|
||||||
|
_, err = amdb.Exec(`INSERT INTO communities (createdate, lastaccess, lastupdate, read_lvl, write_lvl,
|
||||||
|
create_lvl, delete_lvl, join_lvl, host_uid, hide_dir, hide_search, commname, language,
|
||||||
|
synopsis, rules, joinkey, alias) VALUES (NOW(), NOW(), NOW(), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||||
|
AmRoleList("Community.Read").Default().Level(), AmRoleList("Community.Write").Default().Level(),
|
||||||
|
AmRoleList("Community.Create").Default().Level(), AmRoleList("Community.Delete").Default().Level(),
|
||||||
|
AmRoleList("Community.Join").Default().Level(), hostUid, hideDirectory, hideSearch, name, language,
|
||||||
|
synopsis, rules, joinkey, alias)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read back the community, which also puts it in the cache.
|
||||||
|
comm, err := AmGetCommunityByAlias(alias)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else if comm == nil {
|
||||||
|
return nil, errors.New("unable to find newly-generated community")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Establish the community services.
|
||||||
|
err = AmEstablishCommunityServices(comm.Id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the new host has host privileges in the community. The host's membership is "locked" so they
|
||||||
|
// can't unjoin and leave the community hostless.
|
||||||
|
_, err = amdb.Exec("INSERT INTO commmember (commid, uid, granted_lvl, locked) VALUES (?, ?, ?, 1)", comm.Id, hostUid,
|
||||||
|
AmDefaultRole("Community.Creator").Level())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
stuffMembership(comm.Id, hostUid, true, true, AmDefaultRole("Community.Creator").Level())
|
||||||
|
|
||||||
|
amdb.Exec("UNLOCK TABLES;")
|
||||||
|
unlock = false
|
||||||
|
|
||||||
|
// operation was a success - add an audit record
|
||||||
|
ar = AmNewAudit(AuditCommunityCreate, hostUid, remoteIP, fmt.Sprintf("id=%d", comm.Id),
|
||||||
|
fmt.Sprintf("name=%s", comm.Name), fmt.Sprintf("alias=%s", comm.Alias))
|
||||||
|
return comm, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -250,3 +250,15 @@ func AmNewUserContactInfo(uid int32) *ContactInfo {
|
|||||||
rc := ContactInfo{OwnerUid: uid, OwnerCommId: -1}
|
rc := ContactInfo{OwnerUid: uid, OwnerCommId: -1}
|
||||||
return &rc
|
return &rc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* AmNewCommunityContactInfo creates a new contact info record for the community.
|
||||||
|
* Parameters:
|
||||||
|
* uid - The UID of the host of this community.
|
||||||
|
* cid - The community ID of the owning community.
|
||||||
|
* Returns:
|
||||||
|
* New ContactInfo structure.
|
||||||
|
*/
|
||||||
|
func AmNewCommunityContactInfo(uid int32, cid int32) *ContactInfo {
|
||||||
|
rc := ContactInfo{OwnerUid: uid, OwnerCommId: cid}
|
||||||
|
return &rc
|
||||||
|
}
|
||||||
|
|||||||
@@ -114,3 +114,27 @@ func AmGetCommunityServices(cid int32) ([]*ServiceDef, error) {
|
|||||||
}
|
}
|
||||||
return rc.([]*ServiceDef), nil
|
return rc.([]*ServiceDef), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* AmEstablishCommunityServices extablishes the service (feature) records for a new community.
|
||||||
|
* Parameters:
|
||||||
|
* cid - ID of the new community.
|
||||||
|
* Returns:
|
||||||
|
* Standard Go error status.
|
||||||
|
*/
|
||||||
|
func AmEstablishCommunityServices(cid int32) error {
|
||||||
|
dom := serviceRoot.byName["community"]
|
||||||
|
a := make([]*ServiceDef, 0, len(dom.Services))
|
||||||
|
for i, svc := range dom.Services {
|
||||||
|
if svc.Default {
|
||||||
|
_, err := amdb.Exec("INSERT INTO commftrs (commid, ftr_code) VALUES (?, ?)", cid, svc.Index)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
a = append(a, &(dom.Services[i]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
servicesCacheMutex.Lock()
|
||||||
|
servicesCache.Add(cid, a)
|
||||||
|
servicesCacheMutex.Unlock()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -64,6 +64,8 @@ func setupEcho() *echo.Echo {
|
|||||||
e.GET("/user/:uname", ui.AmWrap(ShowProfile))
|
e.GET("/user/:uname", ui.AmWrap(ShowProfile))
|
||||||
e.POST("/quick_email", ui.AmWrap(QuickEMail))
|
e.POST("/quick_email", ui.AmWrap(QuickEMail))
|
||||||
e.GET("/sysadmin", ui.AmWrap(SysAdminMenu))
|
e.GET("/sysadmin", ui.AmWrap(SysAdminMenu))
|
||||||
|
e.GET("/create_comm", ui.AmWrap(CreateCommunityForm))
|
||||||
|
e.POST("/create_comm", ui.AmWrap(CreateCommunity))
|
||||||
e.GET("/comm/:cid/profile", ui.AmWrap(ShowCommunity))
|
e.GET("/comm/:cid/profile", ui.AmWrap(ShowCommunity))
|
||||||
e.GET("/comm/:cid/admin", ui.AmWrap(CommunityAdminMenu))
|
e.GET("/comm/:cid/admin", ui.AmWrap(CommunityAdminMenu))
|
||||||
e.GET("/comm/:cid/admin/profile", ui.AmWrap(CommunityProfileForm))
|
e.GET("/comm/:cid/admin/profile", ui.AmWrap(CommunityProfileForm))
|
||||||
|
|||||||
@@ -13,9 +13,6 @@ title: "Edit Community Profile:"
|
|||||||
subtitle: "[CNAME]"
|
subtitle: "[CNAME]"
|
||||||
action: "/comm/[CID]/admin/profile"
|
action: "/comm/[CID]/admin/profile"
|
||||||
fields:
|
fields:
|
||||||
- type: "hidden"
|
|
||||||
name: "cc"
|
|
||||||
value: ""
|
|
||||||
- type: "header"
|
- type: "header"
|
||||||
name: "header1"
|
name: "header1"
|
||||||
caption: "Basic Information"
|
caption: "Basic Information"
|
||||||
|
|||||||
@@ -0,0 +1,107 @@
|
|||||||
|
#
|
||||||
|
# Amsterdam Web Communities System
|
||||||
|
# Copyright (c) 2025 Erbosoft Metaverse Design Solutions, All Rights Reserved
|
||||||
|
#
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
#
|
||||||
|
name: "create.community"
|
||||||
|
formName: "createcommform"
|
||||||
|
menuSelector: "top"
|
||||||
|
title: "Create New Community"
|
||||||
|
action: "/create_comm"
|
||||||
|
fields:
|
||||||
|
- type: "header"
|
||||||
|
name: "header1"
|
||||||
|
caption: "Basic Information"
|
||||||
|
- type: "text"
|
||||||
|
name: "name"
|
||||||
|
caption: "Community Name"
|
||||||
|
required: true
|
||||||
|
size: 32
|
||||||
|
maxlength: 128
|
||||||
|
- type: "ams_id"
|
||||||
|
name: "alias"
|
||||||
|
caption: "Community Alias"
|
||||||
|
required: true
|
||||||
|
size: 32
|
||||||
|
maxlength: 32
|
||||||
|
- type: "text"
|
||||||
|
name: "synopsis"
|
||||||
|
caption: "Synopsis"
|
||||||
|
size: 32
|
||||||
|
maxlength: 255
|
||||||
|
- type: "text"
|
||||||
|
name: "rules"
|
||||||
|
caption: "Rules"
|
||||||
|
size: 32
|
||||||
|
maxlength: 255
|
||||||
|
- type: "localelist"
|
||||||
|
name: "language"
|
||||||
|
caption: "Primary Language"
|
||||||
|
required: true
|
||||||
|
- type: "header"
|
||||||
|
name: "header2"
|
||||||
|
caption: "Location"
|
||||||
|
- type: "text"
|
||||||
|
name: "loc"
|
||||||
|
caption: "City"
|
||||||
|
required: true
|
||||||
|
size: 32
|
||||||
|
maxlength: 64
|
||||||
|
- type: "text"
|
||||||
|
name: "reg"
|
||||||
|
caption: "State/Province"
|
||||||
|
required: true
|
||||||
|
size: 32
|
||||||
|
maxlength: 64
|
||||||
|
- type: "text"
|
||||||
|
name: "pcode"
|
||||||
|
caption: "Zip/Postal Code"
|
||||||
|
required: true
|
||||||
|
size: 32
|
||||||
|
maxlength: 64
|
||||||
|
- type: "countrylist"
|
||||||
|
name: "country"
|
||||||
|
caption: "Country"
|
||||||
|
required: true
|
||||||
|
- type: "header"
|
||||||
|
name: "header3"
|
||||||
|
caption: "Security"
|
||||||
|
- type: "dropdown"
|
||||||
|
name: "comtype"
|
||||||
|
caption: "Community type"
|
||||||
|
required: true
|
||||||
|
choices:
|
||||||
|
- id: "0"
|
||||||
|
text: "Public"
|
||||||
|
default: true
|
||||||
|
- id: "1"
|
||||||
|
text: "Private"
|
||||||
|
- type: "text"
|
||||||
|
name: "joinkey"
|
||||||
|
caption: "Join Key"
|
||||||
|
subcaption: "(for private communities)"
|
||||||
|
size: 32
|
||||||
|
maxlength: 64
|
||||||
|
- type: "dropdown"
|
||||||
|
name: "hidemode"
|
||||||
|
caption: "Community visibility"
|
||||||
|
required: true
|
||||||
|
choices:
|
||||||
|
- id: "NONE"
|
||||||
|
text: "Show in both directory and search"
|
||||||
|
default: true
|
||||||
|
- id: "DIRECTORY"
|
||||||
|
text: "Hide in directory, but not in search"
|
||||||
|
- id: "BOTH"
|
||||||
|
text: "Hide in both directory and search"
|
||||||
|
- type: "button"
|
||||||
|
name: "create"
|
||||||
|
caption: "Create"
|
||||||
|
param: "blue"
|
||||||
|
- type: "button"
|
||||||
|
name: "cancel"
|
||||||
|
caption: "Cancel"
|
||||||
|
param: "red"
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
{{ if sb.Flags["canCreate"] }}|{{ end }}
|
{{ if sb.Flags["canCreate"] }}|{{ end }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ if sb.Flags["canCreate"] }}
|
{{ if sb.Flags["canCreate"] }}
|
||||||
<a href="/TODO/create_comm" class="text-blue-700 hover:text-blue-900">Create New</a>
|
<a href="/create_comm" class="text-blue-700 hover:text-blue-900">Create New</a>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
]
|
]
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
Reference in New Issue
Block a user