using System; using System.Linq; using Microsoft.SharePoint; using Microsoft.SharePoint.Utilities; using Taloyhtio.CondoUpdate.Common; namespace CondoUpdate.AddResponsibleUsersToGroupsTallier { public class UpdaterImpl : ICondoUpdater { public event EventHandler OnNotify; public void Update(object args) { string url = args as string; if (string.IsNullOrEmpty(url)) { this.warn("Url is empty"); return; } try { this.updateImpl(url); } catch (Exception x) { this.error("Error occured during updating of Condo '{0}':\n{1}\n{2}", url, x.Message, x.StackTrace); } } private void updateImpl(string url) { using (var site = new SPSite(url)) { var web = site.RootWeb; var list = web.Lists.Cast().FirstOrDefault(l => string.Compare(l.Title, "Sivustot", true) == 0); if (list == null) { warn("List not found"); return; } foreach (SPListItem item in list.Items) { string urlFieldTitle = "URL-osoite"; var urlField = list.Fields.Cast().FirstOrDefault( i => i.Title == urlFieldTitle || i.StaticName == urlFieldTitle); if (urlField == null) { return; } if (item[urlField.Id] == null || string.IsNullOrEmpty(item[urlField.Id].ToString())) { // for some lists on production there are 2 fields with the same title, so 1st field value may contain null foreach (SPField f in item.Fields) { if (f.Title == urlFieldTitle && item[f.Id] != null && !string.IsNullOrEmpty(item[f.Id].ToString())) { urlField = f; break; } } } if (item[urlField.Id] == null || string.IsNullOrEmpty(item[urlField.Id].ToString())) { return; } string condoUrl = new SPFieldUrlValue(item[urlField.Id].ToString()).Url; SPUser user = null; string userFieldTitle = "Kirjanpitäjä"; var userField = list.Fields.Cast().FirstOrDefault(f => f.Title == userFieldTitle); if (userField != null && userField.Type == SPFieldType.User && item[userFieldTitle] != null) { var fieldValue = userField.GetFieldValue(item[userFieldTitle].ToString()) as SPFieldUserValue; if (fieldValue != null) { user = fieldValue.User; } } if (SPUrlUtility.IsUrlRelative(condoUrl)) { condoUrl = SPUrlUtility.CombineUrl(site.RootWeb.Url, condoUrl); } using (var s = new SPSite(condoUrl)) { using (var condoWeb = s.OpenWeb()) { if (!condoWeb.Exists) { return; } string groupName = getResponsiblePropertyManagersGroupName(condoWeb); ensureSiteGroup(condoWeb, groupName); if (user != null) { addUserToGroup(condoWeb, user, groupName); } else { // clear the group var group = web.SiteGroups[groupName]; group.Users.Cast().ToList().ForEach(u => group.RemoveUser(u)); } } } } } } private void addUserToGroup(SPWeb web, SPUser user, string groupName) { if (user == null || string.IsNullOrEmpty(groupName)) { return; } // don't need to add user in group second time if (isUserInGroup(web, user.LoginName, groupName)) { return; } if (!containsUser(web, user.LoginName)) { web.EnsureUser(user.LoginName); } var group = web.SiteGroups[groupName]; group.AddUser(user); } private bool isUserInGroup(SPWeb web, string loginName, string groupName) { var group = web.SiteGroups[groupName]; return group.Users.Cast().Any(u => string.Compare(u.LoginName, loginName, true) == 0); } public static bool containsUser(SPWeb web, string loginName) { return web.AllUsers.Cast().Any(u => string.Compare(u.LoginName, loginName, true) == 0); } private string getResponsiblePropertyManagersGroupName(SPWeb web) { return string.Format("{0} - Responsible accountants", web.Title); } private SPGroup ensureSiteGroup(SPWeb web, string groupName) { if (!isGroupExist(web, groupName)) { web.SiteGroups.Add(groupName, web.SiteAdministrators[0], null, string.Empty); } return web.SiteGroups[groupName]; } private static bool isGroupExist(SPWeb web, string groupName) { return web.SiteGroups.Cast().Any(g => string.Compare(g.Name, groupName, true) == 0); } private void info(string msg, params object[] args) { this.notify(LogLevel.Info, msg, args); } private void warn(string msg, params object[] args) { this.notify(LogLevel.Warn, msg, args); } private void error(string msg, params object[] args) { this.notify(LogLevel.Error, msg, args); } private void notify(LogLevel level, string msg, params object[] args) { this.notify(level, string.Format(msg, args)); } private void notify(LogLevel level, string msg) { if (this.OnNotify != null) { this.OnNotify(this, new LogEventArgs { LogLevel = level, Message = msg }); } } } }