public async Task <TagBaseContract> Create(string name) { ParamIs.NotNullOrWhiteSpace(() => name); PermissionContext.VerifyManageDatabase(); return(await _repository.HandleTransactionAsync(async ctx => { var duplicateName = await ctx.Query <TagName>() .Select(t => t.Value) .Where(t => t == name) .VdbFirstOrDefaultAsync(); if (duplicateName != null) { throw new DuplicateTagNameException(duplicateName); } var factory = new TagFactoryRepository(ctx, ctx.CreateAgentLoginData(PermissionContext)); var tag = await factory.CreateTagAsync(name); await ctx.AuditLogger.AuditLogAsync($"created tag {_entryLinkFactory.CreateEntryLink(tag)}"); return new TagBaseContract(tag, PermissionContext.LanguagePreference); })); }
public void AddSongTags(int songId, string[] tags) { ParamIs.NotNull(() => tags); VerifyManageDatabase(); repository.HandleTransaction(ctx => { tags = tags.Distinct(StringComparer.InvariantCultureIgnoreCase).ToArray(); var user = ctx.GetLoggedUser(PermissionContext); var song = ctx.OfType <Song>().Load(songId); ctx.AuditLogger.AuditLog(string.Format("appending {0} with {1}", entryLinkFactory.CreateEntryLink(song), string.Join(", ", tags)), user); var tagFactory = new TagFactoryRepository(ctx.OfType <Tag>(), new AgentLoginData(user)); var existingTags = TagHelpers.GetTags(ctx.OfType <Tag>(), tags); song.Tags.SyncVotes(user, tags, existingTags, tagFactory, new SongTagUsageFactoryRepository(ctx.OfType <SongTagUsage>(), song), onlyAdd: true); }); }
/// <summary> /// Creates a new tag. /// </summary> /// <param name="name">Tag English name. Cannot be null or empty. Must be unique.</param> /// <returns>The created tag. Cannot be null.</returns> /// <exception cref="DuplicateTagNameException">If a tag with the specified name already exists.</exception> public TagBaseContract Create(string name) { ParamIs.NotNullOrWhiteSpace(() => name); PermissionContext.VerifyManageDatabase(); return(repository.HandleTransaction(ctx => { var duplicateName = ctx.Query <TagName>() .Select(t => t.Value) .FirstOrDefault(t => t == name); if (duplicateName != null) { throw new DuplicateTagNameException(duplicateName); } var factory = new TagFactoryRepository(ctx, ctx.CreateAgentLoginData(PermissionContext)); var tag = factory.CreateTag(name); ctx.AuditLogger.AuditLog(string.Format("created tag {0}", entryLinkFactory.CreateEntryLink(tag))); return new TagBaseContract(tag, PermissionContext.LanguagePreference); })); }
public TagUsageForApiContract[] AddTags <TEntry, TTag>(int entryId, TagBaseContract[] tags, bool onlyAdd, IRepository <User> repository, IEntryLinkFactory entryLinkFactory, IEnumTranslations enumTranslations, Func <TEntry, TagManager <TTag> > tagFunc, Func <TEntry, IDatabaseContext <TTag>, ITagUsageFactory <TTag> > tagUsageFactoryFactory) where TEntry : IEntryWithNames, IEntryWithTags where TTag : TagUsage { ParamIs.NotNull(() => tags); permissionContext.VerifyManageDatabase(); tags = tags.Where(IsValid).ToArray(); if (onlyAdd && !tags.Any()) { return(new TagUsageForApiContract[0]); } return(repository.HandleTransaction(ctx => { // Tags are primarily added by Id, secondarily by translated name. // First separate given tags for tag IDs and tag names var tagIds = tags.Where(HasId).Select(t => t.Id).ToArray(); var translatedTagNames = tags.Where(t => !HasId(t) && !string.IsNullOrEmpty(t.Name)).Select(t => t.Name).ToArray(); // Load existing tags by name and ID. var tagsFromIds = ctx.Query <Tag>().Where(t => tagIds.Contains(t.Id)).ToArray(); var tagsFromNames = ctx.Query <Tag>().WhereHasName(translatedTagNames).ToArray(); // Figure out tags that don't exist yet (no ID and no matching name). var newTagNames = translatedTagNames.Except(tagsFromNames.SelectMany(t => t.Names.AllValues), StringComparer.InvariantCultureIgnoreCase).ToArray(); var user = ctx.OfType <User>().GetLoggedUser(permissionContext); var tagFactory = new TagFactoryRepository(ctx.OfType <Tag>(), new AgentLoginData(user)); var newTags = newTagNames.Select(t => tagFactory.CreateTag(t)).ToArray(); // Get the final list of tag names with translations var appliedTags = tagsFromNames.Concat(tagsFromIds).Concat(newTags).Distinct().ToArray(); var entry = ctx.OfType <TEntry>().Load(entryId); var tagUsageFactory = tagUsageFactoryFactory(entry, ctx.OfType <TTag>()); var tagNames = appliedTags.Select(t => t.DefaultName); ctx.AuditLogger.AuditLog(string.Format("tagging {0} with {1}", entryLinkFactory.CreateEntryLink(entry), string.Join(", ", tagNames)), user); var addedTags = appliedTags.Except(entry.Tags.Tags).ToArray(); new FollowedTagNotifier().SendNotifications(ctx, entry, addedTags, new[] { user.Id }, entryLinkFactory, enumTranslations); var updatedTags = tagFunc(entry).SyncVotes(user, appliedTags, tagUsageFactory, onlyAdd: onlyAdd); var tagCtx = ctx.OfType <Tag>(); foreach (var tag in updatedTags) { tagCtx.Update(tag); } RecomputeTagUsagesCounts(tagCtx, updatedTags); ctx.AuditLogger.SysLog("finished tagging"); return tagFunc(entry).ActiveUsages.Select(t => new TagUsageForApiContract(t, permissionContext.LanguagePreference)).ToArray(); })); }