示例#1
0
        public IEnumerable <Permission> GetPermissions()
        {
            var permissions = new List <Permission>();

            permissions.Add(ManageAllHashedStringFields);
            permissions.Add(ManageOwnHashedStringFields);

            IEnumerable <ContentPartDefinition> partDefinitions = _contentDefinitionManager.ListPartDefinitions();

            // LINQ.
            var tmp = partDefinitions
                      .Where(cpd =>
                             cpd.Fields.Any(cpfd =>
                                            cpfd.FieldDefinition.Name.Equals("HashedStringField")))
                      .SelectMany(cpd => cpd.Fields
                                  .Where(cpfd =>
                                         cpfd.FieldDefinition.Name.Equals("HashedStringField"))
                                  .Select(cpfd => new[] {
                _secureFieldService.GetAllHashedPermission(cpd.Name, cpfd.Name),
                _secureFieldService.GetOwnHashedPermission(cpd.Name, cpfd.Name)
            }));

            permissions.AddRange(tmp.SelectMany(p => p));

            return(permissions);
        }
        public void Describe(DescribeFilterContext describe)
        {
            foreach (var part in _contentDefinitionManager.ListPartDefinitions())
            {
                // This query returns all EncryptedStringFieldDefinitions in the parts where there's at least one EncryptedStringField.
                var encryptedStringFieldDefinitions = part.Fields.Where(fd => fd.FieldDefinition.Name.Equals("EncryptedStringField"));
                var localPart = part;

                foreach (var field in encryptedStringFieldDefinitions)
                {
                    var localField = field;

                    // The following code generates the list of filters you can apply on EncryptedStringFields.
                    // Fields are grouped by part.
                    describe
                    .For(
                        part.Name + "ContentFields",
                        T("{0} Content Fields", part.Name.CamelFriendly()),
                        T("Content Fields for {0}", part.Name.CamelFriendly()))
                    .Element(
                        localPart.Name + "." + localField.Name,
                        T(localField.DisplayName),
                        T("Value for {0}", localField.DisplayName),
                        context => ApplyFilter(context, part, field),
                        DisplayFilter,
                        SecureStringFieldForm.FormName);
                }
            }
        }
示例#3
0
        public async Task Setup(IDictionary <string, object> properties, Action <string, string> reportError)
        {
            var features = _extensionManager.GetFeatures();

            var featuresToEnable = features.Where(x => x.Id == "ThisNetWorks.OrchardCore.GoogleMaps");

            await _shellFeatureManager.EnableFeaturesAsync(featuresToEnable, true);

            var ctds = _contentDefinitionManager.ListPartDefinitions();

            if (ctds.FirstOrDefault(x => x.Name == "BlogPost") != null)
            {
                _contentDefinitionManager.AlterTypeDefinition("BlogPost", builder => builder
                                                              .WithPart("GoogleMapPart"));

                var query = _session.Query <ContentItem>()
                            .With <ContentItemIndex>(x => x.ContentType == "BlogPost" && x.Published);

                var blogPosts = await query.ListAsync();

                foreach (var blogPost in blogPosts)
                {
                    blogPost.Alter <GoogleMapPart>(part =>
                    {
                        part.Marker = new LatLng {
                            Lat = GoogleMapsSettings.DefaultLatitude, Lng = GoogleMapsSettings.DefaultLongitude
                        };
                    });

                    _session.Save(blogPost);
                }
            }
        }
示例#4
0
        public void Describe(DescribeFilterContext describe)
        {
            foreach (var part in _contentDefinitionManager.ListPartDefinitions())
            {
                var booleanFields = part.Fields.Where(field => field.FieldDefinition.Name == typeof(BooleanField).Name);

                if (!booleanFields.Any())
                {
                    continue;
                }

                var descriptor = describe.For(
                    part.Name + "ContentFields",
                    T("{0} Content Fields", part.Name.CamelFriendly()),
                    T("Content Fields for {0}", part.Name.CamelFriendly()));

                foreach (var field in booleanFields)
                {
                    descriptor.Element(
                        typeof(TokenizedBooleanFilter).Name,
                        T("{0}: Tokenized Value", field.DisplayName),
                        T("The tokenized boolean value of the field."),
                        context => ApplyFilter(context, part, field),
                        context => DisplayFilter(context, part, field),
                        TokenizedBooleanFilterForm.FormName
                        );
                }
            }
        }
示例#5
0
        public void Describe(DescribeContext context)
        {
            Func <IShapeFactory, object> form =
                shape => {
                var f = Shape.Form(
                    Id: "AnyOfContentParts",
                    _Parts: Shape.SelectList(
                        Id: "contentparts", Name: "ContentParts",
                        Title: T("Content parts"),
                        Description: T("Select some content parts."),
                        Size: 10,
                        Multiple: true
                        )
                    );

                f._Parts.Add(new SelectListItem {
                    Value = "", Text = T("Any").Text
                });

                foreach (var contentPart in _contentDefinitionManager.ListPartDefinitions().OrderBy(x => x.Name))
                {
                    f._Parts.Add(new SelectListItem {
                        Value = contentPart.Name, Text = contentPart.Name
                    });
                }

                return(f);
            };

            context.Form("ContentPartsFilter", form);
        }
        public static IEnumerable <ContentTypeDefinition> ListUserDefinedTypeDefinitions(this IContentDefinitionManager contentDefinitionManager)
        {
            var contentTypes = contentDefinitionManager.ListTypeDefinitions();
            var parts        = contentDefinitionManager.ListPartDefinitions();

            return(contentTypes.Where(t => parts.Any(p => p.Name == t.Name)));
        }
        public ActionResult Index()
        {
            var model = new MetadataIndexViewModel {
                TypeDefinitions = _contentDefinitionManager.ListTypeDefinitions(),
                PartDefinitions = _contentDefinitionManager.ListPartDefinitions()
            };
            var types = new XElement("Types");

            foreach (var type in model.TypeDefinitions)
            {
                types.Add(_contentDefinitionWriter.Export(type));
            }

            var parts = new XElement("Parts");

            foreach (var part in model.PartDefinitions)
            {
                parts.Add(_contentDefinitionWriter.Export(part));
            }

            var stringWriter = new StringWriter();

            using (var xmlWriter = XmlWriter.Create(stringWriter, new XmlWriterSettings {
                Indent = true, IndentChars = "  "
            })) {
                if (xmlWriter != null)
                {
                    new XElement("Orchard", types, parts).WriteTo(xmlWriter);
                }
            }
            model.ExportText = stringWriter.ToString();

            return(View(model));
        }
示例#8
0
        public IEnumerable <EditPartViewModel> GetParts(bool metadataPartsOnly)
        {
            var typeNames = new HashSet <string>(GetTypes().Select(ctd => ctd.Name));

            // user-defined parts
            // except for those parts with the same name as a type (implicit type's part or a mistake)
            var userContentParts = _contentDefinitionManager.ListPartDefinitions()
                                   .Where(cpd => !typeNames.Contains(cpd.Name))
                                   .Select(cpd => new EditPartViewModel(cpd))
                                   .ToDictionary(
                k => k.Name,
                v => v);

            // code-defined parts
            var codeDefinedParts = metadataPartsOnly
                ? Enumerable.Empty <EditPartViewModel>()
                : _contentPartDrivers
                                   .Select(d => d.GetPartInfo())
                                   .Where(cpd => !userContentParts.ContainsKey(cpd.PartName))
                                   .Select(cpi => new EditPartViewModel {
                Name = cpi.PartName, DisplayName = cpi.PartName
            })
                                   .ToList();

            // Order by display name
            return(codeDefinedParts
                   .Union(userContentParts.Values)
                   .OrderBy(m => m.DisplayName));
        }
示例#9
0
        public IEnumerable <dynamic> BuildLayoutEditors()
        {
            var contentParts = _contentDefinitionManager
                               .ListPartDefinitions()
                               .OrderBy(p => p.Name);
            var contentFields = _contentDefinitionManager
                                .ListPartDefinitions()
                                .SelectMany(p => p.Fields)
                                .OrderBy(f => f.DisplayName);

            return(new[] {
                Shape.LayoutElements_Part_LayoutEditor(
                    Order: "10",
                    ContentParts: contentParts
                    ),
                Shape.LayoutElements_Field_LayoutEditor(
                    Order: "11",
                    ContentFields: contentFields
                    )
            });
        }
示例#10
0
        public TaxonomyPartHandler(
            IRepository <TaxonomyPartRecord> repository,
            ITaxonomyService taxonomyService,
            IContentDefinitionManager contentDefinitionManager)
        {
            string previousName = null;

            Filters.Add(StorageFilter.For(repository));
            OnPublished <TaxonomyPart>((context, part) => {
                var previousTermTypeName = part.TermTypeName;

                if (previousName == null || part.Name == previousName)
                {
                    // is it a new taxonomy ?
                    taxonomyService.CreateTermContentType(part);
                }
                else
                {
                    // keep the previous term type name as it would otherwise force us
                    // to update all terms to use another type
                    part.TermTypeName = previousTermTypeName;

                    // update existing fields
                    foreach (var partDefinition in contentDefinitionManager.ListPartDefinitions())
                    {
                        foreach (var field in partDefinition.Fields)
                        {
                            if (field.FieldDefinition.Name == typeof(TaxonomyField).Name)
                            {
                                if (field.Settings.GetModel <TaxonomyFieldSettings>().Taxonomy == previousName)
                                {
                                    contentDefinitionManager.AlterPartDefinition(partDefinition.Name,
                                                                                 cfg => cfg.WithField(field.Name,
                                                                                                      builder => builder.WithSetting("TaxonomyFieldSettings.Taxonomy", part.Name)));
                                }
                            }
                        }
                    }
                }
            });

            OnLoading <TaxonomyPart>((context, part) => part.TermsField.Loader(x => taxonomyService.GetTerms(part.Id)));

            OnUpdating <TitlePart>((context, part) => {
                // if altering the title of a taxonomy, save the name
                if (part.As <TaxonomyPart>() != null)
                {
                    previousName = part.Title;
                }
            });
        }
示例#11
0
        public OptionSetPartHandler(
            IRepository <OptionSetPartRecord> repository,
            IOptionSetService optionSetService,
            IContentDefinitionManager contentDefinitionManager)
        {
            int?previousId = null;

            Filters.Add(StorageFilter.For(repository));
            OnPublished <OptionSetPart>((context, part) => {
                var previousTermTypeName = part.TermTypeName;

                if (previousId != null && part.Id != previousId)
                {
                    // remove previous term type
                    contentDefinitionManager.DeleteTypeDefinition(previousTermTypeName);

                    // update existing fields
                    foreach (var partDefinition in contentDefinitionManager.ListPartDefinitions())
                    {
                        foreach (var field in partDefinition.Fields)
                        {
                            if (field.FieldDefinition.Name == typeof(OptionSetField).Name)
                            {
                                if (field.Settings.GetModel <OptionSetFieldSettings>().OptionSetId == previousId)
                                {
                                    contentDefinitionManager.AlterPartDefinition(partDefinition.Name,
                                                                                 cfg => cfg.WithField(field.Name,
                                                                                                      builder => builder.WithSetting("TaxonomyFieldSettings.TaxonomyId", part.Id.ToString())));
                                }
                            }
                        }
                    }
                }
            });

            OnLoading <OptionSetPart>((context, part) => part.OptionItemsField.Loader(x => optionSetService.GetOptionItems(part.Id)));

            OnUpdating <TitlePart>((context, part) => {
                // if altering the title of a taxonomy, save the name
                if (part.As <OptionSetPart>() != null)
                {
                    previousId = part.Id;
                }
            });
        }
示例#12
0
        public void Describe(DescribeFilterContext describe)
        {
            foreach (var part in _contentDefinitionManager.ListPartDefinitions())
            {
                if (!part.Fields.Any())
                {
                    continue;
                }

                var descriptor = describe.For(part.Name + "ContentFields", T("{0} Content Fields", part.Name.CamelFriendly()), T("Content Fields for {0}", part.Name.CamelFriendly()));

                foreach (var field in part.Fields)
                {
                    var localField = field;
                    var localPart  = part;
                    var drivers    = _contentFieldDrivers.Where(x => x.GetFieldInfo().Any(fi => fi.FieldTypeName == localField.FieldDefinition.Name)).ToList();

                    var membersContext = new DescribeMembersContext(
                        (storageName, storageType, displayName, description) => {
                        // look for a compatible field type editor
                        IConcreteFieldTypeEditor concreteFieldTypeEditor = _fieldTypeEditors.FirstOrDefault(x => x.CanHandle(localField.FieldDefinition.Name, storageType))
                                                                           ?? _fieldTypeEditors.FirstOrDefault(x => x.CanHandle(storageType));
                        IFieldTypeEditor fieldTypeEditor = concreteFieldTypeEditor;

                        if (fieldTypeEditor == null)
                        {
                            return;
                        }

                        descriptor.Element(
                            type: localPart.Name + "." + localField.Name + "." + storageName,
                            name: new LocalizedString(localField.DisplayName + (displayName != null ? ":" + displayName.Text : "")),
                            description: description ?? T("{0} property for {1}", storageName, localField.DisplayName),
                            filter: context => concreteFieldTypeEditor.ApplyFilter(context, storageName, storageType, localPart, localField),
                            display: context => fieldTypeEditor.DisplayFilter(localPart.Name.CamelFriendly() + "." + localField.DisplayName, storageName, context.State),
                            form: fieldTypeEditor.FormName);
                    });

                    foreach (var driver in drivers)
                    {
                        driver.Describe(membersContext);
                    }
                }
            }
        }
示例#13
0
        public TaxonomyPartHandler(
            IRepository<TaxonomyPartRecord> repository, 
            ITaxonomyService taxonomyService,
            IContentDefinitionManager contentDefinitionManager)
        {
            string previousName = null;

            Filters.Add(StorageFilter.For(repository));
            OnPublished<TaxonomyPart>((context, part) => {
                var previousTermTypeName = part.TermTypeName;

                if (previousName == null || part.Name == previousName) {
                    // is it a new taxonomy ?
                    taxonomyService.CreateTermContentType(part);
                }
                else {
                    // keep the previous term type name as it would otherwise force us
                    // to update all terms to use another type
                    part.TermTypeName = previousTermTypeName;

                    // update existing fields
                    foreach (var partDefinition in contentDefinitionManager.ListPartDefinitions()) {
                        foreach (var field in partDefinition.Fields) {
                            if (field.FieldDefinition.Name == typeof (TaxonomyField).Name) {

                                if (field.Settings.GetModel<TaxonomyFieldSettings>().Taxonomy == previousName) {
                                    contentDefinitionManager.AlterPartDefinition(partDefinition.Name,
                                        cfg => cfg.WithField(field.Name,
                                            builder => builder.WithSetting("TaxonomyFieldSettings.Taxonomy", part.Name)));
                                }
                            }
                        }
                    }
                }
            });

            OnLoading<TaxonomyPart>( (context, part) => part.TermsField.Loader(x => taxonomyService.GetTerms(part.Id)));

            OnUpdating<TitlePart>((context, part) => {
                // if altering the title of a taxonomy, save the name
                if (part.As<TaxonomyPart>() != null) {
                    previousName = part.Title;
                }
            });
        }
示例#14
0
        public void Describe(DescribeFilterContext describe)
        {
            foreach (var part in _contentDefinitionManager.ListPartDefinitions())
            {
                if (!part.Fields.Any())
                {
                    continue;
                }

                var descriptor = describe.For(part.Name + "ContentFieldsNullSafe", T("{0} Content Fields (null-safe)", part.Name.CamelFriendly()), T("Content Fields for {0} (null-safe).", part.Name.CamelFriendly()));

                foreach (var field in part.Fields)
                {
                    var localField = field;
                    var localPart  = part;
                    var drivers    = _contentFieldDrivers.Where(x => x.GetFieldInfo().Any(fi => fi.FieldTypeName == localField.FieldDefinition.Name)).ToList();

                    var membersContext = new DescribeMembersContext((storageName, storageType, displayName, description) =>
                    {
                        // Look for a compatible field type editor.
                        IFieldTypeEditor fieldTypeEditor = _fieldTypeEditors.FirstOrDefault(x => x.CanHandle(storageType));

                        if (fieldTypeEditor == null)
                        {
                            return;
                        }

                        descriptor.Element(
                            type: localPart.Name + "." + localField.Name + "." + storageName,
                            name: new LocalizedString(localField.DisplayName + (displayName != null ? ":" + displayName.Text : "") + " (null-safe)"),
                            description: new LocalizedString(description != null ? description + " (null-safe)" : "No filter will be applied if the filter value is empty, so items indexed as null in the database won't be excluded from the result."),
                            filter: context => ApplyFilter(context, fieldTypeEditor, storageName, storageType, localPart, localField),
                            display: context => fieldTypeEditor.DisplayFilter(localPart.Name + "." + localField.DisplayName, storageName, context.State),
                            form: fieldTypeEditor.FormName);
                    });

                    foreach (var driver in drivers)
                    {
                        driver.Describe(membersContext);
                    }
                }
            }
        }
示例#15
0
        public OptionSetPartHandler(
            IRepository<OptionSetPartRecord> repository, 
            IOptionSetService optionSetService,
            IContentDefinitionManager contentDefinitionManager) {

            int? previousId = null;

            Filters.Add(StorageFilter.For(repository));
            OnPublished<OptionSetPart>((context, part) => {
                var previousTermTypeName = part.TermTypeName;

                if (previousId != null && part.Id != previousId) {

                    // remove previous term type
                    contentDefinitionManager.DeleteTypeDefinition(previousTermTypeName);

                    // update existing fields
                    foreach (var partDefinition in contentDefinitionManager.ListPartDefinitions()) {
                        foreach (var field in partDefinition.Fields) {
                            if (field.FieldDefinition.Name == typeof (OptionSetField).Name) {

                                if (field.Settings.GetModel<OptionSetFieldSettings>().OptionSetId == previousId) {
                                    contentDefinitionManager.AlterPartDefinition(partDefinition.Name, 
                                        cfg => cfg.WithField(field.Name,
                                            builder => builder.WithSetting("TaxonomyFieldSettings.TaxonomyId", part.Id.ToString())));
                                }
                            }
                        }
                    }
                }
            });

            OnLoading<OptionSetPart>((context, part) => part.OptionItemsField.Loader(x => optionSetService.GetOptionItems(part.Id)));

            OnUpdating<TitlePart>((context, part) => {
                // if altering the title of a taxonomy, save the name
                if (part.As<OptionSetPart>() != null) {
                    previousId = part.Id;
                }
            });
        }
示例#16
0
        // Migration content part definitions.
        // This code can be removed in a later version.
        public int UpdateFrom4()
        {
            var partDefinitions = _contentDefinitionManager.ListPartDefinitions();

            foreach (var partDefinition in partDefinitions)
            {
                var existingPartSettings = partDefinition.Settings.ToObject <ContentPartSettings>();

                // Do this before creating builder, so settings are removed from the builder settings object.
                // Remove existing properties from JObject
                var contentTypeSettingsProperties = existingPartSettings.GetType().GetProperties();
                foreach (var property in contentTypeSettingsProperties)
                {
                    partDefinition.Settings.Remove(property.Name);
                }

                _contentDefinitionManager.AlterPartDefinition(partDefinition.Name, partBuilder =>
                {
                    partBuilder.WithSettings(existingPartSettings);
                    foreach (var fieldDefinition in partDefinition.Fields)
                    {
                        var existingFieldSettings = fieldDefinition.Settings.ToObject <ContentPartFieldSettings>();

                        // Do this before creating builder, so settings are removed from the builder settings object.
                        // Remove existing properties from JObject
                        var fieldSettingsProperties = existingFieldSettings.GetType().GetProperties();
                        foreach (var property in fieldSettingsProperties)
                        {
                            fieldDefinition.Settings.Remove(property.Name);
                        }

                        partBuilder.WithField(fieldDefinition.Name, fieldBuilder =>
                        {
                            fieldBuilder.WithSettings(existingFieldSettings);
                        });
                    }
                });
            }

            return(5);
        }
        /// <summary>
        /// Migrate existing ContentField settings to WithSettings<typeparamref name="TSettings"/>
        /// This method will be removed in a future release.
        /// </summary>
        /// <typeparam name="TField"></typeparam>
        /// <typeparam name="TSettings"></typeparam>
        /// <param name="manager"></param>
        public static void MigrateFieldSettings <TField, TSettings>(this IContentDefinitionManager manager)
            where TField : ContentField where TSettings : class
        {
            var partDefinitions = manager.ListPartDefinitions();

            foreach (var partDefinition in partDefinitions)
            {
                manager.AlterPartDefinition(partDefinition.Name, partBuilder =>
                {
                    foreach (var fieldDefinition in partDefinition.Fields.Where(x => x.FieldDefinition.Name == typeof(TField).Name))
                    {
                        var existingFieldSettings = fieldDefinition.Settings.ToObject <TSettings>();

                        // Do this before creating builder, so settings are removed from the builder settings object.
                        // Remove existing properties from JObject
                        var fieldSettingsProperties = existingFieldSettings.GetType().GetProperties();
                        var hasSetting = false;
                        foreach (var property in fieldSettingsProperties)
                        {
                            if (fieldDefinition.Settings.ContainsKey(property.Name))
                            {
                                hasSetting = true;
                                fieldDefinition.Settings.Remove(property.Name);
                            }
                        }

                        // Only include settings if the definition already has at least one of these settings.
                        if (hasSetting)
                        {
                            partBuilder.WithField(fieldDefinition.Name, fieldBuilder =>
                            {
                                fieldBuilder.WithSettings(existingFieldSettings);
                            });
                        }
                    }
                });
            }
        }
示例#18
0
        public TaxonomyPartHandler(
            IRepository <TaxonomyPartRecord> repository,
            ITaxonomyService taxonomyService,
            IContentDefinitionManager contentDefinitionManager,
            ILocalizationService localizationService = null)   //Localization feature may not be active
        {
            string previousName = null;

            Filters.Add(StorageFilter.For(repository));
            OnPublished <TaxonomyPart>((context, part) => {
                if (string.IsNullOrWhiteSpace(part.TermTypeName))
                {
                    // is it a new taxonomy ?
                    taxonomyService.CreateTermContentType(part);
                }
                else
                {
                    // update existing fields
                    foreach (var partDefinition in contentDefinitionManager.ListPartDefinitions())
                    {
                        foreach (var field in partDefinition.Fields)
                        {
                            if (field.FieldDefinition.Name == typeof(TaxonomyField).Name)
                            {
                                if (field.Settings.GetModel <TaxonomyFieldSettings>().Taxonomy == previousName)
                                {
                                    //could either be a name change, or we could be publishing a translation
                                    if (localizationService != null)   //Localization feature may not be active
                                    {
                                        var locPart = part.ContentItem.As <LocalizationPart>();
                                        if (locPart != null)
                                        {
                                            var localizedTaxonomies = localizationService
                                                                      .GetLocalizations(part.ContentItem)                    //versions in all cultures
                                                                      .Where(pa => pa.ContentItem.Id != part.ContentItem.Id) //but not the one we are publishing
                                                                      .Select(pa => {
                                                var tax = pa.ContentItem.As <TaxonomyPart>();                                //the TaxonomyPart
                                                return(tax == null ? string.Empty : tax.Name);                               //get its name (with sanity check)
                                            });
                                            if (localizedTaxonomies.Contains(previousName))
                                            {
                                                continue; //this is a new localization, so move along
                                            }
                                        }
                                    }
                                    contentDefinitionManager.AlterPartDefinition(partDefinition.Name,
                                                                                 cfg => cfg.WithField(field.Name,
                                                                                                      builder => builder.WithSetting("TaxonomyFieldSettings.Taxonomy", part.Name)));
                                }
                            }
                        }
                    }
                }
            });

            OnLoading <TaxonomyPart>((context, part) => part.TermsField.Loader(() => taxonomyService.GetTerms(part.Id)));

            OnUpdating <TitlePart>((context, part) => {
                // if altering the title of a taxonomy, save the name
                if (part.As <TaxonomyPart>() != null)
                {
                    previousName = part.Title;
                }
            });
        }
        public void Describe(DescribeGroupByContext describe)
        {
            foreach (var part in _contentDefinitionManager.ListPartDefinitions())
            {
                if (!part.Fields.Any())
                {
                    continue;
                }

                var descriptor = describe.For(part.Name + "ContentFields", T("{0} Content Fields", part.Name.CamelFriendly()), T("Content Fields for {0}", part.Name.CamelFriendly()));

                foreach (var field in part.Fields)
                {
                    var localField = field;
                    var localPart  = part;
                    var drivers    = _contentFieldDrivers.Where(x => x.GetFieldInfo().Any(fi => fi.FieldTypeName == localField.FieldDefinition.Name)).ToList();

                    var membersContext = new DescribeMembersContext(
                        (storageName, storageType, displayName, description) =>
                    {
                        // look for a compatible field type editor
                        IFieldTypeEditor fieldTypeEditor = _fieldTypeEditors.FirstOrDefault(x => x.CanHandle(storageType));

                        if (fieldTypeEditor == null)
                        {
                            return;
                        }

                        if (localField.FieldDefinition.Name == "NumericField")
                        {
                            this.DescribeNumericFieldMemberContext(
                                localField: localField,
                                description: description,
                                storageName: storageName,
                                descriptor: descriptor,
                                displayName: displayName,
                                fieldTypeEditor: fieldTypeEditor,
                                localPart: localPart);
                        }
                        else if (localField.FieldDefinition.Name == "EnumerationField")
                        {
                            //field.FieldDefinition.Name
                            List <AggregateMethods> methods = new List <AggregateMethods>();
                            methods.Add(AggregateMethods.Count);

                            descriptor.Element(
                                type: localPart.Name + "." + localField.Name + "." + storageName,
                                name: T(localField.DisplayName),
                                description: T("group the result by {0} values", localField.DisplayName),
                                run: (query, method) => this.fieldAggregateQueryService.RunEnumerationAggregation(query, method, localField.Name, localPart.Name),
                                aggregateMethods: methods,
                                display: context => fieldTypeEditor.DisplayFilter(localPart.Name.CamelFriendly() + "." + localField.DisplayName, storageName, context.State));
                        }
                    });

                    foreach (var driver in drivers)
                    {
                        driver.Describe(membersContext);
                    }
                }
            }
        }
示例#20
0
        public void Process(DocumentProcessorContext context)
        {
            if (!_openApiOptions.ContentTypes.ProcessContentTypes)
            {
                return;
            }

            _contentDefinitionManager ??= _httpContextAccessor.HttpContext.RequestServices.GetRequiredService <IContentDefinitionManager>();

            var contentElementDtoSchema = context.SchemaGenerator.Generate(typeof(ContentElementDto), context.SchemaResolver);

            // Due to issue with NJsonSchema we force set additional properties here to false
            // because it is defined on the base class.
            // cf. https://github.com/RicoSuter/NSwag/issues/2818
            contentElementDtoSchema.AllowAdditionalProperties = false;
            var fieldDtoSchema = context.SchemaGenerator.Generate(typeof(ContentFieldDto), context.SchemaResolver);

            fieldDtoSchema.AllowAdditionalProperties = false;

            var ctds = _contentDefinitionManager.ListTypeDefinitions();
            var allFieldDefinitions = ctds
                                      .SelectMany(x => x.Parts.SelectMany(p => p.PartDefinition.Fields))
                                      .Select(x => x.FieldDefinition).ToLookup(x => x.Name, StringComparer.OrdinalIgnoreCase);

            // Process fields
            foreach (var contentFieldOption in _contentOptions.ContentFieldOptions)
            {
                if (!_openApiOptions.ContentTypes.IncludeAllFields)
                {
                    if (!allFieldDefinitions.Contains(contentFieldOption.Type.Name))
                    {
                        continue;
                    }
                }

                if (_openApiOptions.ContentTypes.ExcludedFields.Any(x => string.Equals(x, contentFieldOption.Type.Name, StringComparison.OrdinalIgnoreCase)))
                {
                    continue;
                }

                var fieldSchema = context.SchemaGenerator.Generate(contentFieldOption.Type, context.SchemaResolver);
                fieldSchema.AllOf.ElementAt(1).AllowAdditionalProperties = false;
                // remove first AllOf and reinsert the fieldDtoSchema as the ref.
                InsertDtoReferenceSchema(fieldSchema, fieldDtoSchema);

                // Change schema regisitration name to 'TextFieldDto'
                AlterSchemaDefinition(context, contentFieldOption.Type.Name, _openApiOptions.ContentTypes.SchemaNameExtension);
            }

            // Process Parts
            // Note we have to use the content definition manager here
            // because parts may be created dynamically.
            // We also include definitions for code only parts, like ContainedPart
            var contentItemSchema = context.SchemaResolver.GetSchema(typeof(ContentItem), false);
            // This should end up being ignored, because we remove it from the nswag.config
            var contentItemDtoSchema = context.SchemaGenerator.Generate(typeof(ContentItemDto), context.SchemaResolver);

            contentItemDtoSchema.AllowAdditionalProperties = false;
            //var contentItemDtoSchema = context.Document.Definitions["ContentItemDto"];

            var partDtoSchema = context.SchemaGenerator.Generate(typeof(ContentPartDto), context.SchemaResolver);

            partDtoSchema.AllowAdditionalProperties = false;
            var allPartDefinitions = _contentDefinitionManager.ListPartDefinitions();

            // Register code only parts first.
            foreach (var registeredPartOption in _contentOptions.ContentPartOptions)
            {
                // Is also registered in the part definitions.
                if (allPartDefinitions.Any(x => x.Name == registeredPartOption.Type.Name))
                {
                    continue;
                }
                // Has no fields as it is code only
                var partSchema = context.SchemaGenerator.Generate(registeredPartOption.Type, context.SchemaResolver);

                partSchema.AllOf.ElementAt(1).AllowAdditionalProperties = false;
                // remove first AllOf and reinsert the partDtoSchema as the ref.
                InsertDtoReferenceSchema(partSchema, partDtoSchema);

                // Use ActualProperties here, not Properties
                AlterArrayPropertiesToContentItemDtoSchema(partSchema.ActualProperties, contentItemSchema, contentItemDtoSchema);
                // Change schema regisitration name to 'ContainedPartDto'
                AlterSchemaDefinition(context, registeredPartOption.Type.Name, _openApiOptions.ContentTypes.SchemaNameExtension);
            }

            // Then register parts defined in the part definitions.
            foreach (var partDefinition in allPartDefinitions)
            {
                // check to see if it is a hard typed part.
                if (_contentOptions.ContentPartOptionsLookup.TryGetValue(partDefinition.Name, out var contentPartOption))
                {
                    var partSchema = context.SchemaGenerator.Generate(contentPartOption.Type, context.SchemaResolver);

                    partSchema.AllOf.ElementAt(1).AllowAdditionalProperties = false;
                    // remove first AllOf and reinsert the partDtoSchema as the ref.
                    InsertDtoReferenceSchema(partSchema, partDtoSchema);

                    //TODO test this, it's being added as a direct property
                    // but the other properties are added as part of all of
                    // so we might need to find all of index 1 and insert it there
                    foreach (var field in partDefinition.Fields)
                    {
                        // Lookup field definition.
                        if (context.Document.Definitions.TryGetValue(field.FieldDefinition.Name + _openApiOptions.ContentTypes.SchemaNameExtension, out var fieldSchema))
                        {
                            // Add field as property.
                            var propertySchema = new JsonSchemaProperty
                            {
                                Type          = JsonObjectType.Object,
                                IsNullableRaw = true
                            };

                            propertySchema.OneOf.Add(new JsonSchema
                            {
                                Type      = JsonObjectType.Object,
                                Reference = fieldSchema.ActualSchema
                            });
                            partSchema.Properties[field.Name] = propertySchema;
                        }
                    }

                    foreach (var allOfSchema in partSchema.AllOf)
                    {
                        AlterArrayPropertiesToContentItemDtoSchema(allOfSchema.ActualProperties, contentItemSchema, contentItemDtoSchema);
                    }
                    // Change schema regisitration name to 'HtmlPartDto'
                    AlterSchemaDefinition(context, contentPartOption.Type.Name, _openApiOptions.ContentTypes.SchemaNameExtension);
                }
                else // This builds dynamic parts.
                {
                    // We need to skip registrations for type definition parts.
                    if (ctds.Any(x => x.Name == partDefinition.Name))
                    {
                        continue;
                    }
                    var partReferenceSchema = new JsonSchema
                    {
                        Type      = JsonObjectType.Object,
                        Reference = partDtoSchema.ActualSchema,
                        AllowAdditionalProperties = false
                    };
                    var partSchema = new JsonSchema
                    {
                        Type = JsonObjectType.Object,
                        AllowAdditionalProperties = false
                    };

                    partSchema.AllOf.Add(partReferenceSchema);
                    foreach (var field in partDefinition.Fields)
                    {
                        // Lookup field definition.
                        if (context.Document.Definitions.TryGetValue(field.FieldDefinition.Name + _openApiOptions.ContentTypes.SchemaNameExtension, out var fieldSchema))
                        {
                            // Add field as property.
                            var propertySchema = new JsonSchemaProperty
                            {
                                Type          = JsonObjectType.Object,
                                IsNullableRaw = true
                            };

                            propertySchema.OneOf.Add(new JsonSchema
                            {
                                Type      = JsonObjectType.Object,
                                Reference = fieldSchema.ActualSchema
                            });
                            partSchema.Properties[field.Name] = propertySchema;
                        }
                    }

                    context.Document.Definitions[partDefinition.Name + _openApiOptions.ContentTypes.SchemaNameExtension] = partSchema;
                }
            }

            // Content Types
            var typeDtoSchema = context.SchemaGenerator.Generate(typeof(ContentItemDto), context.SchemaResolver);

            typeDtoSchema.AllowAdditionalProperties            = false;
            typeDtoSchema.ActualTypeSchema.DiscriminatorObject = new OpenApiDiscriminator
            {
                //PropertyName = "discriminator",
                PropertyName = "ContentType",
                // TODO a custom one of these might help create types automatically.
                // Particularly useful for Flow.ContentItems etc.
                JsonInheritanceConverter = new JsonInheritanceConverter("ContentType")
            };

            foreach (var ctd in ctds)
            {
                if (_openApiOptions.ContentTypes.ExcludedTypes.Any(x => string.Equals(x, ctd.Name)))
                {
                    continue;
                }
                var typeReferenceSchema = new JsonSchema
                {
                    Type      = JsonObjectType.Object,
                    Reference = typeDtoSchema.ActualSchema,
                    AllowAdditionalProperties = false
                };

                var typeSchema = new JsonSchema
                {
                    Type = JsonObjectType.Object,
                    AllowAdditionalProperties = false
                };

                typeSchema.AllOf.Add(typeReferenceSchema);
                var typeFieldPartDefinition = ctd.Parts.FirstOrDefault(x => x.PartDefinition.Name == ctd.Name);
                // Not all content types will have a 'FieldDefinitionPart' until fields are added.
                if (typeFieldPartDefinition != null)
                {
                    // Add Field Part container
                    var partSchema = new JsonSchema
                    {
                        Type = JsonObjectType.Object,
                        AllowAdditionalProperties = false
                    };
                    var partReferenceSchema = new JsonSchema
                    {
                        Type = JsonObjectType.Object,
                        AllowAdditionalProperties = false,
                        Reference = partDtoSchema.ActualSchema
                    };
                    partSchema.AllOf.Add(partReferenceSchema);
                    // TODO move to method
                    foreach (var field in typeFieldPartDefinition.PartDefinition.Fields)
                    {
                        // Lookup field definition.
                        if (context.Document.Definitions.TryGetValue(field.FieldDefinition.Name + _openApiOptions.ContentTypes.SchemaNameExtension, out var fieldSchema))
                        {
                            // Add field as property.
                            var propertySchema = new JsonSchemaProperty
                            {
                                Type          = JsonObjectType.Object,
                                IsNullableRaw = true
                            };

                            propertySchema.OneOf.Add(new JsonSchema
                            {
                                Type      = JsonObjectType.Object,
                                Reference = fieldSchema.ActualSchema
                            });
                            partSchema.Properties[field.Name] = propertySchema;
                        }
                    }

                    // Don't add "Part" here because users often create their own TypePart.
                    context.Document.Definitions[ctd.Name + _openApiOptions.ContentTypes.SchemaNameExtension] = partSchema;

                    // Add fieldpart as property.
                    var typePropertySchema = new JsonSchemaProperty
                    {
                        Type          = JsonObjectType.Object,
                        IsNullableRaw = true
                    };

                    typePropertySchema.OneOf.Add(new JsonSchema
                    {
                        Type      = JsonObjectType.Object,
                        Reference = partSchema.ActualSchema
                    });
                    typeSchema.Properties[typeFieldPartDefinition.Name] = typePropertySchema;
                }

                // Add all other parts
                var parts = ctd.Parts.Where(x => x.PartDefinition.Name != ctd.Name);
                foreach (var partDefinition in parts)
                {
                    // Lookup part definition.
                    if (context.Document.Definitions.TryGetValue(partDefinition.PartDefinition.Name + _openApiOptions.ContentTypes.SchemaNameExtension,
                                                                 out var typePartSchema))
                    {
                        // Add part as property.
                        var propertySchema = new JsonSchemaProperty
                        {
                            Type          = JsonObjectType.Object,
                            IsNullableRaw = true
                        };

                        propertySchema.OneOf.Add(new JsonSchema
                        {
                            Type      = JsonObjectType.Object,
                            Reference = typePartSchema.ActualSchema
                        });
                        typeSchema.Properties[partDefinition.Name] = propertySchema;
                    }
                }

                // Add final definition.
                context.Document.Definitions[ctd.Name + _openApiOptions.ContentTypes.SchemaTypeNameExtension + _openApiOptions.ContentTypes.SchemaNameExtension] = typeSchema;

                // Add discriminator mappings to actual type schema
                typeDtoSchema.ActualTypeSchema.DiscriminatorObject.Mapping.Add(
                    ctd.Name + _openApiOptions.ContentTypes.SchemaTypeNameExtension + _openApiOptions.ContentTypes.SchemaNameExtension,
                    new JsonSchema
                {
                    Reference = typeSchema
                }
                    );
            }
        }