Last active
October 31, 2023 11:45
-
-
Save Migaroez/162faab59d4d04515d665e27f50e2735 to your computer and use it in GitHub Desktop.
Umbraco entity generation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//todo: refactor code for future expansion | |
using Microsoft.AspNetCore.Mvc; | |
using Umbraco.Cms.Core.Models; | |
using Umbraco.Cms.Core.Services; | |
using Umbraco.Cms.Core.Strings; | |
using Umbraco.Cms.Infrastructure.Persistence; | |
using Umbraco.Cms.Infrastructure.Persistence.Querying; | |
using Umbraco.Cms.Web.Common.Controllers; | |
namespace Umbraco.Cms.Web.UI.Code; | |
public class ContentGenerateController : UmbracoApiController | |
{ | |
private readonly IContentTypeService _contentTypeService; | |
private readonly IContentService _contentService; | |
private readonly IShortStringHelper _shortStringHelper; | |
private readonly IDataTypeService _dataTypeService; | |
private readonly ILocalizationService _localizationService; | |
private readonly ISqlContext _sqlContext; | |
public ContentGenerateController(IContentTypeService contentTypeService, IContentService contentService, | |
IShortStringHelper shortStringHelper, IDataTypeService dataTypeService, | |
ILocalizationService localizationService, ISqlContext sqlContext) | |
{ | |
_contentTypeService = contentTypeService; | |
_contentService = contentService; | |
_shortStringHelper = shortStringHelper; | |
_dataTypeService = dataTypeService; | |
_localizationService = localizationService; | |
_sqlContext = sqlContext; | |
} | |
[Route("api/generate/test")] | |
public bool Test() | |
{ | |
return true; | |
} | |
public class ContentGenerateRequestModel | |
{ | |
public int amount { get; set; } = 100; | |
public string[]? doctypeAliases { get; set; } = null; | |
public string? containingDoctypeAlias { get; set; } = null; | |
public bool firstContainingDocumentOnly { get; set; } = true; | |
public int newDocTypePropertyMinAmount { get; set; } = 1; | |
public int newDocTypePropertyMaxAmount { get; set; } = 1; | |
public string[]? languageIsoCodes { get; set; } | |
public string[]? segments { get; set; } | |
public bool containtingDoctypeUsesListview { get; set; } | |
} | |
[Route("api/generate/content")] | |
[HttpPost] | |
public List<string> Index([FromBody] ContentGenerateRequestModel model) | |
{ | |
var messages = new List<string>(); | |
var languages = GetOrCreateLanguages(model.languageIsoCodes); | |
var newDocTypesNeedToSupportCultures = languages.Count() > 1; | |
var newDocTypesNeedToSupportSegments = model.segments?.Length > 1; | |
var doctypes = GetOrCreateDocTypes(messages, model.doctypeAliases, model.newDocTypePropertyMinAmount, | |
model.newDocTypePropertyMaxAmount, newDocTypesNeedToSupportCultures, newDocTypesNeedToSupportSegments); | |
if (doctypes == null) | |
{ | |
return messages; | |
} | |
var containingDocuments = GetOrCreateContainingDocuments(model.containingDoctypeAlias, doctypes, | |
model.containtingDoctypeUsesListview); | |
if (containingDocuments == null || model.firstContainingDocumentOnly) | |
{ | |
CreateDocument(model.amount, doctypes, languages, model.segments, model.firstContainingDocumentOnly ? containingDocuments?.First() : null, messages); | |
} | |
else | |
{ | |
foreach (IContent containingDocument in containingDocuments) | |
{ | |
CreateDocument(model.amount, doctypes, languages, model.segments, containingDocument, messages); | |
} | |
} | |
return messages; | |
} | |
private void CreateDocument(int amount, List<IContentType> doctypes, ICollection<ILanguage> languages, string[]? segments, IContent? containingDocument, List<string> messages) | |
{ | |
for (int documentCreateIndex = 0; documentCreateIndex < amount; documentCreateIndex++) | |
{ | |
var doctype = doctypes[(documentCreateIndex + 1) % doctypes.Count]; | |
var properties = new PropertyCollection(); | |
foreach (IPropertyType propertyType in doctype.PropertyTypes.Where(pt => | |
pt.PropertyEditorAlias.Equals("Umbraco.TextBox", StringComparison.InvariantCultureIgnoreCase))) | |
{ | |
var property = new Property(propertyType); | |
if (doctype.Variations is ContentVariation.CultureAndSegment && | |
propertyType.Variations is ContentVariation.CultureAndSegment) | |
{ | |
foreach (var cultureIsoCode in languages.Select(l => l.IsoCode)) | |
{ | |
foreach (var segment in segments ?? Enumerable.Empty<string>()) | |
{ | |
property.SetValue(Guid.NewGuid() + "_" + cultureIsoCode + "_" + segment, cultureIsoCode, | |
segment); | |
} | |
} | |
} | |
else if (doctype.Variations is ContentVariation.CultureAndSegment or ContentVariation.Culture && | |
propertyType.Variations is ContentVariation.Culture) | |
{ | |
foreach (var cultureIsoCode in languages.Select(l => l.IsoCode)) | |
{ | |
property.SetValue(Guid.NewGuid() + "_" + cultureIsoCode, cultureIsoCode); | |
} | |
} | |
else if (doctype.Variations is ContentVariation.CultureAndSegment or ContentVariation.Segment && | |
propertyType.Variations is ContentVariation.Segment) | |
{ | |
foreach (var segment in segments ?? Enumerable.Empty<string>()) | |
{ | |
property.SetValue(Guid.NewGuid() + "_" + segment, null, segment); | |
} | |
} | |
else | |
{ | |
property.SetValue(Guid.NewGuid().ToString()); | |
} | |
properties.Add(property); | |
} | |
var content = containingDocument != null | |
? new Content(DateTime.Now.Ticks.ToString(), containingDocument!, doctype, | |
properties) | |
: new Content(DateTime.Now.Ticks.ToString(), -1, doctype, | |
properties); | |
if (doctype.Variations is ContentVariation.Culture or ContentVariation.CultureAndSegment) | |
{ | |
foreach (var cultureIsoCode in languages.Select(l => l.IsoCode)) | |
{ | |
content.SetCultureName(content.Name + "_" + cultureIsoCode, cultureIsoCode); | |
} | |
} | |
_contentService.SaveAndPublish(content); | |
messages.Add("Published content: " + content.Name); | |
} | |
} | |
private ICollection<ILanguage> GetOrCreateLanguages(string[]? modelLanguageIsoCodes) | |
{ | |
if (modelLanguageIsoCodes?.Any() != true) | |
{ | |
return new[] | |
{ | |
_localizationService.GetLanguageByIsoCode(_localizationService.GetDefaultLanguageIsoCode())! | |
}; | |
} | |
var languages = _localizationService.GetAllLanguages().Where(l => | |
modelLanguageIsoCodes.Any(lic => lic.Equals(l.IsoCode, StringComparison.InvariantCultureIgnoreCase))) | |
.ToList(); | |
var languagesToCreate = modelLanguageIsoCodes.Where(lic => | |
languages.Any(l => l.IsoCode.Equals(lic, StringComparison.InvariantCultureIgnoreCase)) == false).ToArray(); | |
foreach (var languageIsoCode in languagesToCreate) | |
{ | |
var language = new Language(languageIsoCode, languageIsoCode); | |
_localizationService.Save(language); | |
languages.Add(language); | |
} | |
return languages; | |
} | |
private List<IContentType>? GetOrCreateDocTypes(List<string> messages, string[]? doctypeAliases = null, | |
int newDocTypePropertyMinAmount = 1, int newDocTypePropertyMaxAmount = 1, bool makeNewPropertiesCultureVariant = false, | |
bool makeNewPropertiesSegmentVariant = false) | |
{ | |
if (doctypeAliases?.Any() != true) | |
{ | |
messages.Add("need at least one existing or new doctypeAlias"); | |
return null; | |
} | |
List<IContentType> doctypes = new List<IContentType>(); | |
if (doctypeAliases?.Any() == true) | |
{ | |
doctypes.AddRange(_contentTypeService.GetAll().Where(ct => | |
doctypeAliases.Contains(ct.Alias, StringComparer.InvariantCultureIgnoreCase))); | |
} | |
var newDocTypesAliases = doctypeAliases!.Where(dta => | |
doctypes.Any(dt => dt.Alias.Equals(dta, StringComparison.InvariantCultureIgnoreCase)) == false).ToList(); | |
var random = new Random(); | |
var textBoxDataType = _dataTypeService.GetByEditorAlias("Umbraco.TextBox").First(); | |
foreach (var newDoctypeAlias in newDocTypesAliases) | |
{ | |
var doctype = new ContentType(_shortStringHelper, -1); | |
doctype.Alias = newDoctypeAlias; | |
doctype.Icon = "icon-add"; | |
doctype.Name = newDoctypeAlias.ToFirstUpper(); | |
doctype.AllowedAsRoot = true; | |
doctype.Variations = ContentVariation.Nothing; | |
if (makeNewPropertiesCultureVariant) | |
{ | |
doctype.Variations = doctype.Variations.SetFlag(ContentVariation.Culture); | |
} | |
if (makeNewPropertiesSegmentVariant) | |
{ | |
doctype.Variations = doctype.Variations.SetFlag(ContentVariation.Segment); | |
} | |
var properties = new List<PropertyType>(); | |
var maxPropertyCount = random.Next(newDocTypePropertyMinAmount, newDocTypePropertyMaxAmount + 1); | |
for (var i = 0; i < maxPropertyCount; i++) | |
{ | |
properties.Add( | |
new PropertyType(_shortStringHelper, textBoxDataType, "generatedProperty" + i) | |
{ | |
Name = "generatedProperty" + i, | |
Variations = doctype.Variations, | |
}); | |
} | |
var propertyTypeCollection = new PropertyTypeCollection(true, properties); | |
doctype.PropertyGroups = new PropertyGroupCollection() | |
{ | |
new PropertyGroup(false) | |
{ | |
Alias = "generated", PropertyTypes = propertyTypeCollection, Name = "generated" | |
}, | |
}; | |
_contentTypeService.Save(doctype); | |
messages.Add("Created doctype: " + newDoctypeAlias); | |
doctypes.Add(doctype); | |
} | |
return doctypes; | |
} | |
private IEnumerable<IContent>? GetOrCreateContainingDocuments(string? containingDoctypeAlias, | |
IEnumerable<IContentType> contentTypesThatShouldBeAllowed, bool isContainer) | |
{ | |
if (containingDoctypeAlias.IsNullOrWhiteSpace()) | |
{ | |
return null; | |
} | |
var doctype = _contentTypeService | |
.GetAll() | |
.FirstOrDefault(ct => ct.Alias.Equals(containingDoctypeAlias, StringComparison.InvariantCultureIgnoreCase)); | |
if (doctype == null) | |
{ | |
doctype = new ContentType(_shortStringHelper, -1); | |
doctype.Alias = containingDoctypeAlias; | |
doctype.Icon = "icon-folder"; | |
doctype.Name = containingDoctypeAlias.ToFirstUpper(); | |
doctype.IsContainer = isContainer; | |
} | |
var allowedContentTypes = new List<ContentTypeSort>(); | |
if (doctype.AllowedContentTypes != null) | |
{ | |
allowedContentTypes.AddRange(doctype.AllowedContentTypes); | |
} | |
// make sure the doctypes are allowed | |
allowedContentTypes.AddRange(contentTypesThatShouldBeAllowed | |
.Where(ct => allowedContentTypes.Any(act => act.Alias == ct.Alias) == false) | |
.Select(ct => new ContentTypeSort(ct.Id, 0))); | |
doctype.AllowedContentTypes = allowedContentTypes; | |
// make sure it can be created at root so we don't need to go look for it | |
doctype.AllowedAsRoot = true; | |
_contentTypeService.Save(doctype); | |
var containingDocuments = _contentService.GetPagedOfType(doctype.Id,0,1000, out var _,new Query<IContent>(_sqlContext)) | |
.Where(doc => doc.ContentType.Alias == containingDoctypeAlias).ToList(); | |
if (containingDocuments.Any()) | |
{ | |
return containingDocuments; | |
} | |
var newContainingDocument = new Content("Generate Container " + DateTime.Now.Ticks, -1, doctype); | |
_contentService.SaveAndPublish(newContainingDocument); | |
containingDocuments.Add(newContainingDocument); | |
return containingDocuments; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Microsoft.AspNetCore.Mvc; | |
using Umbraco.Cms.Core.Security; | |
using Umbraco.Cms.Core.Services; | |
using Umbraco.Cms.Web.Common.Controllers; | |
namespace Umbraco.Cms.Web.UI.Generate; | |
public class GenerateMembersController : UmbracoApiController | |
{ | |
private readonly IMemberService _memberService; | |
private readonly IMemberManager _memberManager; | |
private readonly IPasswordHasher _passwordHasher; | |
public GenerateMembersController(IMemberService memberService, IMemberManager memberManager, IPasswordHasher passwordHasher) | |
{ | |
_memberService = memberService; | |
_memberManager = memberManager; | |
_passwordHasher = passwordHasher; | |
} | |
[Route("api/generate/members")] | |
public List<string> Index(int amount = 100, string emailPattern = "test[]@test.test", string namePattern = "test[]", string passwordPattern = "test[]@test.test", string memberTypeAlias = "Member") | |
{ | |
var messages = new List<string>(); | |
for (int i = 0; i < amount; i++) | |
{ | |
var email = emailPattern.Replace("[]", i.ToString()); | |
var password = passwordPattern.Replace("[]", i.ToString()); | |
var name = namePattern.Replace("[]", i.ToString()); | |
var member = _memberService.CreateMember(email, email, name, memberTypeAlias); | |
member.RawPasswordValue = _passwordHasher.HashPassword(password); | |
_memberService.Save(member); | |
messages.Add($"Created user {email} with password {password}"); | |
} | |
return messages; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment